commit b9eba78ec7521da0194b982834c41db934157f01 Author: thierrico Date: Mon Sep 9 22:24:02 2024 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa3957c --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/.idea/ +*.iml +**/target/** +**/out/** \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..e4e3064 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,64 @@ +pipeline { + agent {node 'debian'} + options { + buildDiscarder(logRotator(numToKeepStr: '10', artifactNumToKeepStr: '10')) + } + environment { + VERSION = readMavenPom().getVersion() + } + stages { + stage('Checkout') { + steps { + checkout scm + script { + currentBuild.displayName = "${env.BRANCH_NAME}-${env.BUILD_NUMBER}" + } + } + } + stage ('Build') { + steps { + withMaven(jdk: 'JDK1.7_Oracle', maven: 'Maven3', mavenSettingsConfig: 'nexus_settings') { + sh "mvn -Dhttps.protocols=TLSv1.2 -Dmaven.test.failure.ignore=true -P validation clean install" + } + } + post { + success { + archiveArtifacts artifacts: '**/*.ear', fingerprint: true + // + // junit '**/build/surefire-reports/**/*.xml' + } + } + } + stage ('Quality') { + steps { + withSonarQubeEnv('Sonarqube') { + withMaven(jdk: 'JDK1.8_Oracle', maven: 'Maven3', mavenSettingsConfig: 'nexus_settings', mavenOpts: '-Xms256m -Xmx1024m') { + sh "mvn -Dhttps.protocols=TLSv1.2 -Dmaven.test.failure.ignore=true org.sonarsource.scanner.maven:sonar-maven-plugin:3.5.0.1254:sonar" + } + } + } + } + stage('Deploy VAL') { + when { + beforeAgent true + branch 'TM*' + } + steps { + sh '' + } + } + stage('Package') { + steps { + withMaven(jdk: 'JDK1.7_Oracle', maven: 'Maven3', mavenSettingsConfig: 'nexus_settings') { + sh "mvn -Dhttps.protocols=TLSv1.2 package" + } + } + post { + success { + archiveArtifacts '**/target/*.ear' + archiveArtifacts '**/target/*.zip' + } + } + } + } +} \ No newline at end of file diff --git a/core-ear/pom.xml b/core-ear/pom.xml new file mode 100644 index 0000000..ba33d7f --- /dev/null +++ b/core-ear/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + core-ear + ear + core-ear + + + com.capgemini.reports + kurt + 1.32.9 + + + + + com.capgemini.reports + kurt-web + 1.32.9 + war + + + + + + + org.apache.maven.plugins + maven-ear-plugin + + 6 + lib + + + com.capgemini.reports + kurt-web + /kurt-web + + + + + + + + + + validation + + + + org.jboss.as.plugins + jboss-as-maven-plugin + + ${hostname} + 9999 + admin + jboss + true + + + + + + + + + diff --git a/deployment-tool/pom.xml b/deployment-tool/pom.xml new file mode 100644 index 0000000..e1459bb --- /dev/null +++ b/deployment-tool/pom.xml @@ -0,0 +1,96 @@ + + + 4.0.0 + deployment-tool + jar + Deployment tool + Deployment tool for JAVA project facilitating resources updates in archives (jar, war, ear) + + + + kurt + com.capgemini.reports + 1.32.9 + + + + + org.testng + testng + test + + + org.assertj + assertj-core + test + + + org.slf4j + slf4j-api + 1.7.7 + + + + org.slf4j + slf4j-log4j12 + 1.7.7 + + + + log4j + log4j + 1.2.16 + + + + com.google.guava + guava + + + + com.oracle + ojdbc6 + 11.2.0.3 + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + prepare-package + + unpack-dependencies + + + ${project.build.directory}/classes + runtime + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + com.capgemini.framework.deployment.Install + true + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + diff --git a/deployment-tool/src/main/java/com/capgemini/framework/common/FileHelper.java b/deployment-tool/src/main/java/com/capgemini/framework/common/FileHelper.java new file mode 100644 index 0000000..c14ecef --- /dev/null +++ b/deployment-tool/src/main/java/com/capgemini/framework/common/FileHelper.java @@ -0,0 +1,71 @@ +package com.capgemini.framework.common; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; + +/** + * Class for common file management. + **/ +public final class FileHelper { + private static final Logger log = LoggerFactory.getLogger(FileHelper.class); + private static final char LINE_FEED = 0x000A; + + private FileHelper() { + // Constructor of helper classes must be private + } + + /** + * Check file existence. + * + * @param aFilePath File which must be checked + * @return True when the file exists + */ + public static boolean fileExist(final String aFilePath) { + boolean status = true; + if (aFilePath == null) { + log.debug("File name is null"); + return false; + } + + File theFile = new File(aFilePath); + if (!theFile.exists() || theFile.isDirectory()) { + log.debug("File does not exist: {}", theFile.getAbsolutePath()); + status = false; + } + + return status; + } + + /** + * Read a text file and findAll its content. + * + * @param aSourceFilePath parsed source file path + * @return string with text file content + */ + public static String read(final String aSourceFilePath) throws IOException { + // Check file existence + if (!fileExist(aSourceFilePath)) { + throw new FileNotFoundException("File does not exist: " + aSourceFilePath); + } + + StringBuilder theContent = new StringBuilder(); + try (BufferedReader reader = new BufferedReader(new FileReader(aSourceFilePath))) { + // Browse lines of file + String theCurrentLine = reader.readLine(); + while (theCurrentLine != null) { + theContent.append(theCurrentLine); + theContent.append(LINE_FEED); + theCurrentLine = reader.readLine(); + } + } + + // Read file content + return theContent.toString(); + } +} diff --git a/deployment-tool/src/main/java/com/capgemini/framework/common/FolderHelper.java b/deployment-tool/src/main/java/com/capgemini/framework/common/FolderHelper.java new file mode 100644 index 0000000..9009468 --- /dev/null +++ b/deployment-tool/src/main/java/com/capgemini/framework/common/FolderHelper.java @@ -0,0 +1,35 @@ +package com.capgemini.framework.common; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * Class for folder management. + **/ +public final class FolderHelper { + + private FolderHelper() { + // Constructor of helper classes must be private + } + + + /** + * Get file list from a specific directory with a filtered extension. + * + * @param aDirectory Directory path containing searched files + * @param anExtension Extension of searched files (Set to null when all files should be returned) + * @return List of files + */ + public static List dirList(final File aDirectory, final String anExtension) { + List filteredFileList = new ArrayList<>(); + for (String element : aDirectory.list()) { + if (anExtension == null || (element.endsWith(anExtension))) { + filteredFileList.add(element); + } + } + + return filteredFileList; + } + +} diff --git a/deployment-tool/src/main/java/com/capgemini/framework/db/DbConnection.java b/deployment-tool/src/main/java/com/capgemini/framework/db/DbConnection.java new file mode 100644 index 0000000..6696c38 --- /dev/null +++ b/deployment-tool/src/main/java/com/capgemini/framework/db/DbConnection.java @@ -0,0 +1,48 @@ +package com.capgemini.framework.db; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +/** + * Define the migration database connection. + **/ +class DbConnection { + private static final Logger log = LoggerFactory.getLogger(DbConnection.class); + private Connection connection; + + /** + * Connect directly to the database by specifying user and password. + * + * @param anUrl Database URL. + * @param anUser User required for authentication. + * @param aPassword Password required for authentication. + **/ + DbConnection(final String anUrl, final String anUser, final String aPassword) { + try { + /* Load driver */ + DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); + + /* Connect to database */ + connection = DriverManager.getConnection(anUrl, anUser, aPassword); + + /* By default enabled auto commit */ + connection.setAutoCommit(true); + } + catch (SQLException e) { + log.error("Unable to prepare connection", e); + } + } + + /** + * Getter for connection attribute. + * + * @return Active connection. + */ + Connection getConnection() { + return connection; + } +} diff --git a/deployment-tool/src/main/java/com/capgemini/framework/db/DbManager.java b/deployment-tool/src/main/java/com/capgemini/framework/db/DbManager.java new file mode 100644 index 0000000..d344b67 --- /dev/null +++ b/deployment-tool/src/main/java/com/capgemini/framework/db/DbManager.java @@ -0,0 +1,69 @@ +package com.capgemini.framework.db; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.SQLException; +import java.sql.Statement; + +/** + * Class for all JDBC connections. + */ +public class DbManager { + private static final Logger log = LoggerFactory.getLogger(DbManager.class); + private final DbConnection connection; + + public DbManager(final String url, final String login, final String password) { + connection = new DbConnection(url, login, password); + } + + /** + * Execute a query for private use of this utility class. + * + * @param query the SQL query + * @return the number of affected rows + */ + private int execute(final String query) throws SQLException { + try (Statement theStatement = connection.getConnection().createStatement()) { + return theStatement.executeUpdate(query); + } + } + + /** + * Execute a SQL query with stack trace display parameter. + * + * @param aQuery SQL query content. + * @return True when the query has been executed successfully. + */ + boolean executeQuery(final String aQuery) { + boolean status = true; + int nbRowsImpacted = executeQueryAndGetRowCount(aQuery); + if (nbRowsImpacted < 0) { + status = false; + } + return status; + } + + /** + * Execute a SQL query and findAll its impacted rows count (for UPDATE and DELETE operations). + * + * @param aQuery SQL query content. + * @return impacted row count (-1 = error). + */ + private int executeQueryAndGetRowCount(final String aQuery) { + try { + return execute(aQuery); + } + catch (SQLException e) { + if (!isIgnoredError(e)) { + log.error("SQL error detected during following query execution: " + aQuery, e); + } + return -1; + } + } + + private boolean isIgnoredError(final SQLException exc) { + int theErrorCode = exc.getErrorCode(); + return theErrorCode == 2289 || theErrorCode == 942; + } +} diff --git a/deployment-tool/src/main/java/com/capgemini/framework/db/SqlHelper.java b/deployment-tool/src/main/java/com/capgemini/framework/db/SqlHelper.java new file mode 100644 index 0000000..f13a721 --- /dev/null +++ b/deployment-tool/src/main/java/com/capgemini/framework/db/SqlHelper.java @@ -0,0 +1,105 @@ +package com.capgemini.framework.db; + +import com.capgemini.framework.common.FileHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +/** + * Utility class for running SQL queries from an SQL file. + **/ +public final class SqlHelper { + private static final Logger log = LoggerFactory.getLogger(SqlHelper.class); + + private SqlHelper() { + /* Constructor of helper classes must be private */ + } + + /** + * Load a set of SQL queries from a text file. + * + * @param aDbManager Database manager for executing SQL queries + * @param aFilePath File path for the loaded SQL file + * @return True when all executed queries have been successfully run + **/ + public static boolean runSqlFile(DbManager aDbManager, String aFilePath) throws IOException { + + /* Check file existence */ + if (!FileHelper.fileExist(aFilePath)) { + log.error("SQL file does not exist: {}", aFilePath); + return false; + } + + /* Extract the SQL file content */ + String theFileContent = FileHelper.read(aFilePath); + + /* Separate each query */ + String[] theQueryArray = theFileContent.split(";\n"); + + return runSqlFile(aDbManager, aFilePath, theQueryArray); + } + + /** + * Load a set of SQL queries from a text file. + * + * @param aDbManager Database manager for executing SQL queries + * @param aFilePath File path for the loaded SQL file + * @param aQueryArray List of SQL queries executed + * @return True when all executed queries have been successfully run + **/ + public static boolean runSqlFile(DbManager aDbManager, String aFilePath, String[] aQueryArray) { + + boolean isSuccess = true; + int successQueryCount = 0; + + /* Browse SQL queries from file */ + for (String currentQuery : aQueryArray) { + + /* Check if current query could be managed by loader */ + String currentUnformatedQuery = unformatQuery(currentQuery); + if (currentUnformatedQuery.isEmpty()) { + continue; + } + + /* Run the SQL query */ + if (aDbManager.executeQuery(currentUnformatedQuery)) { + successQueryCount++; + } + else { + isSuccess = false; + } + } + + /* Log correct queries */ + if (successQueryCount > 0) { + log.debug("{} queries have been executed successfully from file: {}", successQueryCount, aFilePath); + } + + return isSuccess; + } + + /** + * Clean the special characters used for indentation in the query. + * + * @param aQueryValue Original query (with pretty print format) + * @return Cleaned query + **/ + private static String unformatQuery(String aQueryValue) { + + String theUnformatedQuery = aQueryValue; + + /* Delete "pretty print" */ + theUnformatedQuery = theUnformatedQuery.replace("\n", " ").replace("\r", "").replace("\t", " "); + + /* Delete comments */ + theUnformatedQuery = theUnformatedQuery.replaceAll("/\\*.*?\\*/", "").trim(); + + /* Ignore query with only "COMMIT" instruction */ + if ("COMMIT".equalsIgnoreCase(theUnformatedQuery)) { + theUnformatedQuery = ""; + } + + return theUnformatedQuery; + } +} diff --git a/deployment-tool/src/main/java/com/capgemini/framework/deployment/DeployProperties.java b/deployment-tool/src/main/java/com/capgemini/framework/deployment/DeployProperties.java new file mode 100644 index 0000000..3608c67 --- /dev/null +++ b/deployment-tool/src/main/java/com/capgemini/framework/deployment/DeployProperties.java @@ -0,0 +1,77 @@ +package com.capgemini.framework.deployment; + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Map.Entry; +import java.util.Properties; + +/** + * Property ready for user inputs. + **/ +class DeployProperties { + private static final Logger log = LoggerFactory.getLogger(DeployProperties.class); + private final Properties propFile; + + DeployProperties(String aFilePath) { + propFile = new Properties(); + try (FileInputStream theFileStream = getInputStream(aFilePath)) { + propFile.load(theFileStream); + displayValues(); + } + catch (FileNotFoundException e) { + log.error("The file has not been found: " + aFilePath, e); + } + catch (IOException e) { + log.error("Error while reading file: " + aFilePath, e); + } + + } + + /** + * Display property file content for debug purpose. + */ + private void displayValues() { + if (log.isDebugEnabled()) { + StringBuilder thePropValues = new StringBuilder(); + thePropValues.append("Property values:\n"); + + for (Entry currentProp : propFile.entrySet()) { + String currentKey = currentProp.getKey().toString(); + String currentValue = currentProp.getValue().toString(); + thePropValues.append("\t").append(currentKey).append("=").append(currentValue).append("\n"); + } + + log.debug(thePropValues.toString()); + } + } + + /** + * Read input properties file. + */ + private FileInputStream getInputStream(String aFilePath) throws FileNotFoundException { + return new FileInputStream(new File(aFilePath)); + } + + /** + * Retrieve a property value. + * + * @param aDynamicRef Reference of the the searched property + * @return Property value + */ + String getString(String aDynamicRef) { + String thePropValue = ""; + if (propFile.containsKey(aDynamicRef)) { + thePropValue = propFile.getProperty(aDynamicRef); + } + else { + log.debug("Unknown property reference: {}", aDynamicRef); + } + return thePropValue; + } +} diff --git a/deployment-tool/src/main/java/com/capgemini/framework/deployment/Install.java b/deployment-tool/src/main/java/com/capgemini/framework/deployment/Install.java new file mode 100644 index 0000000..5af8dfc --- /dev/null +++ b/deployment-tool/src/main/java/com/capgemini/framework/deployment/Install.java @@ -0,0 +1,137 @@ +package com.capgemini.framework.deployment; + +import com.capgemini.framework.common.FileHelper; +import com.capgemini.framework.common.FolderHelper; +import com.capgemini.framework.db.DbManager; +import com.capgemini.framework.db.SqlHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +/** + * Main class of executable JAR. + **/ +public class Install { + private static final Logger log = LoggerFactory.getLogger(Install.class); + private String homeDir; + private DeployProperties deployProperties; + + /** + * Main entry point of executable JAR. + * + * @param args Command line arguments + */ + public static void main(String[] args) { + log.info("Start installation"); + log.info("=================="); + + boolean isSuccess = true; + int theStatus = 0; + try { + Install theInstaller = new Install(); + + /* Check that the execution mode has been selected */ + isSuccess = theInstaller.checkEnvironment(); + if (isSuccess) { + isSuccess = theInstaller.runSqlExec(); + } + } + catch (Exception e) { + log.error("Unexpected error occurred", e); + } + finally { + if (!isSuccess) { + log.info("Installation status: FAILED"); + theStatus = 1; + } + else { + log.info("Installation status: SUCCESS"); + } + log.info("==============================="); + } + System.exit(theStatus); + } + + /** + * Check if a environment variable is set. + * + * @return True when variable is set + */ + private static boolean checkEnvVar() { + boolean isSet = true; + String theEnvValue = System.getenv("DEPLOY_TOOL_HOME"); + if (theEnvValue == null) { + isSet = false; + } + return isSet; + } + + /** + * Load SQL files which are in the "sql" sub-folder. + * + * @return True when all the SQL queries have been executed successfully + **/ + private boolean runSqlExec() throws IOException { + + boolean isSuccess = true; + + /* Retrieve database parameters from properties */ + String url = deployProperties.getString("database.url"); + String theLogin = deployProperties.getString("database.schema.login"); + String thePass = deployProperties.getString("database.schema.password"); + + /* Instantiate database connector */ + DbManager theDbManager = new DbManager(url, theLogin, thePass); + + /* Browse PL/SQL folder and load each SQL file */ + File thePlSqlFolder = new File(homeDir + "/plsql"); + List theDirList = FolderHelper.dirList(thePlSqlFolder, "sql"); + for (String currentFile : theDirList) { + String currentFilePath = homeDir + "/plsql/" + currentFile; + String currentFileContent = FileHelper.read(currentFilePath); + isSuccess &= SqlHelper.runSqlFile(theDbManager, currentFilePath, new String[]{currentFileContent}); + } + + /* Browse SQL folder and load each SQL file */ + File theSqlFolder = new File(homeDir + "/sql"); + theDirList = FolderHelper.dirList(theSqlFolder, "sql"); + for (String currentFile : theDirList) { + isSuccess &= SqlHelper.runSqlFile(theDbManager, homeDir + "/sql/" + currentFile); + } + + return isSuccess; + } + + /** + * Run all prerequisite checks for verifying the environment setup. + **/ + private boolean checkEnvironment() { + /* Check environment */ + if (!checkEnvVar()) { + log.error("The environment variable DEPLOY_TOOL_HOME must be set"); + return false; + } + homeDir = getEnvDir(); + String propFilePath = homeDir + "/db.properties"; + if (!FileHelper.fileExist(propFilePath)) { + log.error("The property file for installation is missing: {}", propFilePath); + return false; + } + + /* Call the properties loader when all prerequisites checks have been done. */ + deployProperties = new DeployProperties(propFilePath); + + return true; + } + + /** + * Get directory path and replace backslash separator to slash separator. + **/ + private String getEnvDir() { + String theDirPath = System.getenv("DEPLOY_TOOL_HOME"); + return theDirPath.replace("\\", "/"); + } +} diff --git a/deployment-tool/src/main/resources/log4j.properties b/deployment-tool/src/main/resources/log4j.properties new file mode 100644 index 0000000..2567034 --- /dev/null +++ b/deployment-tool/src/main/resources/log4j.properties @@ -0,0 +1,15 @@ +# Root logger option +log4j.rootLogger=DEBUG, stdout, file +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.threshold=DEBUG +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} - %m%n + +log4j.appender.file=org.apache.log4j.RollingFileAppender +log4j.appender.file.File=./log/install.log +log4j.appender.file.MaxFileSize=10MB +log4j.appender.file.MaxBackupIndex=10 +log4j.appender.file.layout=org.apache.log4j.PatternLayout +log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n diff --git a/deployment-tool/src/test/resources/input/deploy.test.properties b/deployment-tool/src/test/resources/input/deploy.test.properties new file mode 100644 index 0000000..9daadde --- /dev/null +++ b/deployment-tool/src/test/resources/input/deploy.test.properties @@ -0,0 +1 @@ +# This file may be empty for test but must exist diff --git a/deployment-tool/src/test/resources/input/sampleArchives/sampleEar.ear b/deployment-tool/src/test/resources/input/sampleArchives/sampleEar.ear new file mode 100644 index 0000000..613209f Binary files /dev/null and b/deployment-tool/src/test/resources/input/sampleArchives/sampleEar.ear differ diff --git a/deployment-tool/src/test/resources/input/sampleArchives/sampleJar.jar b/deployment-tool/src/test/resources/input/sampleArchives/sampleJar.jar new file mode 100644 index 0000000..54fd94c Binary files /dev/null and b/deployment-tool/src/test/resources/input/sampleArchives/sampleJar.jar differ diff --git a/deployment-tool/src/test/resources/input/sampleArchives/sampleWar.war b/deployment-tool/src/test/resources/input/sampleArchives/sampleWar.war new file mode 100644 index 0000000..44b6e40 Binary files /dev/null and b/deployment-tool/src/test/resources/input/sampleArchives/sampleWar.war differ diff --git a/deployment-tool/src/test/resources/input/sampleArchives/updated/repackedSampleEar.ear b/deployment-tool/src/test/resources/input/sampleArchives/updated/repackedSampleEar.ear new file mode 100644 index 0000000..ad23189 Binary files /dev/null and b/deployment-tool/src/test/resources/input/sampleArchives/updated/repackedSampleEar.ear differ diff --git a/deployment-tool/src/test/resources/input/sampleArchives/updated/repackedSampleJar.jar b/deployment-tool/src/test/resources/input/sampleArchives/updated/repackedSampleJar.jar new file mode 100644 index 0000000..86feaee Binary files /dev/null and b/deployment-tool/src/test/resources/input/sampleArchives/updated/repackedSampleJar.jar differ diff --git a/deployment-tool/src/test/resources/input/sampleArchives/updated/repackedSampleWar.war b/deployment-tool/src/test/resources/input/sampleArchives/updated/repackedSampleWar.war new file mode 100644 index 0000000..53ba982 Binary files /dev/null and b/deployment-tool/src/test/resources/input/sampleArchives/updated/repackedSampleWar.war differ diff --git a/deployment-tool/src/test/resources/input/updatedFiles/PropertyUpdaterTest.properties b/deployment-tool/src/test/resources/input/updatedFiles/PropertyUpdaterTest.properties new file mode 100644 index 0000000..bc1bd3f --- /dev/null +++ b/deployment-tool/src/test/resources/input/updatedFiles/PropertyUpdaterTest.properties @@ -0,0 +1,7 @@ +com.capgemini.property1=value1 +com.capgemini.property2 =value2 + +# Unmodified comment and commented property +# com.capgemini.property1=value1 + +com.capgemini.property3 =value3 \ No newline at end of file diff --git a/deployment-tool/src/test/resources/input/updatedFiles/XmlUpdaterTest.xml b/deployment-tool/src/test/resources/input/updatedFiles/XmlUpdaterTest.xml new file mode 100644 index 0000000..6dd1e96 --- /dev/null +++ b/deployment-tool/src/test/resources/input/updatedFiles/XmlUpdaterTest.xml @@ -0,0 +1,19 @@ + + + + + + OldValue1 + + OldValue2 + + + + + + + Should not be updated + + Changed + Unchanged + \ No newline at end of file diff --git a/deployment-tool/src/test/resources/input/xml/updateSampleEar.xml b/deployment-tool/src/test/resources/input/xml/updateSampleEar.xml new file mode 100644 index 0000000..f0e03c7 --- /dev/null +++ b/deployment-tool/src/test/resources/input/xml/updateSampleEar.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/deployment-tool/src/test/resources/log4j.properties b/deployment-tool/src/test/resources/log4j.properties new file mode 100644 index 0000000..eef248b --- /dev/null +++ b/deployment-tool/src/test/resources/log4j.properties @@ -0,0 +1,9 @@ +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.threshold=DEBUG +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %c{1}:%L - %m%n + +# Root logger option +log4j.rootLogger=DEBUG, stdout diff --git a/deployment-tool/src/test/resources/ref/PropertyUpdaterTest.ref b/deployment-tool/src/test/resources/ref/PropertyUpdaterTest.ref new file mode 100644 index 0000000..039027b --- /dev/null +++ b/deployment-tool/src/test/resources/ref/PropertyUpdaterTest.ref @@ -0,0 +1,7 @@ +com.capgemini.property1=NewValueOne +com.capgemini.property2=NewValueTwo + +# Unmodified comment and commented property +# com.capgemini.property1=value1 + +com.capgemini.property3=NewValueThree diff --git a/deployment-tool/src/test/resources/ref/XmlUpdaterTest.ref b/deployment-tool/src/test/resources/ref/XmlUpdaterTest.ref new file mode 100644 index 0000000..3018e0d --- /dev/null +++ b/deployment-tool/src/test/resources/ref/XmlUpdaterTest.ref @@ -0,0 +1,17 @@ + + + + + NewValueOne + NewValueTwo + + + + + + + Should not be updated + + Changed by condition + Unchanged + \ No newline at end of file diff --git a/distribution/assembly.xml b/distribution/assembly.xml new file mode 100644 index 0000000..38b111e --- /dev/null +++ b/distribution/assembly.xml @@ -0,0 +1,97 @@ + + report-assembly + + zip + + false + + + true + + com.capgemini.reports:core-ear + + + Installation/reports + false + false + snecma-reports.${module.extension} + + + + true + + com.capgemini.reports:deployment-tool + + + Installation/reports/bin + false + false + install-reports.${module.extension} + + + + true + + com.capgemini.reports:distribution + + + + + + target/ + src/test/ + **/*.iml + + + + Sources/${module.basedir.name} + + + + true + + com.capgemini.reports:kurt-utility + + + + + src/main/resources/xml/policies/ + + **/*.xml + + + + Installation/teamcenter/data/policies + + + + + + ${basedir}/install + Installation + + **/bin/** + **/modules/** + + unix + + + ${basedir}/install + Installation + + **/bin/** + **/modules/** + + + + + + install/teamcenter/report_install.pl + Installation/teamcenter + true + + + + diff --git a/distribution/install/reports/DBcreate/001_hibernate_sequence.sql b/distribution/install/reports/DBcreate/001_hibernate_sequence.sql new file mode 100644 index 0000000..255e723 --- /dev/null +++ b/distribution/install/reports/DBcreate/001_hibernate_sequence.sql @@ -0,0 +1,9 @@ +CALL PR_DROP_SEQ_IF_EXIST('HIBERNATE_SEQUENCE'); + +CREATE SEQUENCE HIBERNATE_SEQUENCE + START WITH 1 + MAXVALUE 9999999999999999999999999999 + MINVALUE 1 + NOCYCLE + CACHE 20 + NOORDER; diff --git a/distribution/install/reports/DBcreate/002_table.sql b/distribution/install/reports/DBcreate/002_table.sql new file mode 100644 index 0000000..9f17927 --- /dev/null +++ b/distribution/install/reports/DBcreate/002_table.sql @@ -0,0 +1,101 @@ +CALL PR_DROP_IF_EXIST('CRITERIA_VAL'); +CALL PR_DROP_IF_EXIST('CRITERIA'); +CALL PR_DROP_IF_EXIST('MEM_MONITOR'); +CALL PR_DROP_IF_EXIST('REP_USER'); +CALL PR_DROP_IF_EXIST('REPORT_OWNER'); +CALL PR_DROP_IF_EXIST('CRITERIA'); +CALL PR_DROP_IF_EXIST('REPORT'); +CALL PR_DROP_IF_EXIST('REPORT_OWNER'); +CALL PR_DROP_IF_EXIST('REPORT_TYPE'); +CALL PR_DROP_IF_EXIST('SCHEDULING_REPORT'); +CALL PR_DROP_IF_EXIST('SCHEDULING_CRITERIA_VAL'); + +CREATE TABLE CRITERIA +( + CRITERIA_ID NUMBER(19) NOT NULL PRIMARY KEY, + CRITERIA_NAME VARCHAR2(32 CHAR) NOT NULL, + CRITERIA_TYPE VARCHAR2(32 CHAR) NOT NULL, + IS_TEMPOREL VARCHAR2(5 CHAR) NOT NULL +); + +CREATE TABLE CRITERIA_VAL +( + CRITERIA_VAL_ID NUMBER(19) NOT NULL PRIMARY KEY, + REPORT_ID NUMBER(19), + CRITERIA_ID NUMBER(19) NOT NULL, + CRITERIA_VALUE VARCHAR2(3999 CHAR) +); + +CREATE TABLE MEM_MONITOR +( + MEM_MONITOR_ID NUMBER(19) NOT NULL PRIMARY KEY, + MONITORDATE TIMESTAMP(6), + TOTALMEMORY FLOAT(126), + MAXMEMORY FLOAT(126), + FREEMEMORY FLOAT(126), + USEDMEMORY FLOAT(126), + MAXPERCENT FLOAT(126) +); + +CREATE TABLE REP_USER +( + USER_ID NUMBER(19) NOT NULL PRIMARY KEY, + LOGIN VARCHAR2(16 CHAR) NOT NULL, + EMAIL VARCHAR2(255 CHAR), + SURNAME VARCHAR2(32 CHAR), + FIRSTNAME VARCHAR2(32 CHAR), + LASTCONNECTIONDATE DATE, + IS_ADMIN VARCHAR2(5 CHAR) +); + +CREATE TABLE REPORT +( + REPORT_ID NUMBER(19) NOT NULL PRIMARY KEY, + STARTGENERATIONDATE TIMESTAMP(6), + ENDGENERATIONDATE TIMESTAMP(6), + GENERATION_DURATION NUMBER(19), + REPORT_CODE VARCHAR2(3 CHAR) NOT NULL, + REPORTUID VARCHAR2(64 CHAR) NOT NULL, + FILE_NAME VARCHAR2(255 CHAR), + STATE VARCHAR2(16 CHAR) NOT NULL, + ERROR_TYPE VARCHAR2(16 CHAR), + ERROR_MESSAGE VARCHAR2(3999 CHAR), + SCHEDULING_REPORT_ID NUMBER(19,0) +); + +CREATE TABLE REPORT_OWNER +( + REPORT_OWNER_ID NUMBER(19) NOT NULL PRIMARY KEY, + REPORT_ID NUMBER(19) NOT NULL, + USER_ID NUMBER(19) NOT NULL, + REQUESTDATE TIMESTAMP(6), + MONTH_PERIOD VARCHAR2(7 CHAR) +); + +CREATE TABLE REPORT_TYPE +( + REPORT_TYPE_ID NUMBER(19) NOT NULL PRIMARY KEY, + CODE VARCHAR2(3 CHAR) NOT NULL, + TITLE VARCHAR2(255 CHAR) NOT NULL, + REVISION_RULE VARCHAR2(255 CHAR), + PRIORITY NUMBER(19) NOT NULL, + REPORT_AUTHORIZED VARCHAR2(5 CHAR), + IS_CANDIDATE_FOR_SCHEDULING VARCHAR2(5 CHAR) +); + +CREATE TABLE SCHEDULING_CRITERIA_VAL +( + SCHEDULING_CRITERIA_VAL_ID NUMBER(19) NOT NULL PRIMARY KEY, + CRITERIA_ID NUMBER(19) NOT NULL, + SCHEDULING_REPORT_ID NUMBER(19) NOT NULL, + CRITERIA_VALUE VARCHAR2(32 CHAR) +); + +CREATE TABLE SCHEDULING_REPORT +( + SCHEDULING_REPORT_ID NUMBER(19) NOT NULL PRIMARY KEY, + SCHEDULING_NAME VARCHAR2(200 CHAR) NOT NULL, + USER_ID NUMBER(19) NOT NULL, + LAST_UPDATE TIMESTAMP(6), + REPORT_CODE VARCHAR2(3 CHAR) NOT NULL +); diff --git a/distribution/install/reports/DBcreate/003_report_type_data.sql b/distribution/install/reports/DBcreate/003_report_type_data.sql new file mode 100644 index 0000000..6b2d4ff --- /dev/null +++ b/distribution/install/reports/DBcreate/003_report_type_data.sql @@ -0,0 +1,81 @@ +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R01', 'BOM assemblage PU', ' DMA Configuration Interface R01', 2, 'TRUE', 'TRUE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R03', 'BOM fabrication date', ' DMA Configuration Interface', 1, 'TRUE', 'FALSE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R05', 'BOM Multi r�cepteurs PU', ' DMA Configuration Interface', 1, 'FALSE', + 'FALSE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R06', 'Statut Def et Indus PU', ' DMA Configuration Interface', 1, 'FALSE', + 'FALSE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R07', 'Comparaison BOM PU', ' DMA Configuration Rapport PU', 1, 'TRUE', 'TRUE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R10', 'Documents associes g�n�rique', ' DMA Configuration Validated', 1, 'TRUE', + 'TRUE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R11', 'Mise en maquette et coh�rence', ' DMA Configuration Mockup Best So Far', 1, + 'TRUE', + 'TRUE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R13', 'Etat avancement processus', ' DMA Configuration Interface', 2, 'TRUE', + 'TRUE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R15', 'Fiche article', ' DMA Configuration Interface', 1, 'TRUE', 'FALSE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'W15', 'Fiche article', ' DMA Configuration Interface', 1, 'FALSE', 'FALSE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R16', 'Fiche g�n�rique', ' DMA Configuration Validated', 1, 'TRUE', 'TRUE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R17', 'Liste document associ�s article', ' DMA Configuration Interface', 1, 'TRUE', + 'FALSE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R19', 'Cas utilisation document', ' DMA Configuration Interface', 1, 'TRUE', + 'FALSE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R20', 'Gel de UNIT', ' DMA Configuration Interface', 2, 'TRUE', 'TRUE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R21', 'Compare Net', ' DMA Configuration Interface', 3, 'TRUE', 'TRUE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R22', 'BOM fabrication date PDF eDOC', ' DMA Configuration Interface', 1, 'TRUE', + 'FALSE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'W22', 'BOM fabrication date PDF eDOC', ' DMA Configuration Interface', 1, 'FALSE', + 'FALSE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R23', 'BOM assemblage PU(s)', ' DMA Configuration Interface PU R23', 2, 'FALSE', 'TRUE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R24', 'Fiche(s) g�n�rique(s)', ' DMA Configuration Validated', 1, 'FALSE', 'TRUE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R25', 'Liste des documents des g�n�riques', ' DMA Configuration Descriptif R25', 1, + 'TRUE', 'TRUE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R26', 'Cas d''emploi d''un article', ' DMA Configuration Interface', 1, 'TRUE', + 'FALSE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R27', 'Extraction des articles de type Pi�ces', null, 1, 'TRUE', 'TRUE'); +Insert into REPORT_TYPE +(REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values (HIBERNATE_SEQUENCE.NEXTVAL, 'R28', 'Extraction des rep�res fonctionnels ', null, 1, 'TRUE', 'TRUE'); \ No newline at end of file diff --git a/distribution/install/reports/DBcreate/004_criteria_data.sql b/distribution/install/reports/DBcreate/004_criteria_data.sql new file mode 100644 index 0000000..d4d3868 --- /dev/null +++ b/distribution/install/reports/DBcreate/004_criteria_data.sql @@ -0,0 +1,111 @@ +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Date d''effectivit�', 'date', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'G�n�rique', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'G�n�rique montage', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Niveau', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Num�ro d''article', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'R�vision', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Produit', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Unit', 'integer', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Unit pr�c�dent', 'integer', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Unit suivant', 'integer', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Produit pr�c�dent', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Produit suivant', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Matricule moteur', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'LMR', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Classe', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Majeur mineur', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Conjoint unique', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Type d''impression', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Langue', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Date de d�but', 'date', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Date de fin', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Type d''objet', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Unit configuration 1', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Unit configuration 2', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Num�ro document', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'Document R�vision', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'period', 'string', 'TRUE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'weekly', 'string', 'TRUE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'weekend', 'string', 'TRUE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'date', 'string', 'TRUE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'day_in_month_value', 'string', 'TRUE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'R�gle de r�vision', 'string', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values (HIBERNATE_SEQUENCE.NEXTVAL, 'SuperModel', 'boolean', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values +(HIBERNATE_SEQUENCE.NEXTVAL, 'Avec le(s) unit(s) gelé(s)', 'boolean', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values +(HIBERNATE_SEQUENCE.NEXTVAL, 'A partir de Unit', 'integer', 'FALSE'); +insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values +(HIBERNATE_SEQUENCE.NEXTVAL, 'Units gelés il y a moins de', 'string', 'FALSE'); \ No newline at end of file diff --git a/distribution/install/reports/DBcreate/006_quartz_tables.sql b/distribution/install/reports/DBcreate/006_quartz_tables.sql new file mode 100644 index 0000000..26c39dc --- /dev/null +++ b/distribution/install/reports/DBcreate/006_quartz_tables.sql @@ -0,0 +1,192 @@ +-- +-- A hint submitted by a user: Oracle DB MUST be created as "shared" and the +-- job_queue_processes parameter must be greater than 2 +-- However, these settings are pretty much standard after any +-- Oracle install, so most users need not worry about this. +-- +-- Many other users (including the primary author of Quartz) have had success +-- runing in dedicated mode, so only consider the above as a hint ;-) +-- + +delete from qrtz_fired_triggers; +delete from qrtz_simple_triggers; +delete from qrtz_simprop_triggers; +delete from qrtz_cron_triggers; +delete from qrtz_blob_triggers; +delete from qrtz_triggers; +delete from qrtz_job_details; +delete from qrtz_calendars; +delete from qrtz_paused_trigger_grps; +delete from qrtz_locks; +delete from qrtz_scheduler_state; + +drop table qrtz_calendars; +drop table qrtz_fired_triggers; +drop table qrtz_blob_triggers; +drop table qrtz_cron_triggers; +drop table qrtz_simple_triggers; +drop table qrtz_simprop_triggers; +drop table qrtz_triggers; +drop table qrtz_job_details; +drop table qrtz_paused_trigger_grps; +drop table qrtz_locks; +drop table qrtz_scheduler_state; + + +CREATE TABLE qrtz_job_details + ( + SCHED_NAME VARCHAR2(120) NOT NULL, + JOB_NAME VARCHAR2(200) NOT NULL, + JOB_GROUP VARCHAR2(200) NOT NULL, + DESCRIPTION VARCHAR2(250) NULL, + JOB_CLASS_NAME VARCHAR2(250) NOT NULL, + IS_DURABLE VARCHAR2(1) NOT NULL, + IS_NONCONCURRENT VARCHAR2(1) NOT NULL, + IS_UPDATE_DATA VARCHAR2(1) NOT NULL, + REQUESTS_RECOVERY VARCHAR2(1) NOT NULL, + JOB_DATA BLOB NULL, + CONSTRAINT QRTZ_JOB_DETAILS_PK PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) +); +CREATE TABLE qrtz_triggers + ( + SCHED_NAME VARCHAR2(120) NOT NULL, + TRIGGER_NAME VARCHAR2(200) NOT NULL, + TRIGGER_GROUP VARCHAR2(200) NOT NULL, + JOB_NAME VARCHAR2(200) NOT NULL, + JOB_GROUP VARCHAR2(200) NOT NULL, + DESCRIPTION VARCHAR2(250) NULL, + NEXT_FIRE_TIME NUMBER(13) NULL, + PREV_FIRE_TIME NUMBER(13) NULL, + PRIORITY NUMBER(13) NULL, + TRIGGER_STATE VARCHAR2(16) NOT NULL, + TRIGGER_TYPE VARCHAR2(8) NOT NULL, + START_TIME NUMBER(13) NOT NULL, + END_TIME NUMBER(13) NULL, + CALENDAR_NAME VARCHAR2(200) NULL, + MISFIRE_INSTR NUMBER(2) NULL, + JOB_DATA BLOB NULL, + CONSTRAINT QRTZ_TRIGGERS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + CONSTRAINT QRTZ_TRIGGER_TO_JOBS_FK FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) + REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP) +); +CREATE TABLE qrtz_simple_triggers + ( + SCHED_NAME VARCHAR2(120) NOT NULL, + TRIGGER_NAME VARCHAR2(200) NOT NULL, + TRIGGER_GROUP VARCHAR2(200) NOT NULL, + REPEAT_COUNT NUMBER(7) NOT NULL, + REPEAT_INTERVAL NUMBER(12) NOT NULL, + TIMES_TRIGGERED NUMBER(10) NOT NULL, + CONSTRAINT QRTZ_SIMPLE_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + CONSTRAINT QRTZ_SIMPLE_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +); +CREATE TABLE qrtz_cron_triggers + ( + SCHED_NAME VARCHAR2(120) NOT NULL, + TRIGGER_NAME VARCHAR2(200) NOT NULL, + TRIGGER_GROUP VARCHAR2(200) NOT NULL, + CRON_EXPRESSION VARCHAR2(120) NOT NULL, + TIME_ZONE_ID VARCHAR2(80), + CONSTRAINT QRTZ_CRON_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + CONSTRAINT QRTZ_CRON_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +); +CREATE TABLE qrtz_simprop_triggers + ( + SCHED_NAME VARCHAR2(120) NOT NULL, + TRIGGER_NAME VARCHAR2(200) NOT NULL, + TRIGGER_GROUP VARCHAR2(200) NOT NULL, + STR_PROP_1 VARCHAR2(512) NULL, + STR_PROP_2 VARCHAR2(512) NULL, + STR_PROP_3 VARCHAR2(512) NULL, + INT_PROP_1 NUMBER(10) NULL, + INT_PROP_2 NUMBER(10) NULL, + LONG_PROP_1 NUMBER(13) NULL, + LONG_PROP_2 NUMBER(13) NULL, + DEC_PROP_1 NUMERIC(13,4) NULL, + DEC_PROP_2 NUMERIC(13,4) NULL, + BOOL_PROP_1 VARCHAR2(1) NULL, + BOOL_PROP_2 VARCHAR2(1) NULL, + CONSTRAINT QRTZ_SIMPROP_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + CONSTRAINT QRTZ_SIMPROP_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +); +CREATE TABLE qrtz_blob_triggers + ( + SCHED_NAME VARCHAR2(120) NOT NULL, + TRIGGER_NAME VARCHAR2(200) NOT NULL, + TRIGGER_GROUP VARCHAR2(200) NOT NULL, + BLOB_DATA BLOB NULL, + CONSTRAINT QRTZ_BLOB_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + CONSTRAINT QRTZ_BLOB_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +); +CREATE TABLE qrtz_calendars + ( + SCHED_NAME VARCHAR2(120) NOT NULL, + CALENDAR_NAME VARCHAR2(200) NOT NULL, + CALENDAR BLOB NOT NULL, + CONSTRAINT QRTZ_CALENDARS_PK PRIMARY KEY (SCHED_NAME,CALENDAR_NAME) +); +CREATE TABLE qrtz_paused_trigger_grps + ( + SCHED_NAME VARCHAR2(120) NOT NULL, + TRIGGER_GROUP VARCHAR2(200) NOT NULL, + CONSTRAINT QRTZ_PAUSED_TRIG_GRPS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP) +); +CREATE TABLE qrtz_fired_triggers + ( + SCHED_NAME VARCHAR2(120) NOT NULL, + ENTRY_ID VARCHAR2(95) NOT NULL, + TRIGGER_NAME VARCHAR2(200) NOT NULL, + TRIGGER_GROUP VARCHAR2(200) NOT NULL, + INSTANCE_NAME VARCHAR2(200) NOT NULL, + FIRED_TIME NUMBER(13) NOT NULL, + PRIORITY NUMBER(13) NOT NULL, + STATE VARCHAR2(16) NOT NULL, + JOB_NAME VARCHAR2(200) NULL, + JOB_GROUP VARCHAR2(200) NULL, + IS_NONCONCURRENT VARCHAR2(1) NULL, + REQUESTS_RECOVERY VARCHAR2(1) NULL, + CONSTRAINT QRTZ_FIRED_TRIGGER_PK PRIMARY KEY (SCHED_NAME,ENTRY_ID) +); +CREATE TABLE qrtz_scheduler_state + ( + SCHED_NAME VARCHAR2(120) NOT NULL, + INSTANCE_NAME VARCHAR2(200) NOT NULL, + LAST_CHECKIN_TIME NUMBER(13) NOT NULL, + CHECKIN_INTERVAL NUMBER(13) NOT NULL, + CONSTRAINT QRTZ_SCHEDULER_STATE_PK PRIMARY KEY (SCHED_NAME,INSTANCE_NAME) +); +CREATE TABLE qrtz_locks + ( + SCHED_NAME VARCHAR2(120) NOT NULL, + LOCK_NAME VARCHAR2(40) NOT NULL, + CONSTRAINT QRTZ_LOCKS_PK PRIMARY KEY (SCHED_NAME,LOCK_NAME) +); + +create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY); +create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP); + +create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP); +create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP); +create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME); +create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP); +create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE); +create index idx_qrtz_t_n_state on qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE); +create index idx_qrtz_t_n_g_state on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE); +create index idx_qrtz_t_next_fire_time on qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME); +create index idx_qrtz_t_nft_st on qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME); +create index idx_qrtz_t_nft_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME); +create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE); +create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE); + +create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME); +create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY); +create index idx_qrtz_ft_j_g on qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP); +create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP); +create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP); +create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP); + + diff --git a/distribution/install/reports/DBupdate/003_report_type_data_1.28.0.sql b/distribution/install/reports/DBupdate/003_report_type_data_1.28.0.sql new file mode 100644 index 0000000..a02ea48 --- /dev/null +++ b/distribution/install/reports/DBupdate/003_report_type_data_1.28.0.sql @@ -0,0 +1,5 @@ +Insert into REPORT_TYPE + (REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) +Values + (HIBERNATE_SEQUENCE.NEXTVAL, 'R26', 'Cas d''emploi d''un article', ' DMA Configuration Interface', 1, 'TRUE', + 'FALSE'); \ No newline at end of file diff --git a/distribution/install/reports/DBupdate/003_report_type_data_1.30.0.sql b/distribution/install/reports/DBupdate/003_report_type_data_1.30.0.sql new file mode 100644 index 0000000..b297a36 --- /dev/null +++ b/distribution/install/reports/DBupdate/003_report_type_data_1.30.0.sql @@ -0,0 +1,2 @@ +INSERT INTO REPORT_TYPE (REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) VALUES (HIBERNATE_SEQUENCE.NEXTVAL, 'R27', 'Extraction des articles de type pièces', null, 1, 'FALSE', 'TRUE'); +INSERT INTO REPORT_TYPE (REPORT_TYPE_ID, CODE, TITLE, REVISION_RULE, PRIORITY, REPORT_AUTHORIZED, IS_CANDIDATE_FOR_SCHEDULING) VALUES (HIBERNATE_SEQUENCE.NEXTVAL, 'R28', 'Extraction des repères fonctionnels ', null, 1, 'FALSE', 'TRUE'); \ No newline at end of file diff --git a/distribution/install/reports/DBupdate/003_report_type_data_1.32.0.sql b/distribution/install/reports/DBupdate/003_report_type_data_1.32.0.sql new file mode 100644 index 0000000..0b1e879 --- /dev/null +++ b/distribution/install/reports/DBupdate/003_report_type_data_1.32.0.sql @@ -0,0 +1,2 @@ +update REPORT_TYPE set REVISION_RULE = ' DMA Configuration Interface R01' where CODE = 'R01'; +update REPORT_TYPE set REVISION_RULE = ' DMA Configuration Interface PU R23' where CODE = 'R23'; \ No newline at end of file diff --git a/distribution/install/reports/DBupdate/003_report_type_data_1.32.7.sql b/distribution/install/reports/DBupdate/003_report_type_data_1.32.7.sql new file mode 100644 index 0000000..bf7e056 --- /dev/null +++ b/distribution/install/reports/DBupdate/003_report_type_data_1.32.7.sql @@ -0,0 +1 @@ +update REPORT_TYPE set REVISION_RULE = ' Generic / Generic Assemb R19' where CODE = 'R19'; \ No newline at end of file diff --git a/distribution/install/reports/DBupdate/004_criteria_data_1.28.0.sql b/distribution/install/reports/DBupdate/004_criteria_data_1.28.0.sql new file mode 100644 index 0000000..267ed1c --- /dev/null +++ b/distribution/install/reports/DBupdate/004_criteria_data_1.28.0.sql @@ -0,0 +1,4 @@ +Insert into CRITERIA + (CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +Values + (HIBERNATE_SEQUENCE.NEXTVAL, 'R�gle de r�vision', 'string', 'FALSE'); \ No newline at end of file diff --git a/distribution/install/reports/DBupdate/004_criteria_data_1.32.0.sql b/distribution/install/reports/DBupdate/004_criteria_data_1.32.0.sql new file mode 100644 index 0000000..9cbfb6b --- /dev/null +++ b/distribution/install/reports/DBupdate/004_criteria_data_1.32.0.sql @@ -0,0 +1,4 @@ +insert into CRITERIA +(CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values +(HIBERNATE_SEQUENCE.NEXTVAL, 'SuperModel', 'boolean', 'FALSE'); \ No newline at end of file diff --git a/distribution/install/reports/DBupdate/004_criteria_data_1.32.6.sql b/distribution/install/reports/DBupdate/004_criteria_data_1.32.6.sql new file mode 100644 index 0000000..aa789ff --- /dev/null +++ b/distribution/install/reports/DBupdate/004_criteria_data_1.32.6.sql @@ -0,0 +1,14 @@ +insert into CRITERIA +(CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values +(HIBERNATE_SEQUENCE.NEXTVAL, 'Avec le(s) unit(s) gelé(s)', 'boolean', 'FALSE'); + +insert into CRITERIA +(CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values +(HIBERNATE_SEQUENCE.NEXTVAL, 'A partir de Unit', 'integer', 'FALSE'); + +insert into CRITERIA +(CRITERIA_ID, CRITERIA_NAME, CRITERIA_TYPE, IS_TEMPOREL) +values +(HIBERNATE_SEQUENCE.NEXTVAL, 'Units gelés il y a moins de', 'string', 'FALSE'); diff --git a/distribution/install/reports/create_database.bat b/distribution/install/reports/create_database.bat new file mode 100644 index 0000000..50b0f58 --- /dev/null +++ b/distribution/install/reports/create_database.bat @@ -0,0 +1,35 @@ +@echo on +echo ========================= +echo REPORTING DATABASE CREATE +echo ========================= + +IF "%DEPLOY_TOOL_HOME%"=="" ( + echo > DEPLOY_TOOL_HOME must be defined + exit/B +) + +IF "%JBOSS_HOME%"=="" ( + echo > JBOSS_HOME must be defined + exit/B +) + +echo copy sql creation files +copy %DEPLOY_TOOL_HOME%\DBcreate\. %DEPLOY_TOOL_HOME%\sql +echo - Run database create +java -jar %DEPLOY_TOOL_HOME%\bin\install-reports.jar +if %ERRORLEVEL% EQU 1 ( + echo - Error detected, check install.log file +) else ( + echo - Database create run successfully +) + +echo clearing sql folder contents +del %DEPLOY_TOOL_HOME%\sql\* /Q + +echo ========================== +echo END OF DATABASE CREATE +echo ========================== + +pause + +exit/B \ No newline at end of file diff --git a/distribution/install/reports/create_database.bat:Zone.Identifier b/distribution/install/reports/create_database.bat:Zone.Identifier new file mode 100644 index 0000000..a45e1ac --- /dev/null +++ b/distribution/install/reports/create_database.bat:Zone.Identifier @@ -0,0 +1,2 @@ +[ZoneTransfer] +ZoneId=3 diff --git a/distribution/install/reports/db.properties b/distribution/install/reports/db.properties new file mode 100644 index 0000000..0a932d3 --- /dev/null +++ b/distribution/install/reports/db.properties @@ -0,0 +1,4 @@ +# Database configuration +database.url=TO_BE_DEFINED +database.schema.login=TO_BE_DEFINED +database.schema.password=TO_BE_DEFINED \ No newline at end of file diff --git a/distribution/install/reports/log/readme.txt b/distribution/install/reports/log/readme.txt new file mode 100644 index 0000000..a0ad7d5 --- /dev/null +++ b/distribution/install/reports/log/readme.txt @@ -0,0 +1 @@ +Ce dossier contient l'ensemble des traces d'exécution de la procédure de packaging et de mise à jour de la base de données. \ No newline at end of file diff --git a/distribution/install/reports/modules/modules.zip b/distribution/install/reports/modules/modules.zip new file mode 100644 index 0000000..eda6436 Binary files /dev/null and b/distribution/install/reports/modules/modules.zip differ diff --git a/distribution/install/reports/plsql/001_procedure_drop_sequence_if_exist.sql b/distribution/install/reports/plsql/001_procedure_drop_sequence_if_exist.sql new file mode 100644 index 0000000..049dbc3 --- /dev/null +++ b/distribution/install/reports/plsql/001_procedure_drop_sequence_if_exist.sql @@ -0,0 +1,11 @@ +CREATE OR REPLACE PROCEDURE PR_DROP_SEQ_IF_EXIST +(aSeqName IN VARCHAR2) +IS +BEGIN + EXECUTE IMMEDIATE 'DROP SEQUENCE ' || aSeqName; +EXCEPTION + WHEN OTHERS THEN + IF SQLCODE != -2289 THEN + RAISE; + END IF; +END; diff --git a/distribution/install/reports/plsql/002_procedure_drop_table_if_exist.sql b/distribution/install/reports/plsql/002_procedure_drop_table_if_exist.sql new file mode 100644 index 0000000..8d18c0e --- /dev/null +++ b/distribution/install/reports/plsql/002_procedure_drop_table_if_exist.sql @@ -0,0 +1,11 @@ +CREATE OR REPLACE PROCEDURE PR_DROP_IF_EXIST +(aTableName IN VARCHAR2) +IS +BEGIN + EXECUTE IMMEDIATE 'DROP TABLE ' || aTableName || ' PURGE'; +EXCEPTION + WHEN OTHERS THEN + IF SQLCODE != -942 THEN + RAISE; + END IF; +END; diff --git a/distribution/install/reports/update_database.bat b/distribution/install/reports/update_database.bat new file mode 100644 index 0000000..07944e0 --- /dev/null +++ b/distribution/install/reports/update_database.bat @@ -0,0 +1,35 @@ +@echo off +echo ========================= +echo REPORTING DATABASE UPDATE +echo ========================= + +IF "%DEPLOY_TOOL_HOME%"=="" ( + echo > DEPLOY_TOOL_HOME must be defined + exit/B +) + +IF "%JBOSS_HOME%"=="" ( + echo > JBOSS_HOME must be defined + exit/B +) + +echo copy sql update files +copy %DEPLOY_TOOL_HOME%\DBupdate\. %DEPLOY_TOOL_HOME%\sql +echo - Run database update +java -jar %DEPLOY_TOOL_HOME%\bin\install-reports.jar +if %ERRORLEVEL% EQU 1 ( + echo - Error detected, check install.log file +) else ( + echo - Database update run successfully +) + +echo clearing sql folder contents +del %DEPLOY_TOOL_HOME%\sql\* /Q + +echo ========================== +echo END OF DATABASE UPDATE +echo ========================== + +pause + +exit/B \ No newline at end of file diff --git a/distribution/install/reports/update_database.bat:Zone.Identifier b/distribution/install/reports/update_database.bat:Zone.Identifier new file mode 100644 index 0000000..a45e1ac --- /dev/null +++ b/distribution/install/reports/update_database.bat:Zone.Identifier @@ -0,0 +1,2 @@ +[ZoneTransfer] +ZoneId=3 diff --git a/distribution/install/teamcenter/data/bin/clause_propriete_update b/distribution/install/teamcenter/data/bin/clause_propriete_update new file mode 100644 index 0000000..0e9387a Binary files /dev/null and b/distribution/install/teamcenter/data/bin/clause_propriete_update differ diff --git a/distribution/install/teamcenter/data/bin/encrypt b/distribution/install/teamcenter/data/bin/encrypt new file mode 100644 index 0000000..dda9157 Binary files /dev/null and b/distribution/install/teamcenter/data/bin/encrypt differ diff --git a/distribution/install/teamcenter/data/queries/Report_All_Sequences.xml b/distribution/install/teamcenter/data/queries/Report_All_Sequences.xml new file mode 100644 index 0000000..4b54ccb --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_All_Sequences.xml @@ -0,0 +1,11 @@ + + + + +All Sequences of an ItemRevision + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_Alternate.xml b/distribution/install/teamcenter/data/queries/Report_Alternate.xml new file mode 100644 index 0000000..38d3551 --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_Alternate.xml @@ -0,0 +1,12 @@ + + + + +Toutes les revisions article de type Alternative + + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_ChangeNotice_R07.xml b/distribution/install/teamcenter/data/queries/Report_ChangeNotice_R07.xml new file mode 100644 index 0000000..14e2cab --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_ChangeNotice_R07.xml @@ -0,0 +1,11 @@ + + + + +Récupère toutes les change notice associé à une part ou un générique + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_ChangeRequest.xml b/distribution/install/teamcenter/data/queries/Report_ChangeRequest.xml new file mode 100644 index 0000000..734e066 --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_ChangeRequest.xml @@ -0,0 +1,11 @@ + + + + +Obtain a Change Request RevisionObtain a Change Request Revision + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_ChangeRequest_R07.xml b/distribution/install/teamcenter/data/queries/Report_ChangeRequest_R07.xml new file mode 100644 index 0000000..1b57097 --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_ChangeRequest_R07.xml @@ -0,0 +1,11 @@ + + + + +Récupère toutes les change request associé à une part ou un générique + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_ChangeRequest_With_Seq.xml b/distribution/install/teamcenter/data/queries/Report_ChangeRequest_With_Seq.xml new file mode 100644 index 0000000..ec42338 --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_ChangeRequest_With_Seq.xml @@ -0,0 +1,11 @@ + + + + +Obtain a Change Request Revision + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_ChangeRevision.xml b/distribution/install/teamcenter/data/queries/Report_ChangeRevision.xml new file mode 100644 index 0000000..5bf5ad6 --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_ChangeRevision.xml @@ -0,0 +1,11 @@ + + + + +Obtain a Change Request Revision + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_Change_from_Part.xml b/distribution/install/teamcenter/data/queries/Report_Change_from_Part.xml new file mode 100644 index 0000000..5498b3b --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_Change_from_Part.xml @@ -0,0 +1,11 @@ + + + + +Toutes les revisions article de type CR + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_DET.xml b/distribution/install/teamcenter/data/queries/Report_DET.xml new file mode 100644 index 0000000..4eee89a --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_DET.xml @@ -0,0 +1,12 @@ + + + + +Toutes les revisions article de type DET + + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_FPP_With_Seq.xml b/distribution/install/teamcenter/data/queries/Report_FPP_With_Seq.xml new file mode 100644 index 0000000..478b00f --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_FPP_With_Seq.xml @@ -0,0 +1,11 @@ + + + + +Obtain a FPP Revision with all the sequences.Obtain a FPP Revision with all the sequences. + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_Generic.xml b/distribution/install/teamcenter/data/queries/Report_Generic.xml new file mode 100644 index 0000000..4e727e1 --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_Generic.xml @@ -0,0 +1,11 @@ + + + + +Toutes les revisions article de type Generic + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_Generic_Assemb.xml b/distribution/install/teamcenter/data/queries/Report_Generic_Assemb.xml new file mode 100644 index 0000000..fbf8c49 --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_Generic_Assemb.xml @@ -0,0 +1,11 @@ + + + + +Toutes les revisions d'article de type Generic specifique montage + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_Item.xml b/distribution/install/teamcenter/data/queries/Report_Item.xml new file mode 100644 index 0000000..3ba1ce3 --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_Item.xml @@ -0,0 +1,11 @@ + + + + +Rechercher le(s) articles + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_ItemRevision.xml b/distribution/install/teamcenter/data/queries/Report_ItemRevision.xml new file mode 100644 index 0000000..30fe7b5 --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_ItemRevision.xml @@ -0,0 +1,11 @@ + + + + +Rechercher le(s) révisions d'articles + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_Product.xml b/distribution/install/teamcenter/data/queries/Report_Product.xml new file mode 100644 index 0000000..79bb4a7 --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_Product.xml @@ -0,0 +1,11 @@ + + + + +Toutes les revisions article de type Produit + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_ProductType.xml b/distribution/install/teamcenter/data/queries/Report_ProductType.xml new file mode 100644 index 0000000..4777f6d --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_ProductType.xml @@ -0,0 +1,11 @@ + + + + +Tous les formulaires Type ProduitTous les formulaires Type Produit + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_Relationship.xml b/distribution/install/teamcenter/data/queries/Report_Relationship.xml new file mode 100644 index 0000000..1e05aea --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_Relationship.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_Unit.xml b/distribution/install/teamcenter/data/queries/Report_Unit.xml new file mode 100644 index 0000000..42599e5 --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_Unit.xml @@ -0,0 +1,11 @@ + + + + +Toutes les revisions article de type Unit + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_Unit_from_CR.xml b/distribution/install/teamcenter/data/queries/Report_Unit_from_CR.xml new file mode 100644 index 0000000..1321c8d --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_Unit_from_CR.xml @@ -0,0 +1,11 @@ + + + + +Toutes les revisions article de type UnitToutes les revisions article de type Unit + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/queries/Report_Unit_with_WKF.xml b/distribution/install/teamcenter/data/queries/Report_Unit_with_WKF.xml new file mode 100644 index 0000000..3c3c3e9 --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_Unit_with_WKF.xml @@ -0,0 +1,11 @@ + + + + +Toutes les revisions article de type UnitToutes les revisions article de type Unit + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_WKF_ValidationUnit_on_Unit.xml b/distribution/install/teamcenter/data/queries/Report_WKF_ValidationUnit_on_Unit.xml new file mode 100644 index 0000000..f223603 --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_WKF_ValidationUnit_on_Unit.xml @@ -0,0 +1,11 @@ + + + + +Toutes les revisions article de type UnitToutes les revisions article de type Unit + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_WKF_on_Change.xml b/distribution/install/teamcenter/data/queries/Report_WKF_on_Change.xml new file mode 100644 index 0000000..7e0ac3b --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_WKF_on_Change.xml @@ -0,0 +1,11 @@ + + + + +Tous les Workflows associé à un Change ou correspondant à un certain nom.Tous les Workflows associé à un Change ou correspondant à un certain nom. + + + + diff --git a/distribution/install/teamcenter/data/queries/Report_WKF_on_ItemRevision.xml b/distribution/install/teamcenter/data/queries/Report_WKF_on_ItemRevision.xml new file mode 100644 index 0000000..4ebdcfd --- /dev/null +++ b/distribution/install/teamcenter/data/queries/Report_WKF_on_ItemRevision.xml @@ -0,0 +1,11 @@ + + + + +Tous les Workflows associé à un ItemRevision ou correspondant à un certain nom. + + + + diff --git a/distribution/install/teamcenter/data/queries/__pv_snecma_search_report_by_source.xml b/distribution/install/teamcenter/data/queries/__pv_snecma_search_report_by_source.xml new file mode 100644 index 0000000..86d4cd0 --- /dev/null +++ b/distribution/install/teamcenter/data/queries/__pv_snecma_search_report_by_source.xml @@ -0,0 +1,11 @@ + + + + +Query + + + + diff --git a/distribution/install/teamcenter/data/report_prefs.xml b/distribution/install/teamcenter/data/report_prefs.xml new file mode 100644 index 0000000..0b0cc2d --- /dev/null +++ b/distribution/install/teamcenter/data/report_prefs.xml @@ -0,0 +1,20 @@ + + + + + + Specifies the configuration for eQube by allowing the system administrator to change the Application server Protocol, Host, Port, eQube installation location and eQube servlet name. +By default, the following rules are provided: Protocol:http, Host:localhost, Port:80, Context:eQube, ServletName:eQubeServlet, ServiceDashboard:action=Dashboard. +Valid values for Protocol are http or https. + + Protocol:http + Host:localhost + Port:8080 + Context:kurt-web + ServletName:dispatcherServlet + User:username + Password:encrypted_password + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/reports/REPORT_R01/REPORT_R01.xml b/distribution/install/teamcenter/data/reports/REPORT_R01/REPORT_R01.xml new file mode 100644 index 0000000..3fcccb2 --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R01/REPORT_R01.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/reports/REPORT_R03/REPORT_R03.xml b/distribution/install/teamcenter/data/reports/REPORT_R03/REPORT_R03.xml new file mode 100644 index 0000000..7974d92 --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R03/REPORT_R03.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/reports/REPORT_R07/REPORT_R07.xml b/distribution/install/teamcenter/data/reports/REPORT_R07/REPORT_R07.xml new file mode 100644 index 0000000..fe34b33 --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R07/REPORT_R07.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/reports/REPORT_R10/REPORT_R10.xml b/distribution/install/teamcenter/data/reports/REPORT_R10/REPORT_R10.xml new file mode 100644 index 0000000..82e8921 --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R10/REPORT_R10.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/distribution/install/teamcenter/data/reports/REPORT_R11/REPORT_R11.xml b/distribution/install/teamcenter/data/reports/REPORT_R11/REPORT_R11.xml new file mode 100644 index 0000000..9b1510d --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R11/REPORT_R11.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/distribution/install/teamcenter/data/reports/REPORT_R13/REPORT_R13.xml b/distribution/install/teamcenter/data/reports/REPORT_R13/REPORT_R13.xml new file mode 100644 index 0000000..2c883ec --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R13/REPORT_R13.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/reports/REPORT_R15/REPORT_R15.xml b/distribution/install/teamcenter/data/reports/REPORT_R15/REPORT_R15.xml new file mode 100644 index 0000000..4ee3e39 --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R15/REPORT_R15.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/reports/REPORT_R16/REPORT_R16.xml b/distribution/install/teamcenter/data/reports/REPORT_R16/REPORT_R16.xml new file mode 100644 index 0000000..ba03d48 --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R16/REPORT_R16.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/reports/REPORT_R17/REPORT_R17.xml b/distribution/install/teamcenter/data/reports/REPORT_R17/REPORT_R17.xml new file mode 100644 index 0000000..8a273b5 --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R17/REPORT_R17.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/reports/REPORT_R19_Document/REPORT_R19_Document.xml b/distribution/install/teamcenter/data/reports/REPORT_R19_Document/REPORT_R19_Document.xml new file mode 100644 index 0000000..5d6680b --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R19_Document/REPORT_R19_Document.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/reports/REPORT_R19_Document_Design/REPORT_R19_Document_Design.xml b/distribution/install/teamcenter/data/reports/REPORT_R19_Document_Design/REPORT_R19_Document_Design.xml new file mode 100644 index 0000000..34b8760 --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R19_Document_Design/REPORT_R19_Document_Design.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/reports/REPORT_R19_Document_Revision/REPORT_R19_Document_Revision.xml b/distribution/install/teamcenter/data/reports/REPORT_R19_Document_Revision/REPORT_R19_Document_Revision.xml new file mode 100644 index 0000000..e11a955 --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R19_Document_Revision/REPORT_R19_Document_Revision.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/reports/REPORT_R20/REPORT_R20.xml b/distribution/install/teamcenter/data/reports/REPORT_R20/REPORT_R20.xml new file mode 100644 index 0000000..246a09c --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R20/REPORT_R20.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/reports/REPORT_R21/REPORT_R21.xml b/distribution/install/teamcenter/data/reports/REPORT_R21/REPORT_R21.xml new file mode 100644 index 0000000..e6314fa --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R21/REPORT_R21.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/reports/REPORT_R22/REPORT_R22.xml b/distribution/install/teamcenter/data/reports/REPORT_R22/REPORT_R22.xml new file mode 100644 index 0000000..fd70201 --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R22/REPORT_R22.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/reports/REPORT_R23/REPORT_R23.xml b/distribution/install/teamcenter/data/reports/REPORT_R23/REPORT_R23.xml new file mode 100644 index 0000000..878bd92 --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R23/REPORT_R23.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/reports/REPORT_R24/REPORT_R24.xml b/distribution/install/teamcenter/data/reports/REPORT_R24/REPORT_R24.xml new file mode 100644 index 0000000..2601a14 --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R24/REPORT_R24.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/reports/REPORT_R25/REPORT_R25.xml b/distribution/install/teamcenter/data/reports/REPORT_R25/REPORT_R25.xml new file mode 100644 index 0000000..353943b --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R25/REPORT_R25.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/reports/REPORT_R26_Item/REPORT_R26_Item.xml b/distribution/install/teamcenter/data/reports/REPORT_R26_Item/REPORT_R26_Item.xml new file mode 100644 index 0000000..022a4f0 --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R26_Item/REPORT_R26_Item.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/reports/REPORT_R26_Item_Revision/REPORT_R26_Item_Revision.xml b/distribution/install/teamcenter/data/reports/REPORT_R26_Item_Revision/REPORT_R26_Item_Revision.xml new file mode 100644 index 0000000..37c8444 --- /dev/null +++ b/distribution/install/teamcenter/data/reports/REPORT_R26_Item_Revision/REPORT_R26_Item_Revision.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/distribution/install/teamcenter/data/revision_rule/revisionrule.xml b/distribution/install/teamcenter/data/revision_rule/revisionrule.xml new file mode 100644 index 0000000..ff798da --- /dev/null +++ b/distribution/install/teamcenter/data/revision_rule/revisionrule.xml @@ -0,0 +1,139 @@ + + +
+ + DMA Configuration Rapport PU + + Product + Generic + Generic Assemb + RF Generic + RF Part + RF Part Assemb + RF Admin + RF Admin A + RF Admin AG + RF Admin AP + + + + Part Aero + Part No Aero + Part Mat + Standard + DET + Alternate + Part Assemb + + + + + + + + + + + + DMA Configuration Descriptif R25 + + + RF Generic + RF Admin + RF Admin AG + Descriptif + Generic + + + + Part Aero + + + + + + Part Aero + + + + + + + DMA Configuration Interface R01 + + Product + Generic + Generic Assemb + RF Generic + RF Part + RF Part Assemb + RF Admin + RF Admin A + RF Admin AG + RF Admin AP + Super Model + + + + RF Part + RF Admin + RF Admin AP + + + + + + Part Aero + Part No Aero + Part Mat + Standard + DET + Alternate + Part Assemb + + + + + + + + + + + + DMA Configuration Interface PU R23 + + + Product + Generic + Generic Assemb + RF Generic + RF Part + RF Part Assemb + RF Admin + RF Admin A + RF Admin AG + RF Admin AP + Super Model + + + + + Part Aero + Part No Aero + Part Mat + Standard + DET + Alternate + Part Assemb + + + + + + + + + + +
diff --git a/distribution/install/teamcenter/report_install.pl b/distribution/install/teamcenter/report_install.pl new file mode 100644 index 0000000..e4fde5b --- /dev/null +++ b/distribution/install/teamcenter/report_install.pl @@ -0,0 +1,273 @@ +my $env=0; + +if ($ENV{TC_ROOT} eq "") { + print "Initialiser TC_ROOT avant de lancer le script\n"; + $env = 1; +} + +if ($ENV{TC_DATA} eq "") { + print "Initialiser TC_DATA avant de lancer le script\n"; + $env = 1; +} + +if ($env == 1) { + exit 1; +} + +my $myversion="${project.version}"; +my $to_soa = $ENV{TC_DATA}."/soa/"; +my $to_bin = $ENV{TC_ROOT}."/bin/"; +my $args=0; +my $usr=""; +my $pwd=""; +my $grp=""; + +$numArgs = $#ARGV + 1; + +foreach $argnum (0 .. $#ARGV) { + $arg = $ARGV[$argnum]; + if ($arg =~ m/^-u=/) { + $args = $args + 1; + $usr = $arg; + $usr =~ s/^-u=//; + } + if ($arg =~ m/^-p=/) { + $args = $args + 1; + $pwd = $arg; + $pwd =~ s/^-p=//; + } + if ($arg =~ m/^-g=/) { + $args = $args + 1; + $grp = $arg; + $grp =~ s/^-g=//; + } +} + +if ($args != 3 || $usr eq "" || $pwd eq "" || $grp eq "") { + print "Utilisation 'perl report_install.pl -u= -p= -g='\n"; + print " -u : login utilisateur dba\n"; + print " -p : mot de passe\n"; + print " -g : groupe dba\n"; + exit 1; +} + +my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); +my $datedujour = $mday."/".($mon+1)."/".(1900+$year)."-".$hour.":".$min.":".$sec; +my $suffixe = (1900+$year).($mon+1).$mday.$hour.$min.$sec; + +system "echo '------- INSTALLATION REPORT v" .$myversion. " -------'"; + +system "echo ' Import des reports'"; + +my $repertoireReports = "./data/reports"; +opendir fh_rep, $repertoireReports or die "impossible d'ouvrir le r�pertoire ".$repertoireReports."\n"; + +my $reportId = ""; +system "echo 'Import de la definition des rapports'"; +while( ($filename = readdir(fh_rep))){ + next if ($filename eq "." or $filename eq ".."); + $reportId = $filename; + system "echo ' + Import de ".$reportId."'"; + system "import_export_reports -import -u=".$usr." -p=".$pwd." -g=".$grp." -v -overwrite -stageDir=./data/reports -reportId=\"".$reportId."\""; +} +closedir fh_rep or die "Impossible de fermer le r�pertoire ".$repertoireReports."\n"; + +system "echo 'Import des queries'"; + +my $repertoireQueries = "./data/queries"; +opendir fh_rep, $repertoireQueries or die "impossible d'ouvrir le r�pertoire ".$repertoireQueries."\n"; + my @fic_rep_list = grep { !/^\.\.?$/ } readdir fh_rep; +closedir fh_rep or die "Impossible de fermer le r�pertoire ".$repertoireQueries."\n"; + +concat_query_files($repertoireQueries); +system "echo ' Import des requetes en une fois'"; +$target=$repertoireQueries."/all_queries.xml"; +if (-e $target){ + system "plmxml_import -u=".$usr." -p=".$pwd." -g=".$grp." -import_mode=overwrite -xml_file=".$target; +} +else { + print "File ".$target." cannot be found\n"; +} + +system "echo ' Import des policies'"; +copy_policy_files("./data/policies"); + +system "echo ' Import du binaire d encryptage"; +system "cp ./data/bin/encrypt ".$to_bin; +system "chmod 755 ".$to_bin."encrypt"; + + +system "echo 'Import de la pr�f�rence report'"; +system "preferences_manager -u=".$usr." -p=".$pwd." -g=".$grp." -mode=import -scope=SITE -file=./data/report_prefs.xml -action=OVERRIDE"; + +system "preferences_manager -u=" .$usr. " -p=" .$pwd. " -g=" .$grp. " -mode=import -preference=\"PV SNECMA Reports deployment date\" -scope=SITE -values=" .$datedujour. " -action=OVERRIDE"; +system "preferences_manager -u=" .$usr. " -p=" .$pwd. " -g=" .$grp. " -mode=import -preference=\"PV SNECMA Reports version\" -scope=SITE -values=" .$myversion. " -action=OVERRIDE"; + +system "echo ' Import des Regles de Revision'"; + +system "plmxml_import -u=" .$usr. " -p=" .$pwd. " -g=" .$grp. " -xml_file=./data/revision_rule/revisionrule.xml -import_mode=overwrite"; + +system "echo '----- FIN INSTALLATION REPORT v" .$myversion. " -------'"; + +sub promptUser { + #-------------------------------------------------------------------# + # two possible input arguments - $promptString, and $defaultValue # + # make the input arguments local variables. # + #-------------------------------------------------------------------# + + local($promptString,$defaultValue) = @_; + + #-------------------------------------------------------------------# + # if there is a default value, use the first print statement; if # + # no default is provided, print the second string. # + #-------------------------------------------------------------------# + + if ($defaultValue) { + print $promptString, "[", $defaultValue, "]: "; + } else { + print $promptString, ": "; + } + + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + + + #------------------------------------------------------------------# + # remove the newline character from the end of the input the user # + # gave us. # + #------------------------------------------------------------------# + + chomp; + + #-----------------------------------------------------------------# + # if we had a $default value, and the user gave us input, then # + # return the input; if we had a default, and they gave us no # + # no input, return the $defaultValue. # + # # + # if we did not have a default value, then just return whatever # + # the user gave us. if they just hit the key, # + # the calling routine will have to deal with that. # + #-----------------------------------------------------------------# + + if ("$defaultValue") { + return $_ ? $_ : $defaultValue; # return $_ if it has a value + } else { + return $_; + } +} + +sub copy_policy_files{ + # + # Copie toutes les policies dans tous les sous-dossiers vers le dossier SOA, *a plat* + # system "cp -Rf ./data/policies/reports/SOME_FOLDER/SOME_FILE.xml " . $to_soa; + + my $source_dir = $_[0]; + + print "Import de la policy: dossier = ".$source_dir."\n"; + + # entete du fichier genere + opendir fh_rep, $source_dir or die "impossible d'ouvrir le r�pertoire ".$source_dir."\n"; + my @fic_rep_list = grep { !/^\.\.?$/ } readdir fh_rep; + closedir fh_rep or die "Impossible de fermer le r�pertoire ".$source_dir."\n"; + + # Browse all the folder"s content + foreach my $elem ( @fic_rep_list) { + # Skipping files begginning whith . or .svn + my $absoluteElem = $source_dir . '/'.$elem; + if ($elem!~/^\./ and $elem!~/.svn/) { + # If the file is a directory + if (-d $absoluteElem) { + # Here is where we recurse. + # This makes a new call to process_files() + # using a new directory we just found. + copy_policy_files ($absoluteElem); + } else { + # If it isn't a directory, lets just do some + # processing on it. + print " Import de la policy: ".$elem."\n"; + system "cp -Rf ".$absoluteElem." ".$to_soa."/policies"; + } + }else{ + print " Element ".$absoluteElem." ignor�\n"; + } + } +} + +sub concat_query_files{ + # + # all-queries.pl + # + # concat�ne toutes les queries en 1 seul fichier + + my $source_dir = $_[0]; + #printf("$ARGV[0]"); + #print("--------------------------"); + + # entete du fichier genere + opendir fh_rep, $source_dir or die "impossible d'ouvrir le r�pertoire ".$source_dir."\n"; + my @fic_rep_list = grep { !/^\.\.?$/ } readdir fh_rep; + closedir fh_rep or die "Impossible de fermer le r�pertoire ".$source_dir."\n"; + + open (OUTPUTFILE, "> ".$source_dir."/all_queries.xml") || die "Can't write in ".$outputFile." : $!"; + print OUTPUTFILE "\n"; + print OUTPUTFILE "\n"; + + for $j (0..((scalar @fic_rep_list) -1) ) + { + if ( $fic_rep_list[$j] eq "delete_queries.xml" || $fic_rep_list[$j] eq "all_queries.xml" || $fic_rep_list[$j] eq ".svn") + { + print "skipping query no ".($j+1)."/".scalar @fic_rep_list." : ".$fic_rep_list[$j]."\n"; + } + if ($fic_rep_list[$j]!~/^\./ and $fic_rep_list[$j]!~/delete_queries.xml/ and $fic_rep_list[$j]!~/all_queries.xml/ and $fic_rep_list[$j]!~/.svn/) + { + print "Concat query no ".($j+1)."/".scalar @fic_rep_list." : ".$fic_rep_list[$j]."\n"; + open(F, $source_dir."/".$fic_rep_list[$j]);# || die "Probl�me � l\'ouverture : $!"; + $i = 0; + while($line = ) + { + # doit contenir : plmxml_bus:SavedQueryDef + # doit contenir : plmxml_bus:QueryClause + # remplacer : / ) + { + print OUTPUTFILE $line; #On �crit la ligne dans le fichier r�sultat + } + if ($line =~ m/\<\/Description\>/ ) + { + print OUTPUTFILE $line; #On �crit la ligne dans le fichier r�sultat + } + if ($line =~ m/plmxml_bus:QueryClause/ ) + { + $k=$j+1000; + $line =~ s/\"id."+/\"id$k\"/; + print OUTPUTFILE $line; #On �crit la ligne dans le fichier r�sultat + } + # if ($line =~ m/plmxml_bus:Text/ ) + # { + # $l=$i+2000; + # $line =~ s/\"id."+/\"id$l\"/; + # $line =~ s/\<\/plmxml_bus:PLMXMLBusinessTypes\>//; + # print OUTPUTFILE $line; #On �crit la ligne dans le fichier r�sultat + # } + $i ++; + } + $j ++; + #print "\nNombre de lignes : $fic_rep_list[$j] $i\n"; + close F ;#|| die "Probl�me � la fermeture : $!"; + } + } + + print OUTPUTFILE "\n"; + + close OUTPUTFILE; +} diff --git a/distribution/pom.xml b/distribution/pom.xml new file mode 100644 index 0000000..68aaa11 --- /dev/null +++ b/distribution/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + distribution + project distribution + pom + Full report package including tool and utilities + + + ${project.parent.name}-${project.parent.version} + + + + com.capgemini.reports + kurt + 1.32.9 + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + package-report + package + + single + + + false + snecma-reports-${project.parent.version} + + assembly.xml + + + + + + + + + + + release + + + + com.maestrodev + collabnet-maven-plugin + + + + + + diff --git a/jasper/pom.xml b/jasper/pom.xml new file mode 100644 index 0000000..aa18bc1 --- /dev/null +++ b/jasper/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + jasper + jar + jasper + + + com.capgemini.reports + kurt + 1.32.9 + + + + + + org.testng + testng + test + + + org.assertj + assertj-core + test + + + + + org.slf4j + slf4j-api + + + + org.jboss.spec.javax.annotation + jboss-annotations-api_1.1_spec + + + + javax.enterprise + cdi-api + + + + + + + + + + net.sf.jasperreports + jasperreports + 5.6.1 + + + + diff --git a/jasper/src/main/java/com/capgemini/reports/jasper/compilers/JasperCompiler.java b/jasper/src/main/java/com/capgemini/reports/jasper/compilers/JasperCompiler.java new file mode 100644 index 0000000..66ee659 --- /dev/null +++ b/jasper/src/main/java/com/capgemini/reports/jasper/compilers/JasperCompiler.java @@ -0,0 +1,69 @@ +package com.capgemini.reports.jasper.compilers; + +import com.capgemini.reports.jasper.fillers.MultiFiller; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperCompileManager; +import net.sf.jasperreports.engine.JasperReport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +/** + * This class is able to compile some template files (.jrxml) into a {@link JasperReport} object. + */ +public final class JasperCompiler { + private static final Logger LOGGER = LoggerFactory.getLogger(MultiFiller.class); + + private static final String JASPER_COMPILATION = "JASPER compilation"; + private static final String JASPER_REPORT_COMPILING_TIME_XXX_MS = "JASPER report Compiling time : {} ms"; + private static final String EXCEPTION_CAUGHT = "Jasper Report Exception caught while compiling report"; + + private JasperCompiler() { + + } + + /** + * Builds a report printer with the provided {@link InputStream} template. + * + * @param templateStream the template file to use for this report as an {@link InputStream} + * @return the compiled {@link JasperReport} object + * @throws JRException if Jasper could not compile the report + */ + public static JasperReport compile(final InputStream templateStream) throws JRException { + LOGGER.debug(JASPER_COMPILATION); + long start = System.currentTimeMillis(); + + try { + JasperReport compiledReport = JasperCompileManager.compileReport(templateStream); + LOGGER.debug(JASPER_REPORT_COMPILING_TIME_XXX_MS, System.currentTimeMillis() - start); + return compiledReport; + } catch (JRException e) { + LOGGER.error(EXCEPTION_CAUGHT, e); + throw e; + } + } + + /** + * Builds a report printer with the provided {@link String} template. + * + * @param generatedTemplate the template file to use for this report in a {@link String} + * @return the compiled {@link JasperReport} object + * @throws JRException if Jasper could not compile the report + */ + public static JasperReport compile(final String generatedTemplate) throws JRException { + LOGGER.debug(JASPER_COMPILATION); + long start = System.currentTimeMillis(); + + try { + InputStream templateStream = new ByteArrayInputStream(generatedTemplate.getBytes()); + JasperReport compiledReport = JasperCompileManager.compileReport(templateStream); + LOGGER.debug(JASPER_REPORT_COMPILING_TIME_XXX_MS, System.currentTimeMillis() - start); + return compiledReport; + } catch (JRException e) { + LOGGER.error(EXCEPTION_CAUGHT, e); + throw e; + } + } +} diff --git a/jasper/src/main/java/com/capgemini/reports/jasper/fillers/JasperFiller.java b/jasper/src/main/java/com/capgemini/reports/jasper/fillers/JasperFiller.java new file mode 100644 index 0000000..19312f5 --- /dev/null +++ b/jasper/src/main/java/com/capgemini/reports/jasper/fillers/JasperFiller.java @@ -0,0 +1,20 @@ +package com.capgemini.reports.jasper.fillers; + +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperPrint; +import net.sf.jasperreports.engine.JasperReport; + +/** + * This class is able to populate a {@link JasperReport} template with some data and parameters . + */ +public interface JasperFiller { + + /** + * Returns the a {@link JasperPrint} filled report. + * + * @return the populated {@link JasperPrint} report + * @throws JRException + */ + JasperPrint generate() throws JRException; + +} diff --git a/jasper/src/main/java/com/capgemini/reports/jasper/fillers/MonoFiller.java b/jasper/src/main/java/com/capgemini/reports/jasper/fillers/MonoFiller.java new file mode 100644 index 0000000..4f244a5 --- /dev/null +++ b/jasper/src/main/java/com/capgemini/reports/jasper/fillers/MonoFiller.java @@ -0,0 +1,46 @@ +package com.capgemini.reports.jasper.fillers; + +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperFillManager; +import net.sf.jasperreports.engine.JasperPrint; +import net.sf.jasperreports.engine.JasperReport; +import net.sf.jasperreports.engine.data.JRMapCollectionDataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.Box.Filler; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * This class builds a simple report. + */ +public class MonoFiller implements JasperFiller { + private static final Logger LOGGER = LoggerFactory.getLogger(MonoFiller.class); + private final JasperReport compiledTemplate; + private final Collection> data; + private final Map parameters; + + /** + * Builds a basic Report {@link Filler}. + * + * @param compiledTemplate the {@link JasperReport} used as template + * @param parameters some report-wide parameters, stored as a {@link Map} with their name as a String key + * @param data a {@link List} of {@link Map Maps} representing a series of objects to be added to the report one after the other + */ + public MonoFiller(final JasperReport compiledTemplate, final Collection> data, final Map parameters) { + this.compiledTemplate = compiledTemplate; + this.data = data; + this.parameters = parameters; + } + + @Override + public final JasperPrint generate() throws JRException { + LOGGER.debug("JASPER filling"); + long start = System.currentTimeMillis(); + JasperPrint print = JasperFillManager.fillReport(compiledTemplate, parameters, new JRMapCollectionDataSource(data)); + LOGGER.debug("JASPER report Filling time : {} ms, {} pages expected", System.currentTimeMillis() - start, print.getPages().size()); + return print; + } +} diff --git a/jasper/src/main/java/com/capgemini/reports/jasper/fillers/MultiFiller.java b/jasper/src/main/java/com/capgemini/reports/jasper/fillers/MultiFiller.java new file mode 100644 index 0000000..8f217b4 --- /dev/null +++ b/jasper/src/main/java/com/capgemini/reports/jasper/fillers/MultiFiller.java @@ -0,0 +1,81 @@ +package com.capgemini.reports.jasper.fillers; + +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperFillManager; +import net.sf.jasperreports.engine.JasperPrint; +import net.sf.jasperreports.engine.JasperReport; +import net.sf.jasperreports.engine.data.JRMapCollectionDataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.Box.Filler; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * This class is able to build a report containing one or several sub-reports (tables etc). + */ +public class MultiFiller implements JasperFiller { + private static final Logger LOGGER = LoggerFactory.getLogger(MultiFiller.class); + + private static final String DATA_KEY = "DATA"; + private static final String TEMPLATE_KEY = "TEMPLATE"; + private final JasperReport compiledTemplate; + private final Collection> data; + private final Map parameters; + + /** + * Builds a report {@link Filler} which is able to incorporate sub-reports (for tables etc). + * + * @param compiledTemplate the {@link JasperReport} used as template for the main report + * @param data a {@link List} of {@link Map Maps} representing a series of objects to be added to the report one after the other + * @param parameters some report-wide parameters, stored as a {@link Map} with their name as a String key + */ + public MultiFiller(final JasperReport compiledTemplate, final Collection> data, final Map parameters) { + this.compiledTemplate = compiledTemplate; + this.data = data; + this.parameters = parameters; + } + + /** + * Adds a sub-report to this report. + * + * @param key the {@link String} key in this 'father' template's parameters which leads to all the sub-report data + * @param template the {@link JasperReport} template to use for the sub-report + * @param subReportData the data to use in the sub-report + * @param subReportParameters the sub-report's parameters (parameters are subreport-wide constants) + */ + public void addSubReport(final String key, final JasperReport template, final Collection> subReportData, + final Map subReportParameters) { + Map reportMap = new HashMap<>(); + reportMap.put(TEMPLATE_KEY, template); + reportMap.put(DATA_KEY, subReportData); + reportMap.putAll(subReportParameters); + parameters.put(key, reportMap); + } + + /** + * Adds a sub-report (which is also a composite sub-report) to this report. + * + * @param key the {@link String} key in this 'father' template's parameters which leads to all the sub-report data + * @param subReport the {@link MultiFiller} to use for the sub-report + */ + public void addSubReport(final String key, final MultiFiller subReport) { + Map reportMap = new HashMap<>(); + reportMap.put(TEMPLATE_KEY, subReport.compiledTemplate); + reportMap.put(DATA_KEY, subReport.data); + reportMap.putAll(subReport.parameters); + parameters.put(key, reportMap); + } + + @Override + public final JasperPrint generate() throws JRException { + LOGGER.info("JASPER filling (multi-report)"); + long start = System.currentTimeMillis(); + JasperPrint print = JasperFillManager.fillReport(compiledTemplate, parameters, new JRMapCollectionDataSource(data)); + LOGGER.info("JASPER report Filling time : {} ms, {} pages expected", System.currentTimeMillis() - start, print.getPages().size()); + return print; + } +} diff --git a/jasper/src/main/java/com/capgemini/reports/jasper/printers/JasperCSVPrinter.java b/jasper/src/main/java/com/capgemini/reports/jasper/printers/JasperCSVPrinter.java new file mode 100644 index 0000000..7cb320a --- /dev/null +++ b/jasper/src/main/java/com/capgemini/reports/jasper/printers/JasperCSVPrinter.java @@ -0,0 +1,44 @@ +package com.capgemini.reports.jasper.printers; + +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperPrint; +import net.sf.jasperreports.engine.export.JRCsvExporter; +import net.sf.jasperreports.export.SimpleExporterInput; +import net.sf.jasperreports.export.SimpleWriterExporterOutput; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; + +/** + * Prints a JASPER report to .CSV. + */ +public class JasperCSVPrinter implements JasperPrinter { + private static final Logger LOGGER = LoggerFactory.getLogger(JasperCSVPrinter.class); + + private final String outputFilePath; + private final String outputFileName; + + /** + * Builds a CSV report printer with the provided parameters. + * + * @param outputFilePath the path to the folder where the final output report should be saved + * @param outputFileName the final output report filename + */ + public JasperCSVPrinter(final String outputFilePath, final String outputFileName) { + this.outputFilePath = outputFilePath; + this.outputFileName = outputFileName; + } + + @Override + public File print(final JasperPrint print) throws JRException { + long start = System.currentTimeMillis(); + JRCsvExporter exporter = new JRCsvExporter(); + exporter.setExporterInput(new SimpleExporterInput(print)); + File destFile = new File(this.outputFilePath, this.outputFileName + ".csv"); + exporter.setExporterOutput(new SimpleWriterExporterOutput(destFile)); + exporter.exportReport(); + LOGGER.info("CSV creation time : {} ms", System.currentTimeMillis() - start); + return destFile; + } +} diff --git a/jasper/src/main/java/com/capgemini/reports/jasper/printers/JasperPDFPrinter.java b/jasper/src/main/java/com/capgemini/reports/jasper/printers/JasperPDFPrinter.java new file mode 100644 index 0000000..ccf4552 --- /dev/null +++ b/jasper/src/main/java/com/capgemini/reports/jasper/printers/JasperPDFPrinter.java @@ -0,0 +1,39 @@ +package com.capgemini.reports.jasper.printers; + +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperExportManager; +import net.sf.jasperreports.engine.JasperPrint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; + +/** + * Prints a JASPER report to .PDF. + */ +public class JasperPDFPrinter implements JasperPrinter { + private static final Logger LOGGER = LoggerFactory.getLogger(JasperPDFPrinter.class); + + private final String outputFilePath; + private final String outputFileName; + + /** + * Builds a PDF report printer with the provided parameters. + * + * @param outputFilePath the path to the folder where the final output report should be saved + * @param outputFileName the final output report filename + */ + public JasperPDFPrinter(final String outputFilePath, final String outputFileName) { + this.outputFilePath = outputFilePath; + this.outputFileName = outputFileName; + } + + @Override + public File print(final JasperPrint print) throws JRException { + long start = System.currentTimeMillis(); + String theFileName = outputFilePath + '/' + outputFileName + ".pdf"; + JasperExportManager.exportReportToPdfFile(print, theFileName); + LOGGER.info("PDF creation time {}: {} ms", theFileName, System.currentTimeMillis() - start); + return new File(theFileName); + } +} diff --git a/jasper/src/main/java/com/capgemini/reports/jasper/printers/JasperPrinter.java b/jasper/src/main/java/com/capgemini/reports/jasper/printers/JasperPrinter.java new file mode 100644 index 0000000..00fb786 --- /dev/null +++ b/jasper/src/main/java/com/capgemini/reports/jasper/printers/JasperPrinter.java @@ -0,0 +1,21 @@ +package com.capgemini.reports.jasper.printers; + +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperPrint; + +import java.io.File; + +/** + * Interface pour un gestionnaire d'impression JASPER. + */ +public interface JasperPrinter { + + /** + * Imprime le rapport sous le format desire. + * + * @param print the + * @return the generated {@link File} + */ + File print(final JasperPrint print) throws JRException; + +} diff --git a/jasper/src/main/java/com/capgemini/reports/jasper/printers/JasperXLSXPrinter.java b/jasper/src/main/java/com/capgemini/reports/jasper/printers/JasperXLSXPrinter.java new file mode 100644 index 0000000..dd46afa --- /dev/null +++ b/jasper/src/main/java/com/capgemini/reports/jasper/printers/JasperXLSXPrinter.java @@ -0,0 +1,55 @@ +package com.capgemini.reports.jasper.printers; + +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperPrint; +import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter; +import net.sf.jasperreports.export.SimpleExporterInput; +import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput; +import net.sf.jasperreports.export.SimpleXlsxReportConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; + +/** + * Prints a JASPER report to .XLSX. + */ +public class JasperXLSXPrinter implements JasperPrinter { + private static final Logger LOGGER = LoggerFactory.getLogger(JasperXLSXPrinter.class); + + private final String outputFilePath; + private final String outputFileName; + + /** + * Builds a XLSX report printer with the provided parameters. + * + * @param outputFilePath the path to the folder where the final output report should be saved + * @param outputFileName the final output report filename + */ + public JasperXLSXPrinter(final String outputFilePath, final String outputFileName) { + this.outputFilePath = outputFilePath; + this.outputFileName = outputFileName; + } + + @Override + public File print(final JasperPrint print) throws JRException { + long start = System.currentTimeMillis(); + + + JRXlsxExporter exporter = new JRXlsxExporter(); + exporter.setExporterInput(new SimpleExporterInput(print)); + File destFile = new File(this.outputFilePath, this.outputFileName + ".xlsx"); + exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(destFile)); + + SimpleXlsxReportConfiguration configuration = new SimpleXlsxReportConfiguration(); + configuration.setRemoveEmptySpaceBetweenRows(true); + configuration.setRemoveEmptySpaceBetweenColumns(true); + + exporter.setConfiguration(configuration); + exporter.exportReport(); + + LOGGER.info("XLSX creation time : {} ms", System.currentTimeMillis() - start); + return destFile; + } + +} diff --git a/jasper/src/test/java/com/capgemini/reports/jasper/compilers/JasperCompilerTest.java b/jasper/src/test/java/com/capgemini/reports/jasper/compilers/JasperCompilerTest.java new file mode 100644 index 0000000..0f1a99e --- /dev/null +++ b/jasper/src/test/java/com/capgemini/reports/jasper/compilers/JasperCompilerTest.java @@ -0,0 +1,19 @@ +package com.capgemini.reports.jasper.compilers; + +import net.sf.jasperreports.engine.JRException; +import org.testng.annotations.Test; + +import java.io.InputStream; + +import static org.assertj.core.api.Assertions.assertThat; + + +public class JasperCompilerTest { + private static final String JASPER_TEMPLATE = "/Jasper/template/report_r01.jrxml"; + + @Test + public void compileTest() throws JRException { + InputStream templateStream = getClass().getResourceAsStream(JASPER_TEMPLATE); + assertThat(JasperCompiler.compile(templateStream)).isNotNull(); + } +} diff --git a/jasper/src/test/java/com/capgemini/reports/jasper/fillers/MonoFillerTest.java b/jasper/src/test/java/com/capgemini/reports/jasper/fillers/MonoFillerTest.java new file mode 100644 index 0000000..12a514e --- /dev/null +++ b/jasper/src/test/java/com/capgemini/reports/jasper/fillers/MonoFillerTest.java @@ -0,0 +1,45 @@ +package com.capgemini.reports.jasper.fillers; + +import com.capgemini.reports.jasper.compilers.JasperCompiler; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperPrint; +import net.sf.jasperreports.engine.JasperReport; +import org.testng.annotations.Test; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +public class MonoFillerTest { + + private static final String JASPER_TEMPLATE = "/Jasper/template/report_r20/page2/r20_p2_generics.jrxml"; + + @Test + public void generateTest() throws JRException { + // Compile the report + InputStream templateStream = getClass().getResourceAsStream(JASPER_TEMPLATE); + JasperReport reportTemplate = JasperCompiler.compile(templateStream); + + // Fill with some data + JasperFiller filler = new MonoFiller(reportTemplate, createData(10), new HashMap()); + JasperPrint print = filler.generate(); + assertThat(print).isNotNull(); + assertThat(print.getPages()).isNotEmpty(); + } + + private List> createData(final int numLines) { + List> data = new ArrayList<>(); + for (int num = 0; num < numLines; num++) { + Map map = new HashMap<>(); + map.put("GENERIC_AVEC_RUPTURE", "Generic-" + num); + map.put("ID_PART_AVANT", "Part Avant-" + num); + map.put("ID_PART_APRES", "Part Après-" + num); + data.add(map); + } + return data; + } +} diff --git a/jasper/src/test/java/com/capgemini/reports/jasper/fillers/MultiFillerTest.java b/jasper/src/test/java/com/capgemini/reports/jasper/fillers/MultiFillerTest.java new file mode 100644 index 0000000..22ca70f --- /dev/null +++ b/jasper/src/test/java/com/capgemini/reports/jasper/fillers/MultiFillerTest.java @@ -0,0 +1,87 @@ +package com.capgemini.reports.jasper.fillers; + +import com.capgemini.reports.jasper.compilers.JasperCompiler; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperPrint; +import net.sf.jasperreports.engine.JasperReport; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + + +public class MultiFillerTest { + + private static final String SUBREPORT_P1 = "SUBREPORT_P1"; + private static final String JASPER_TEMPLATE_PAGE1 = "/Jasper/template/report_r20/report_r20_p1.jrxml"; + private static final String JASPER_TEMPLATE_MASTER = "/Jasper/template/report_r20/report_r20_master.jrxml"; + + + @Test + public void fillTest() throws JRException, IOException { + InputStream templateStream = getClass().getResourceAsStream(JASPER_TEMPLATE_MASTER); + InputStream page1Stream = getClass().getResourceAsStream(JASPER_TEMPLATE_PAGE1); + JasperReport mainReport = JasperCompiler.compile(templateStream); + JasperReport page1Report = JasperCompiler.compile(page1Stream); + MultiFiller filler = new MultiFiller(mainReport, setupEmptyData(), setupMainParameters()); + filler.addSubReport(SUBREPORT_P1, page1Report, setupPage1Data(5), setupPage1Parameters()); + JasperPrint print = filler.generate(); + assertThat(print.getPages()).isNotEmpty(); + } + + private List> setupEmptyData() { + List> list = new ArrayList<>(); + list.add(new HashMap()); + return list; + } + + private Map setupMainParameters() throws IOException { + Map parametersMap = new HashMap<>(); + try (InputStream imageStream = getClass().getResourceAsStream("/Jasper/images/Snecma_logo.png")) { + BufferedImage image = ImageIO.read(imageStream); + parametersMap.put("SNECMA_LOGO", image); + parametersMap.put("report_title", "Titre rapport principal"); + return parametersMap; + } + } + + private List> setupPage1Data(final int numberOfElements) { + List> lmrMaps = new ArrayList<>(); + for (int num = 0; num < numberOfElements; num++) { + Map lmrMap = new HashMap<>(); + lmrMap.put("CHANGE_REQUEST_APPLI", "APPLI-" + num); + lmrMap.put("CHANGE_REQUEST_IDENTIFIANT", "ID-" + num); + lmrMap.put("CHANGE_REQUEST_NOM", "NOM-" + num); + lmrMap.put("CHANGE_REQUEST_NO_APPRO_SO", "NO_APPRO-" + num); + lmrMaps.add(lmrMap); + } + return lmrMaps; + } + + private Map setupPage1Parameters() { + Map map = new HashMap<>(); + map.put("PRODUIT", "produit"); + map.put("UNIT_AVANT", "30"); + map.put("UNIT_APRES", "40"); + map.put("EXCEPTIONNEL_AVANT", "oui"); + map.put("EXCEPTIONNEL_APRES", "non"); + map.put("TITRE_P1", "titre 1"); + map.put("TITRE_P2", "titre 2"); + map.put("TITRE_P3", "titre 3"); + map.put("TITRE_P4", "titre 4"); + map.put("DOMAINE_PRODUIT_AVANT", "domaine avant"); + map.put("DOMAINE_PRODUIT_APRES", "domaine apres"); + map.put("LIGNE_PRODUIT_AVANT", "ligne produit avant"); + map.put("LIGNE_PRODUIT_APRES", "ligne produit apres"); + map.put("MATRICULE_MOTEUR", "03435841351"); + return map; + } +} diff --git a/jasper/src/test/java/com/capgemini/reports/jasper/printers/JasperPDFPrinterTest.java b/jasper/src/test/java/com/capgemini/reports/jasper/printers/JasperPDFPrinterTest.java new file mode 100644 index 0000000..b1bf7dd --- /dev/null +++ b/jasper/src/test/java/com/capgemini/reports/jasper/printers/JasperPDFPrinterTest.java @@ -0,0 +1,46 @@ +package com.capgemini.reports.jasper.printers; + +import com.capgemini.reports.jasper.compilers.JasperCompiler; +import com.capgemini.reports.jasper.fillers.JasperFiller; +import com.capgemini.reports.jasper.fillers.MonoFiller; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperPrint; +import net.sf.jasperreports.engine.JasperReport; +import org.testng.annotations.Test; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + + +public class JasperPDFPrinterTest { + + private static final String JASPER_TEMPLATE = "/Jasper/template/report_r20/page2/r20_p2_generics.jrxml"; + + @Test + public void testMulti() throws JRException { + InputStream templateStream = getClass().getResourceAsStream(JASPER_TEMPLATE); + JasperReport reportTemplate = JasperCompiler.compile(templateStream); + + // Fill with some data + JasperFiller filler = new MonoFiller(reportTemplate, setupPage2GenericData(10), new HashMap()); + JasperPrint print = filler.generate(); + assertThat(print.getPages()).isNotEmpty(); + } + + private List> setupPage2GenericData(final int numberOfElements) { + List> lmrMaps = new ArrayList<>(); + for (int num = 0; num < numberOfElements; num++) { + Map lmrMap = new HashMap<>(); + lmrMap.put("GENERIC_AVEC_RUPTURE", "Generic-" + num); + lmrMap.put("ID_PART_AVANT", "Part-Avant-" + num); + lmrMap.put("ID_PART_APREs", "Part-Après-" + num); + lmrMaps.add(lmrMap); + } + return lmrMaps; + } +} diff --git a/jasper/src/test/resources/Jasper/images/Snecma_logo.png b/jasper/src/test/resources/Jasper/images/Snecma_logo.png new file mode 100644 index 0000000..e40717b Binary files /dev/null and b/jasper/src/test/resources/Jasper/images/Snecma_logo.png differ diff --git a/jasper/src/test/resources/Jasper/images/confidentiel_industrie.jpg b/jasper/src/test/resources/Jasper/images/confidentiel_industrie.jpg new file mode 100644 index 0000000..3008bff Binary files /dev/null and b/jasper/src/test/resources/Jasper/images/confidentiel_industrie.jpg differ diff --git a/jasper/src/test/resources/Jasper/template/dynamic_table/reference.jrxml b/jasper/src/test/resources/Jasper/template/dynamic_table/reference.jrxml new file mode 100644 index 0000000..8ba8eb0 --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/dynamic_table/reference.jrxml @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jasper/src/test/resources/Jasper/template/dynamic_table/template.jrxml b/jasper/src/test/resources/Jasper/template/dynamic_table/template.jrxml new file mode 100644 index 0000000..509c616 --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/dynamic_table/template.jrxml @@ -0,0 +1,23 @@ + + + [[PARAMETERS]] + + + [[FIELDS]] + + + + + [[HEADERS]] + + + + [[CONTENT]] + + + diff --git a/jasper/src/test/resources/Jasper/template/report_r01.jrxml b/jasper/src/test/resources/Jasper/template/report_r01.jrxml new file mode 100644 index 0000000..96cb852 --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/report_r01.jrxml @@ -0,0 +1,749 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jasper/src/test/resources/Jasper/template/report_r03.jrxml b/jasper/src/test/resources/Jasper/template/report_r03.jrxml new file mode 100644 index 0000000..ea0509c --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/report_r03.jrxml @@ -0,0 +1,750 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jasper/src/test/resources/Jasper/template/report_r10.jrxml b/jasper/src/test/resources/Jasper/template/report_r10.jrxml new file mode 100644 index 0000000..bb0d0f2 --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/report_r10.jrxml @@ -0,0 +1,975 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jasper/src/test/resources/Jasper/template/report_r11.jrxml b/jasper/src/test/resources/Jasper/template/report_r11.jrxml new file mode 100644 index 0000000..2b3390a --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/report_r11.jrxml @@ -0,0 +1,687 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band height="160" splitType="Stretch"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <staticText> + <reportElement x="-20" y="100" width="320" height="20" uuid="33d7e186-0b67-416e-8a86-26655b01cf0c"/> + <textElement> + <font size="8"/> + </textElement> + <text><![CDATA[Nombre de repères fonctionnels avec mise en maquette cohérente]]></text> + </staticText> + <staticText> + <reportElement x="-20" y="20" width="320" height="20" uuid="b554ec37-e2af-4344-a385-263bd5dffdab"/> + <textElement> + <font size="8"/> + </textElement> + <text><![CDATA[Nombre de repères fonctionnels mis en maquette :]]></text> + </staticText> + <staticText> + <reportElement x="-20" y="40" width="320" height="20" uuid="4628b4ee-acce-490a-a3cc-5ff1289d5db0"/> + <textElement> + <font size="8"/> + </textElement> + <text><![CDATA[Pourcentage de mise en maquette :]]></text> + </staticText> + <staticText> + <reportElement x="-20" y="60" width="320" height="20" uuid="d2763629-2316-46e2-8d08-bc2f012aa4be"/> + <textElement> + <font size="8"/> + </textElement> + <text><![CDATA[Nombre de repères fonctionnels avec une incohérence de mise en maquette :]]></text> + </staticText> + <staticText> + <reportElement x="-20" y="80" width="320" height="20" uuid="594ca80b-2686-45e1-a831-1d32b7d0e891"/> + <textElement> + <font size="8"/> + </textElement> + <text><![CDATA[Pourcentage de repères fonctionnels mis en maquette incohérente]]></text> + </staticText> + <textField> + <reportElement x="300" y="0" width="80" height="20" uuid="1ad40902-0de9-428b-aa8a-7a6f21d3c998"/> + <textFieldExpression><![CDATA[$P{NOMBRE_REPERE_FONCTIONNEL_METTRE_EN_MAQUETTE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="300" y="20" width="80" height="20" uuid="dd6c4654-9f34-4bdd-84df-55ef28c91c67"/> + <textFieldExpression><![CDATA[$P{NOMBRE_REPERE_FONCTIONNEL_MAQUETTE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="300" y="40" width="80" height="20" uuid="6fb1523c-9e69-45aa-b61d-5a8ae9b6ef19"/> + <textFieldExpression><![CDATA[$P{MISE_EN_MAQUETTE_POURCENTAGE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="300" y="60" width="80" height="20" uuid="a90d110c-893d-4f00-83d6-0ad6a7454926"/> + <textFieldExpression><![CDATA[$P{NOMBRE_REPERE_FONCTIONNEL_INCOHERENT}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="300" y="80" width="80" height="20" uuid="f8c79aed-4af3-44d3-bc43-a4ac7fb08f4d"/> + <textFieldExpression> + <![CDATA[$P{REPERE_FONCTIONNEL_MAQUETTE_INCOHERENTE_POURCENTAGE}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="-20" y="0" width="320" height="20" uuid="686e3570-9ad2-4202-8d37-a7e6f8cdb515"/> + <textElement> + <font size="8"/> + </textElement> + <text><![CDATA[Nombre de repères fonctionnels à mettre en maquette]]></text> + </staticText> + <staticText> + <reportElement x="-20" y="120" width="320" height="20" uuid="87021f19-7594-4bdd-a6ff-8ea485226e51"/> + <textElement> + <font size="8"/> + </textElement> + <text><![CDATA[Pourcentage de repères fonctionnels mis en maquette cohérente]]></text> + </staticText> + <textField> + <reportElement x="300" y="120" width="80" height="20" uuid="08415e62-0b9f-439f-af0f-0ab21019984b"/> + <textFieldExpression><![CDATA[$P{POURCENTAGE_MAQUETTE_COHERENTE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="300" y="100" width="80" height="20" uuid="7a9d71de-3528-41f3-a26d-481290de89c6"/> + <textFieldExpression> + <![CDATA[$P{NOMBRE_REPERE_FONCTIONNEL_MISE_EN_MAQUETTE_COHERENTE}]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jasper/src/test/resources/Jasper/template/report_r15r16.jrxml b/jasper/src/test/resources/Jasper/template/report_r15r16.jrxml new file mode 100644 index 0000000..c98dd91 --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/report_r15r16.jrxml @@ -0,0 +1,686 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1]]> + + + + + + + + + + + + + <band height="800"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <image> + <reportElement x="0" y="0" width="180" height="40" uuid="bd1c5457-daa9-4754-9f61-54f1400686ee"> + <property name="local_mesure_unitwidth" value="pixel"/> + <property name="com.jaspersoft.studio.unit.width" value="px"/> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <imageExpression><![CDATA[$P{SNECMA_LOGO}]]></imageExpression> + </image> + <staticText> + <reportElement x="0" y="560" width="150" height="30" uuid="c8e9f5f7-1896-4aaf-b18a-0c09312016cd"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[MT +MT Number]]></text> + </staticText> + <staticText> + <reportElement x="0" y="590" width="150" height="30" uuid="62981c54-a5b2-48bf-9840-cc4e60859226"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Date de lancement +Release date]]></text> + </staticText> + <staticText> + <reportElement x="180" y="530" width="300" height="20" uuid="7cd156c7-8245-4fad-bac6-3244c82501c8"/> + <textElement> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Définition précédente / Previous Definition]]></text> + </staticText> + <textField> + <reportElement x="150" y="590" width="405" height="30" uuid="2c240f3e-0a02-4bcd-a98c-8c894e9e1d19"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PREVIOUS_RELEASE_DATE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="560" width="405" height="30" uuid="2830e066-9f5f-4682-bc32-64bc41b898fa"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{MT_NUMBER}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="280" width="150" height="30" uuid="d58f0c3a-9c3f-42a0-9a74-c4b13a4bfc9e"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Dénomination Française +French Designation]]></text> + </staticText> + <textField> + <reportElement x="150" y="280" width="405" height="30" uuid="e5081414-e2bf-40bd-bccc-567131df6a5e"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{FRENCH_DESIGNATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="490" width="150" height="30" uuid="c71a994c-a413-4f90-a94a-fcadd4a82a17"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Obturation +Obturation]]></text> + </staticText> + <textField> + <reportElement x="150" y="400" width="405" height="30" uuid="48b02918-dd5b-45ea-bce6-6423778e1596"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{LOG_DOCUMENT}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="160" width="405" height="30" uuid="b8f4eb10-ca2d-498c-94ce-7589f0d24c80"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PRODUCT_TYPE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="190" width="405" height="30" uuid="06a0f02d-35ff-49f5-a0da-43fd541563bb"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PART_NUMBER}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="400" width="150" height="30" uuid="a329c593-2261-491c-8216-3449466dd821"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Document de contrôle +Log Document]]></text> + </staticText> + <staticText> + <reportElement x="0" y="250" width="150" height="30" uuid="c887a61f-5bdf-4759-b01f-ca535f263f7c"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Version de l’article +Part version]]></text> + </staticText> + <staticText> + <reportElement x="0" y="160" width="150" height="30" uuid="0b2fbdcf-2b30-4936-b89a-b237bc00858a"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Type produit +Product Type]]></text> + </staticText> + <textField> + <reportElement x="150" y="490" width="405" height="30" uuid="f9019024-1120-45c1-a3fa-a4f6b6c00eab"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{OBTURATION}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="220" width="405" height="30" uuid="04f2420a-7fd1-42b0-8da2-422f0b2a99c5"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{MANUFACTURER_CODE}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="370" width="150" height="30" uuid="a3f18762-a923-47c2-9dab-0bb02dea7ec5"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Suivi Utilisation +Field OPN serialisation]]></text> + </staticText> + <textField> + <reportElement x="150" y="370" width="405" height="30" uuid="0f42ed3c-21a3-48ab-bab2-7e61699bdc78"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{FIELD_OPN_SERIALISATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="340" width="150" height="30" uuid="e74a400e-5b28-4206-9538-0e5322e395be"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Classement +Classification]]></text> + </staticText> + <textField> + <reportElement x="150" y="340" width="405" height="30" uuid="5531e836-80a9-4bb9-8216-98637993b852"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{CLASSIFICATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="190" width="150" height="30" uuid="a760d63d-8652-4c30-a0fc-80032474925f"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Référence de l’article +Part Number]]></text> + </staticText> + <textField> + <reportElement x="150" y="250" width="405" height="30" uuid="7acd17db-c975-482b-b33a-5a50cd7e495e"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PART_VERSION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="220" width="150" height="30" uuid="56254219-d62f-4d1f-b7e2-e7ba6b55db05"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Code Fabricant +Manufacturer code]]></text> + </staticText> + <textField> + <reportElement x="60" y="80" width="120" height="20" uuid="16a34db8-b544-4ed7-aa30-723bbd0f2c97"> + <property name="local_mesure_unity" value="pixel"/> + <property name="com.jaspersoft.studio.unit.y" value="px"/> + </reportElement> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{ITEM_ID}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="200" y="120" width="290" height="20" uuid="5cd5ea2e-370d-4843-86ec-284dd5cc4669"/> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{RELEASE_DATE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="200" y="80" width="290" height="20" uuid="90631035-798d-4f4d-800a-1ae0da7199ce"/> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{ITEM_REVISION_ID}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="60" y="120" width="120" height="20" uuid="ae3b956d-b485-4801-81d9-dc75765b5f27"/> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PRODUCT_UNIT}]]></textFieldExpression> + </textField> + <textField isStretchWithOverflow="true"> + <reportElement stretchType="RelativeToTallestObject" x="30" y="681" width="490" height="119" + uuid="0953ec0c-dd4c-4d2b-bfdf-bc17f90863e7"/> + <textElement textAlignment="Center" markup="styled"> + <font size="7" isBold="false" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{CLAUSE_PROPRIETE}]]></textFieldExpression> + </textField> + <line> + <reportElement x="0" y="680" width="555" height="1" uuid="c8a04261-d21b-476f-a9c8-3513667543fe"> + <property name="local_mesure_unity" value="pixel"/> + <property name="com.jaspersoft.studio.unit.y" value="px"/> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + </line> + <textField> + <reportElement x="520" y="780" width="34" height="20" uuid="f3f0d26b-5d68-4356-88f2-fc0b8d32b880"/> + <textElement textAlignment="Right"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <textFieldExpression><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="310" width="405" height="30" uuid="1e3b2e3b-8658-4332-8baa-1492978ab190"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{ENGLISH_DESIGNATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="310" width="150" height="30" uuid="1026facf-47bb-4163-939d-a87d49e93d9e"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Dénomination Anglaise +English designation]]></text> + </staticText> + <staticText> + <reportElement x="0" y="430" width="150" height="30" uuid="58157510-6554-420b-b0eb-97ade29844ae"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Frontière Avion +Installation Interface]]></text> + </staticText> + <textField> + <reportElement x="150" y="460" width="405" height="30" uuid="a12899e5-d6f2-42f0-9de5-5acdc64ed2a2"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PARTNER_INTERFACE}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="460" width="150" height="30" uuid="5a2f3dcd-1fbd-4e8f-b46f-577c64544d37"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Frontière Coopérant +Partner Interface]]></text> + </staticText> + <textField> + <reportElement x="150" y="430" width="405" height="30" uuid="ab848d3a-8005-4763-8583-384bb8c70cfc"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{INSTALLATION_INTERFACE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="80" y="40" width="380" height="30" uuid="3f7c9d3f-0877-4237-a0c2-5b2c3e0e561c"/> + <textElement textAlignment="Center" verticalAlignment="Middle" markup="styled"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <textFieldExpression><![CDATA[$P{REPORT_TITLE}]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jasper/src/test/resources/Jasper/template/report_r17.jrxml b/jasper/src/test/resources/Jasper/template/report_r17.jrxml new file mode 100644 index 0000000..ec33a10 --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/report_r17.jrxml @@ -0,0 +1,621 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1]]> + + + + + + + + + + + + + <band height="800"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <image> + <reportElement x="0" y="0" width="180" height="40" uuid="bd1c5457-daa9-4754-9f61-54f1400686ee"> + <property name="local_mesure_unitwidth" value="pixel"/> + <property name="com.jaspersoft.studio.unit.width" value="px"/> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <imageExpression><![CDATA[$P{SNECMA_LOGO}]]></imageExpression> + </image> + <staticText> + <reportElement x="0" y="560" width="150" height="30" uuid="c8e9f5f7-1896-4aaf-b18a-0c09312016cd"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[MT +MT Number]]></text> + </staticText> + <staticText> + <reportElement x="0" y="590" width="150" height="30" uuid="62981c54-a5b2-48bf-9840-cc4e60859226"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Date de lancement +Release date]]></text> + </staticText> + <staticText> + <reportElement x="180" y="530" width="300" height="20" uuid="7cd156c7-8245-4fad-bac6-3244c82501c8"/> + <textElement> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Définition précédente / Previous Definition]]></text> + </staticText> + <textField> + <reportElement x="150" y="590" width="405" height="30" uuid="2c240f3e-0a02-4bcd-a98c-8c894e9e1d19"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PREVIOUS_RELEASE_DATE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="560" width="405" height="30" uuid="2830e066-9f5f-4682-bc32-64bc41b898fa"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{MT_NUMBER}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="280" width="150" height="30" uuid="d58f0c3a-9c3f-42a0-9a74-c4b13a4bfc9e"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Dénomination Française +French Designation]]></text> + </staticText> + <textField> + <reportElement x="150" y="280" width="405" height="30" uuid="e5081414-e2bf-40bd-bccc-567131df6a5e"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{FRENCH_DESIGNATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="430" width="150" height="30" uuid="c71a994c-a413-4f90-a94a-fcadd4a82a17"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Obturation +Obturation]]></text> + </staticText> + <textField> + <reportElement x="150" y="400" width="405" height="30" uuid="48b02918-dd5b-45ea-bce6-6423778e1596"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{LOG_DOCUMENT}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="160" width="405" height="30" uuid="b8f4eb10-ca2d-498c-94ce-7589f0d24c80"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PRODUCT_TYPE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="190" width="405" height="30" uuid="06a0f02d-35ff-49f5-a0da-43fd541563bb"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PART_NUMBER}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="400" width="150" height="30" uuid="a329c593-2261-491c-8216-3449466dd821"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Document de contrôle +Log Document]]></text> + </staticText> + <staticText> + <reportElement x="0" y="250" width="150" height="30" uuid="c887a61f-5bdf-4759-b01f-ca535f263f7c"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Version de l’article +Part version]]></text> + </staticText> + <staticText> + <reportElement x="0" y="160" width="150" height="30" uuid="0b2fbdcf-2b30-4936-b89a-b237bc00858a"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Type produit +Product Type]]></text> + </staticText> + <textField> + <reportElement x="150" y="430" width="405" height="30" uuid="f9019024-1120-45c1-a3fa-a4f6b6c00eab"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{OBTURATION}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="220" width="405" height="30" uuid="04f2420a-7fd1-42b0-8da2-422f0b2a99c5"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{MANUFACTURER_CODE}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="370" width="150" height="30" uuid="a3f18762-a923-47c2-9dab-0bb02dea7ec5"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Suivi Utilisation +Field OPN serialisation]]></text> + </staticText> + <textField> + <reportElement x="150" y="370" width="405" height="30" uuid="0f42ed3c-21a3-48ab-bab2-7e61699bdc78"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{FIELD_OPN_SERIALISATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="340" width="150" height="30" uuid="e74a400e-5b28-4206-9538-0e5322e395be"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Classement +Classification]]></text> + </staticText> + <textField> + <reportElement x="150" y="340" width="405" height="30" uuid="5531e836-80a9-4bb9-8216-98637993b852"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{CLASSIFICATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="190" width="150" height="30" uuid="a760d63d-8652-4c30-a0fc-80032474925f"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Référence de l’article +Part Number]]></text> + </staticText> + <textField> + <reportElement x="150" y="250" width="405" height="30" uuid="7acd17db-c975-482b-b33a-5a50cd7e495e"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PART_VERSION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="220" width="150" height="30" uuid="56254219-d62f-4d1f-b7e2-e7ba6b55db05"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Code Fabricant +Manufacturer code]]></text> + </staticText> + <textField> + <reportElement x="60" y="80" width="120" height="20" uuid="16a34db8-b544-4ed7-aa30-723bbd0f2c97"> + <property name="local_mesure_unity" value="pixel"/> + <property name="com.jaspersoft.studio.unit.y" value="px"/> + </reportElement> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{ITEM_ID}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="200" y="120" width="290" height="20" uuid="5cd5ea2e-370d-4843-86ec-284dd5cc4669"/> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{RELEASE_DATE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="200" y="80" width="290" height="20" uuid="90631035-798d-4f4d-800a-1ae0da7199ce"/> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{ITEM_REVISION_ID}]]></textFieldExpression> + </textField> + <textField isStretchWithOverflow="true"> + <reportElement stretchType="RelativeToTallestObject" x="30" y="680" width="490" height="120" + uuid="0953ec0c-dd4c-4d2b-bfdf-bc17f90863e7"/> + <textElement textAlignment="Center" markup="styled"> + <font size="7" isBold="false" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{CLAUSE_PROPRIETE}]]></textFieldExpression> + </textField> + <line> + <reportElement x="0" y="680" width="555" height="1" uuid="c8a04261-d21b-476f-a9c8-3513667543fe"> + <property name="local_mesure_unity" value="pixel"/> + <property name="com.jaspersoft.studio.unit.y" value="px"/> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + </line> + <textField> + <reportElement x="520" y="780" width="34" height="20" uuid="f3f0d26b-5d68-4356-88f2-fc0b8d32b880"/> + <textElement textAlignment="Right"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <textFieldExpression><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="310" width="150" height="30" uuid="7807ccdf-9479-42d0-8a5c-a41805923c37"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Dénomination Anglaise +English designation]]></text> + </staticText> + <textField> + <reportElement x="150" y="310" width="405" height="30" uuid="fdd0ad29-2a8c-4c0a-88f8-da8648ca3f5d"/> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{ENGLISH_DESIGNATION}]]></textFieldExpression> + </textField> + <rectangle> + <reportElement x="60" y="120" width="120" height="20" uuid="fe8029bb-5c43-450a-bb89-70908609e531"/> + </rectangle> + <textField> + <reportElement x="80" y="40" width="380" height="30" uuid="13308d92-200e-48eb-8dcf-77e6f9f271b9"/> + <textElement textAlignment="Center" verticalAlignment="Middle" markup="styled"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <textFieldExpression><![CDATA[$P{REPORT_TITLE}]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jasper/src/test/resources/Jasper/template/report_r19.jrxml b/jasper/src/test/resources/Jasper/template/report_r19.jrxml new file mode 100644 index 0000000..0843752 --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/report_r19.jrxml @@ -0,0 +1,518 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jasper/src/test/resources/Jasper/template/report_r20/page2/r20_p2_generics.jrxml b/jasper/src/test/resources/Jasper/template/report_r20/page2/r20_p2_generics.jrxml new file mode 100644 index 0000000..0bc1aba --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/report_r20/page2/r20_p2_generics.jrxml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jasper/src/test/resources/Jasper/template/report_r20/page2/r20_p2_impacts.jrxml b/jasper/src/test/resources/Jasper/template/report_r20/page2/r20_p2_impacts.jrxml new file mode 100644 index 0000000..f74f250 --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/report_r20/page2/r20_p2_impacts.jrxml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jasper/src/test/resources/Jasper/template/report_r20/page2/r20_p2_noimpacts.jrxml b/jasper/src/test/resources/Jasper/template/report_r20/page2/r20_p2_noimpacts.jrxml new file mode 100644 index 0000000..0f1d05d --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/report_r20/page2/r20_p2_noimpacts.jrxml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jasper/src/test/resources/Jasper/template/report_r20/page3/page3reference.jrxml b/jasper/src/test/resources/Jasper/template/report_r20/page3/page3reference.jrxml new file mode 100644 index 0000000..2aabc7c --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/report_r20/page3/page3reference.jrxml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + >)$P{CROSS_TABLE}.get("DATA_SUBREPORT0"))]]> + + + + + + >)$P{CROSS_TABLE}.get("DATA_SUBREPORT1"))]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jasper/src/test/resources/Jasper/template/report_r20/page3/report_r20_p3.jrxml b/jasper/src/test/resources/Jasper/template/report_r20/page3/report_r20_p3.jrxml new file mode 100644 index 0000000..0c8e5ec --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/report_r20/page3/report_r20_p3.jrxml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [[SUBTABLES]] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jasper/src/test/resources/Jasper/template/report_r20/report_r20_master.jrxml b/jasper/src/test/resources/Jasper/template/report_r20/report_r20_master.jrxml new file mode 100644 index 0000000..9938dcc --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/report_r20/report_r20_master.jrxml @@ -0,0 +1,300 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + >)$P{SUBREPORT_P2}.get("DATA"))]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + >)$P{SUBREPORT_P1}.get("DATA"))]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + >)$P{SUBREPORT_P3}.get("DATA"))]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + >)$P{SUBREPORT_P4}.get("DATA"))]]> + + + + + + + + + + + + + Ce document est la propriété de Safran Aircraft Engines. Il ne peut être utilisé, reproduit ou communiqué sans son autorisation.
F0301"]]>
+
+
+
+ + + + + + + + + +
diff --git a/jasper/src/test/resources/Jasper/template/report_r20/report_r20_p1.jrxml b/jasper/src/test/resources/Jasper/template/report_r20/report_r20_p1.jrxml new file mode 100644 index 0000000..d9891ed --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/report_r20/report_r20_p1.jrxml @@ -0,0 +1,267 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jasper/src/test/resources/Jasper/template/report_r20/report_r20_p2.jrxml b/jasper/src/test/resources/Jasper/template/report_r20/report_r20_p2.jrxml new file mode 100644 index 0000000..81fcd01 --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/report_r20/report_r20_p2.jrxml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + >)$P{SUBREPORT_GENERIC}.get("DATA"))]]> + + + + + + + + + + + + + + + + + + + + + >)$P{SUBREPORT_IMPACTS}.get("DATA"))]]> + + + + + + + + + + + + + + >)$P{SUBREPORT_NOIMPACTS}.get("DATA"))]]> + + + + + + + + + + + + diff --git a/jasper/src/test/resources/Jasper/template/report_r20/report_r20_p4.jrxml b/jasper/src/test/resources/Jasper/template/report_r20/report_r20_p4.jrxml new file mode 100644 index 0000000..d38b7ca --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/report_r20/report_r20_p4.jrxml @@ -0,0 +1,279 @@ + + + + + + + + + + + + + + + + + + + + + + + + <band height="103" splitType="Stretch"> + <staticText> + <reportElement x="0" y="0" width="800" height="30" uuid="92028f51-246a-47f2-8c73-95be69612b49"/> + <textElement textAlignment="Center"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[DOCUMENT DE GEL DE UNIT FINAL (ANNEXE) +CALCUL DES REFERENCES TECHNIQUES]]></text> + </staticText> + <staticText> + <reportElement x="0" y="30" width="800" height="20" uuid="75b69c65-ad19-482b-905e-786a7605cd9a"/> + <text> + <![CDATA[L'impact de chaque modification sur les références des assemblages est décrit dans le tableau suivant : ]]></text> + </staticText> + <textField> + <reportElement x="0" y="50" width="800" height="20" uuid="510054a1-5695-4b3c-954e-fc5b312835aa"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textFieldExpression> + <![CDATA["Avant : UNIT " + $P{UNIT_AVANT} + " " + $P{EXCEPTIONNEL_AVANT} + " du produit " + $P{DOMAINE_PRODUIT_AVANT} + " " + $P{LIGNE_PRODUIT_AVANT}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="0" y="70" width="800" height="20" uuid="b9a32778-73b0-4b97-9616-c06f6f4f2c92"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textFieldExpression> + <![CDATA["Après : UNIT " + $P{UNIT_APRES} + " " + $P{EXCEPTIONNEL_APRES} + " du produit " + $P{DOMAINE_PRODUIT_APRES} + " " + $P{LIGNE_PRODUIT_APRES}]]></textFieldExpression> + </textField> + <textField> + <reportElement mode="Opaque" x="0" y="90" width="290" height="13" backcolor="#E3E3E3" + uuid="c4e431d0-0c8a-4266-9c73-97958c24f127"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <box leftPadding="5"> + <topPen lineWidth="0.5"/> + <leftPen lineWidth="0.5"/> + <bottomPen lineWidth="0.5"/> + <rightPen lineWidth="0.5"/> + </box> + <textFieldExpression><![CDATA[$P{LIGNE_PRODUIT_APRES}]]></textFieldExpression> + </textField> + <rectangle> + <reportElement x="290" y="90" width="130" height="13" backcolor="#E3E3E3" + uuid="c0013ff2-080b-4606-869c-e4105272fdbc"/> + <graphicElement> + <pen lineWidth="0.5"/> + </graphicElement> + </rectangle> + <staticText> + <reportElement mode="Opaque" x="420" y="90" width="190" height="13" backcolor="#E3E3E3" + uuid="e43f8acf-e867-4e00-8108-c15fd3ebc4d2"/> + <box> + <topPen lineWidth="0.5"/> + <leftPen lineWidth="0.5"/> + <bottomPen lineWidth="0.5"/> + <rightPen lineWidth="0.5"/> + </box> + <textElement textAlignment="Center"/> + <text><![CDATA[Ancienne référence]]></text> + </staticText> + <staticText> + <reportElement mode="Opaque" x="610" y="90" width="190" height="13" backcolor="#E3E3E3" + uuid="dcdf2e41-3751-4d1c-9950-7bb9b71f7042"/> + <box> + <topPen lineWidth="0.5"/> + <leftPen lineWidth="0.5"/> + <bottomPen lineWidth="0.5"/> + <rightPen lineWidth="0.5"/> + </box> + <textElement textAlignment="Center"/> + <text><![CDATA[Nouvelle référence]]></text> + </staticText> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jasper/src/test/resources/Jasper/template/report_r21.jrxml b/jasper/src/test/resources/Jasper/template/report_r21.jrxml new file mode 100644 index 0000000..7bc9c14 --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/report_r21.jrxml @@ -0,0 +1,876 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jasper/src/test/resources/Jasper/template/report_r22.jrxml b/jasper/src/test/resources/Jasper/template/report_r22.jrxml new file mode 100644 index 0000000..6759368 --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/report_r22.jrxml @@ -0,0 +1,897 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band height="181"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <image> + <reportElement x="0" y="0" width="802" height="30" uuid="02f283fc-725c-4091-a6df-64b3fe139563"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <imageExpression><![CDATA[$P{LOGO_SNECMA}]]></imageExpression> + </image> + <staticText> + <reportElement stretchType="RelativeToTallestObject" x="0" y="20" width="802" height="40" + uuid="6f86d0ba-b648-4c52-b7dd-f6882be41c2e"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Center"> + <font fontName="SansSerif" size="24" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Extraction de nomenclatures sur effectivité par DATE]]></text> + </staticText> + <staticText> + <reportElement x="0" y="60" width="802" height="20" uuid="3ee15cb1-b6f7-4e0a-8ce4-55531cc1cd0c"/> + <textElement textAlignment="Center"> + <font fontName="SansSerif" size="14" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Bills of material using date effectivity]]></text> + </staticText> + <staticText> + <reportElement x="0" y="80" width="30" height="20" uuid="8213394e-7143-4f85-8259-f11a9e9f6da1"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Date :]]></text> + </staticText> + <staticText> + <reportElement x="0" y="100" width="90" height="20" uuid="16268bcd-1f46-436a-8985-139d61ae36ca"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Date d'effectivité :]]></text> + </staticText> + <staticText> + <reportElement x="0" y="120" width="90" height="20" uuid="ed387d70-8182-4a54-ad00-903b07d1cf5e"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Référence article :]]></text> + </staticText> + <staticText> + <reportElement x="0" y="140" width="40" height="20" uuid="adc6bff6-2abe-41b5-8ed9-296c4ec7649b"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Niveau :]]></text> + </staticText> + <staticText> + <reportElement x="0" y="160" width="50" height="20" uuid="223b27bf-23e1-4c1d-bf84-b487debd8fb2"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Résultat :]]></text> + </staticText> + <textField evaluationTime="Report"> + <reportElement x="30" y="80" width="772" height="20" uuid="2b6b80bd-3694-4680-9b89-8d80a4369f7c"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{DATE_TRAITEMENT}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report"> + <reportElement x="90" y="100" width="712" height="20" uuid="d5cc6967-759a-4822-908b-a0dee6741a2c"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{DATE_EFFECTIVITE}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report"> + <reportElement x="90" y="120" width="712" height="20" uuid="d2f8d509-7634-472c-a313-aecb48ed601a"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{REFERENCE_ARTICLE}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report"> + <reportElement x="40" y="140" width="762" height="20" uuid="2f49bcdb-558b-45f0-810c-8f20fd157827"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[" " + $P{NIVEAU}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="50" y="160" width="752" height="20" uuid="abcf5995-dfdf-44f2-820a-ecc79f1bf320"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" pdfFontName="Helvetica"/> + </textElement> + <text><![CDATA[pdf]]></text> + </staticText> + <break> + <reportElement x="0" y="180" width="96" height="1" uuid="76003345-b03a-4011-b34c-9c3d6a49d511"/> + </break> + </band> + + + + + + 1]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jasper/src/test/resources/Jasper/template/template_R07.jrxml b/jasper/src/test/resources/Jasper/template/template_R07.jrxml new file mode 100644 index 0000000..e7ded6e --- /dev/null +++ b/jasper/src/test/resources/Jasper/template/template_R07.jrxml @@ -0,0 +1,24 @@ + + + [[PROPERTY]][[STYLE]][[PARAMETERS]][[FIELDS]] + + + + + <band height="[[TITLE_HEIGHT]]" splitType="Stretch">[[TITLE]] + </band> + + + [[HEADERS]] + + + + [[CONTENT]] + + + \ No newline at end of file diff --git a/jasper/src/test/resources/log4j.properties b/jasper/src/test/resources/log4j.properties new file mode 100644 index 0000000..8f372cd --- /dev/null +++ b/jasper/src/test/resources/log4j.properties @@ -0,0 +1,13 @@ +log4j.logger.com.teamcenter.soa=WARN +log4j.logger.org.apache=WARN +log4j.logger.httpclient=WARN + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.threshold=DEBUG +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %c{1}:%L - %m%n + +# Root logger option +log4j.rootLogger=DEBUG, stdout diff --git a/jasper/src/test/resources/logging.properties b/jasper/src/test/resources/logging.properties new file mode 100644 index 0000000..1983b8d --- /dev/null +++ b/jasper/src/test/resources/logging.properties @@ -0,0 +1,3 @@ +handlers=java.util.logging.ConsoleHandler +java.util.logging.ConsoleHandler.level=FINEST +com.capgemini.level=FINEST diff --git a/jasper/src/test/resources/simplelogger.properties b/jasper/src/test/resources/simplelogger.properties new file mode 100644 index 0000000..e69de29 diff --git a/kurt-ejb/pom.xml b/kurt-ejb/pom.xml new file mode 100644 index 0000000..69f4b5d --- /dev/null +++ b/kurt-ejb/pom.xml @@ -0,0 +1,240 @@ + + + 4.0.0 + kurt-ejb + ejb + kurt-ejb + + + com.capgemini.reports + kurt + 1.32.9 + + + + + + + + + + com.capgemini.reports + kurt-utility + 1.32.9 + + + + + + + + junit + junit + test + + + + org.mockito + mockito-core + test + + + + org.assertj + assertj-core + test + + + + org.slf4j + slf4j-api + + + + org.projectlombok + lombok + + + + org.json + json + + + + org.jboss.spec.javax.annotation + jboss-annotations-api_1.1_spec + + + + + + + + + + + + org.jboss.as + jboss-as-ejb3 + + + + + + org.hornetq + hornetq-core + provided + + + org.hornetq + hornetq-jms + provided + + + org.hornetq + hornetq-logging + 2.2.13.Final + provided + + + + + org.hornetq + hornetq-core-client + provided + + + org.hornetq + hornetq-jms-client + provided + + + + + org.jboss.spec.javax.jms + jboss-jms-api_1.1_spec + + + + + org.hibernate + hibernate-entitymanager + + provided + + + org.hibernate + hibernate-validator + provided + + + org.hibernate + hibernate-core + provided + + + + + mysql + mysql-connector-java + 5.1.15 + + + + + org.jboss.as + jboss-as-jpa + provided + + + + + org.jboss.arquillian.junit + arquillian-junit-container + test + + + org.jboss.arquillian.protocol + arquillian-protocol-servlet + test + + + org.jboss.weld + weld-core-test-arquillian + 1.1.9.Final + + + + org.jboss.as + jboss-as-controller-client + test + + + + joda-time + joda-time + 2.5 + + + + + org.quartz-scheduler + quartz + 2.1.7 + + + org.quartz-scheduler + quartz-jboss + 2.1.7 + + + com.capgemini.reports + teamcenter + 1.32.9 + + + net.lingala.zip4j + zip4j + 1.3.2 + + + com.capgemini.reports + jasper + 1.32.9 + + + + + + + + org.apache.maven.plugins + maven-ejb-plugin + + 3.1 + + + + + + + + + diff --git a/kurt-ejb/src/main/java/com/capgemini/reports/execution/posting/DelayedPostingStategy.java b/kurt-ejb/src/main/java/com/capgemini/reports/execution/posting/DelayedPostingStategy.java new file mode 100644 index 0000000..f42d488 --- /dev/null +++ b/kurt-ejb/src/main/java/com/capgemini/reports/execution/posting/DelayedPostingStategy.java @@ -0,0 +1,56 @@ +package com.capgemini.reports.execution.posting; + +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.quartz.SchedulerServer; +import com.capgemini.reports.quartz.TriggerPreparator; +import com.capgemini.reports.quartz.jobs.DelayedJob; +import lombok.AllArgsConstructor; +import org.quartz.*; + +import java.util.HashMap; +import java.util.Map; + +/** This strategy can delay a report execution until a later time in the day, using a combination of Quartz and HornetQ. */ +@AllArgsConstructor +public class DelayedPostingStategy implements IPostingStrategy { + + private final SchedulerServer schedulingServer; + + /** Key linking to an {@link AbstractExecutionReport} in the {@link JobDetail} of a delayed Quartz job. */ + public static final String JOB_DETAIL_KEY_REPORT = "Report"; + + @Override + public void handleRequest(final AbstractExecutionReport report) throws SchedulerException { + // Prepare the Trigger + Trigger trigger = TriggerPreparator.prepareDelayedTrigger(report.getReportTechnicalUid(), report.getPriorityCode()); + + // Prepare the Job + JobDetail job = getDelayedJobDetail(report, trigger); + + // Delay the launch into the queue + try { + schedulingServer.schedule(job, trigger); + } catch (SchedulerException e) { + throw new SchedulerException("Unable to delay the job associated to the report " + report.getReportIdentifier().getReportName() + " " + report.getReportTechnicalUid(), e); + } + } + + /** + * Get the JobDetail for a delayed execution of report. + * + * @param report {@link AbstractExecutionReport} - the implementation of the report + * @param trigger {@link Trigger} - the trigger used for the scheduling + * @return the JobDetail + */ + private JobDetail getDelayedJobDetail(final AbstractExecutionReport report, final Trigger trigger) { + // Initialize the parameter used in the execution of the job + Map paramJob = new HashMap<>(); + paramJob.put(JOB_DETAIL_KEY_REPORT, report); + + // Define the job and tie it to our SimpleJob class + JobKey jobKey = trigger.getJobKey(); + + // The method requestRecovery ask scheduler to re-execute this job + return JobBuilder.newJob(DelayedJob.class).withIdentity(jobKey.getName(), jobKey.getGroup()).requestRecovery().usingJobData(new JobDataMap(paramJob)).build(); + } +} diff --git a/kurt-ejb/src/main/java/com/capgemini/reports/execution/posting/IPostingStrategy.java b/kurt-ejb/src/main/java/com/capgemini/reports/execution/posting/IPostingStrategy.java new file mode 100644 index 0000000..448a4a1 --- /dev/null +++ b/kurt-ejb/src/main/java/com/capgemini/reports/execution/posting/IPostingStrategy.java @@ -0,0 +1,30 @@ +package com.capgemini.reports.execution.posting; + +import javax.jms.JMSException; +import javax.naming.NamingException; + +import org.quartz.SchedulerException; + +import com.capgemini.reports.execution.AbstractExecutionReport; + +/** Strategy interface. Allows several behaviour when receiving a demand. */ +public interface IPostingStrategy { + + /** + * What to do when a request is received to perform a report.
+ * The operation can be any of the following: + *
    + *
  • Post the report immediately into the queue
  • + *
  • Post a delayed job in Quartz, that will hold the report execution until later today, then send it to the queue
  • + *
  • Register a scheduled report to be executed some time in the future.
  • + *
+ * + * @param report the report to perform + * + * @throws SchedulerException if a scheduling operation goes boom + * @throws JMSException if unable to post report in a JMS queue + * @throws NamingException if unable to find the queue in JMS dictionary + */ + void handleRequest(final AbstractExecutionReport report) throws SchedulerException, JMSException, NamingException; + +} diff --git a/kurt-ejb/src/main/java/com/capgemini/reports/execution/posting/ImmediatePostingStrategy.java b/kurt-ejb/src/main/java/com/capgemini/reports/execution/posting/ImmediatePostingStrategy.java new file mode 100644 index 0000000..c4ecf10 --- /dev/null +++ b/kurt-ejb/src/main/java/com/capgemini/reports/execution/posting/ImmediatePostingStrategy.java @@ -0,0 +1,18 @@ +package com.capgemini.reports.execution.posting; + +import javax.jms.JMSException; +import javax.naming.NamingException; + +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.queuing.EmbeddedServer; + +/** This strategy posts the job immediately in the queue for execution. */ +public class ImmediatePostingStrategy implements IPostingStrategy { + + @Override + public void handleRequest(final AbstractExecutionReport report) throws JMSException, NamingException { + // Simply post the report into the queues + EmbeddedServer.produce(report); + } + +} diff --git a/kurt-ejb/src/main/java/com/capgemini/reports/execution/posting/SchedulingPostingStrategy.java b/kurt-ejb/src/main/java/com/capgemini/reports/execution/posting/SchedulingPostingStrategy.java new file mode 100644 index 0000000..1b9527a --- /dev/null +++ b/kurt-ejb/src/main/java/com/capgemini/reports/execution/posting/SchedulingPostingStrategy.java @@ -0,0 +1,46 @@ +package com.capgemini.reports.execution.posting; + +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.quartz.SchedulerServer; +import com.capgemini.reports.quartz.jobs.ScheduledJob; +import lombok.AllArgsConstructor; +import org.quartz.*; + +/** Class representing the strategy to post a scheduling template into Quartz DB. */ +@AllArgsConstructor +public class SchedulingPostingStrategy implements IPostingStrategy { + + private final SchedulerServer schedulingServer; + private final Trigger trigger; + + @Override + public void handleRequest(final AbstractExecutionReport template) throws SchedulerException { + JobDetail job = getScheduledJobDetail(template, trigger.getJobKey()); + + // Push the job to Quartz + try { + schedulingServer.schedule(job, trigger); + } catch (SchedulerException e) { + throw new SchedulerException("Unable to schedule the job associated to the template " + template.getReportIdentifier().getReportName() + " " + template.getReportTechnicalUid(), e); + } + } + + /** + * Return the needed {@link JobDetail} for a delayed execution of report. + * + * @param report {@link AbstractExecutionReport} - the implementation of the report + * @param jobKey {@link JobKey} - the JobKey used for the scheduling + * @return the JobDetail + */ + public static JobDetail getScheduledJobDetail(final AbstractExecutionReport report, final JobKey jobKey) { + // Begin setting up the JobBuilder + JobBuilder jobBuilder = JobBuilder.newJob(ScheduledJob.class).withIdentity(jobKey.getName(), jobKey.getGroup()); + // The method requestRecovery asks the scheduler to re-execute this job + jobBuilder.requestRecovery(); + // Add kurt data + ScheduledJob.prepareData(jobBuilder, report.getSchedulingId(), report.getReportBuilderClassName()); + // Build the job + return jobBuilder.build(); + } + +} diff --git a/kurt-ejb/src/main/java/com/capgemini/reports/quartz/JobDataKeys.java b/kurt-ejb/src/main/java/com/capgemini/reports/quartz/JobDataKeys.java new file mode 100644 index 0000000..2ebb0cb --- /dev/null +++ b/kurt-ejb/src/main/java/com/capgemini/reports/quartz/JobDataKeys.java @@ -0,0 +1,13 @@ +package com.capgemini.reports.quartz; + +import org.quartz.JobDataMap; + +/** A Bunch of keys to put/retrieve report data on quartz {@link JobDataMap} classes. */ +public enum JobDataKeys { + + /** Key to the scheduling's DB Identifier. Only for scheduled reports. */ + SCHEDULING_ID, + /** Key to the class to invoke, which can instantiate the report once it triggers. Only for scheduled reports. */ + REPORT_BUILDER_CLASS_NAME, + +} diff --git a/kurt-ejb/src/main/java/com/capgemini/reports/quartz/SchedulerServer.java b/kurt-ejb/src/main/java/com/capgemini/reports/quartz/SchedulerServer.java new file mode 100644 index 0000000..186eb1f --- /dev/null +++ b/kurt-ejb/src/main/java/com/capgemini/reports/quartz/SchedulerServer.java @@ -0,0 +1,309 @@ +package com.capgemini.reports.quartz; + +import com.capgemini.framework.common.QuartzHelper; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.database.javabean.DbSchedulingReport; +import com.capgemini.reports.database.manager.MngSchedulingReport; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.posting.SchedulingPostingStrategy; +import com.capgemini.reports.periodicity.SchedulingPeriod; +import com.capgemini.reports.quartz.jobs.PurgeJob; +import com.google.common.base.Optional; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Session; +import org.quartz.*; +import org.quartz.impl.StdSchedulerFactory; +import org.quartz.impl.matchers.GroupMatcher; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.ejb.Singleton; +import javax.ejb.Startup; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.Calendar; +import java.util.Map.Entry; + +/** + * Class representing a delayed Scheduler.
+ * This class delayed a job (launching of reports) to a Date parameter. + */ +@Singleton +@Startup +@Slf4j +@Getter +public class SchedulerServer { + + private static final int PLANIF_EXECUTION_SECONDS = 0; + private static final int PLANIF_EXECUTION_MINUTES = 0; + private static final int PLANIF_EXECUTION_HOUR = 6; + + // Internal constants + private static final ReportLaunchTypeEnum SCHEDULED_LAUNCH = ReportLaunchTypeEnum.SCHEDULED; + + // Singleton instance + private Scheduler scheduler; + + /** + * Initialize the Scheduler server. + * + * @throws SchedulerException when unable to initialize the scheduler + */ + @PostConstruct + public void init() throws SchedulerException { + log.info("Initializing Quartz scheduler"); + + // Grab the Scheduler instance from the Factory + try { + // Initialize the Scheduler via the Kurt's quartz.properties file + scheduler = new StdSchedulerFactory(QuartzHelper.getPropertiesFilePath()).getScheduler(); + } + catch (SchedulerException e) { + throw new SchedulerException("Unable to findAll an instance of the default Scheduler", e); + } + + // Start the scheduler + scheduler.start(); + createOrUpdatePurgeJob(); + + // Recalled all the waiting jobs for persistent jobs + try { + scheduler.resumeAll(); + } + catch (SchedulerException e) { + throw new SchedulerException("Unable to start the recover the misfires job and triggers", e); + } + } + + private void createOrUpdatePurgeJob() throws SchedulerException { + log.info("Checking purge job status..."); + JobKey purgeKey = PurgeJob.getPurgeJobKey(); + + // update existing purge job + if (scheduler.checkExists(purgeKey)) { + log.info("Purge job already exists. deleting..."); + try { + scheduler.deleteJob(purgeKey); + log.info("Old Purge job has been deleted"); + } + catch (SchedulerException e) { + String jobName = purgeKey.getName(); + throw new SchedulerException("Unable to delete old " + jobName, e); + } + } + + // Now create purge job from scratch + log.info("Creating purge job"); + JobDetail purgeJobDetail = PurgeJob.getPurgeJobDetail(); + Trigger triggerPurge = PurgeJob.getScheduledTrigger(purgeJobDetail); + try { + scheduler.scheduleJob(purgeJobDetail, triggerPurge); + log.info("Purge job is created, next fire time: {}", triggerPurge.getNextFireTime()); + } + catch (SchedulerException e) { + String jobName = purgeJobDetail.getKey().getName(); + throw new SchedulerException("Unable to create " + jobName, e); + } + } + + /** + * Schedule a Report to a Date parameter. + * + * @param job {@link JobDetail} - the job to execute after the scheduling + * @param trigger {@link Trigger} - the prepared trigger for the scheduled + * @throws SchedulerException when unable to schedule the job + */ + public void schedule(final JobDetail job, final Trigger trigger) throws SchedulerException { + Date startDate = Calendar.getInstance().getTime(); + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); + Date nextStart = trigger.getNextFireTime(); + + log.info("Current time : {}", sdf.format(startDate)); + if (nextStart == null) { + log.info("The rapport will never trigger."); + } + else { + log.info("The rapport should first strigger at {}.", sdf.format(nextStart)); + } + + + // Tell quartz to schedule the job using the trigger + scheduler.scheduleJob(job, trigger); + } + + /** + * De-schedule a specific job and all his triggers. + * + * @param jobName String - the unique name of the job + * @param groupName String - the group name of the job + * @throws SchedulerException when unable to deschedule the job + */ + public void deschedule(final String jobName, final String groupName) throws SchedulerException { + try { + // One report is associated to one job + scheduler.deleteJob(new JobKey(jobName, groupName)); + } + catch (SchedulerException e) { + throw new SchedulerException("The job " + jobName + " " + groupName + " cannot be descheduled.", e); + } + } + + /** + * Destroy the Scheduler server. + * + * @throws SchedulerException when a problem occurs during shutdown + */ + @PreDestroy + public void destroy() throws SchedulerException { + log.info("Destroying Quartz scheduler"); + if (scheduler != null) { + try { + scheduler.shutdown(true); + } + catch (SchedulerException e) { + throw new SchedulerException("Unable to shut down the instance of the default Scheduler", e); + } + } + } + + /** + * Deletes a job and all its triggers. + * + * @param schedulingReportId the ID of the scheduling report (same as DB id) + * @throws SchedulerException if anything goes wrong with Quartz + */ + public void deleteScheduledJobAndKeys(final Long schedulingReportId) throws SchedulerException { + JobKey oldJobKey = TriggerPreparator.getScheduledJobKey(schedulingReportId); + scheduler.deleteJob(oldJobKey); + } + + /** + * Updates the functional and temporal execution data of a job, by modifying its JobDetails and Trigger (in Quartz only, same thing should be done you in the DB). + * + * @param schedulingReportId the id of the scheduling to modify in Quartz + * @param report the new parameters are contained in this {@link AbstractExecutionReport} + * @param priorityCode [1-3] the new report priority + * @param period the new periodicity criteria + * @param planifName the name of the scheduling + * @throws SchedulerException if anything goes wrong with Quartz + */ + public void replaceJob(final Long schedulingReportId, final AbstractExecutionReport report, final int priorityCode, + final SchedulingPeriod period, final String planifName) throws SchedulerException { + JobKey oldJobKey = TriggerPreparator.getScheduledJobKey(schedulingReportId); + + // Clean up all traces of this job + scheduler.deleteJob(oldJobKey); + + // Now re-create it all + Trigger trigger; + try { + trigger = TriggerPreparator.prepareScheduledTrigger(schedulingReportId, priorityCode, planifName, period); + } + catch (InvalidInputException e) { + throw new SchedulerException("Unable to understand the scheduling parameters", e); + } + JobDetail jobDetail = SchedulingPostingStrategy.getScheduledJobDetail(report, trigger.getJobKey()); + scheduler.scheduleJob(jobDetail, trigger); + + } + + /** + * Updates the trigger of a job (in Quartz only, same thing should be done in the DB). + * + * @param schedulingReportId the id of the scheduling to modify in Quartz + * @param planifName the new scheduling name + * @param priorityCode [1-3] the new report priority + * @param period the new periodicity criteria + * @throws SchedulerException if anything goes wrong with Quartz + */ + public void updateTemporalParameters(final Long schedulingReportId, final String planifName, final int priorityCode, + final SchedulingPeriod period) throws SchedulerException { + TriggerKey oldTriggerKey = TriggerPreparator.getScheduledTriggerKey(schedulingReportId); + Trigger newTrigger; + try { + newTrigger = TriggerPreparator.prepareScheduledTrigger(schedulingReportId, priorityCode, planifName, period); + } + catch (InvalidInputException e) { + throw new SchedulerException("Unable to understand the scheduling parameters", e); + } + scheduler.rescheduleJob(oldTriggerKey, newTrigger); + } + + /** + * Returns the next {@link Date} at which the job will be triggered.
+ * If no firing will happen in the future (no triggers left, or all triggers are in the past), returns null. + * + * @param schedulingReportId the id of the scheduling to investigate. + * @return the next firing time. May be null if no trigger fires in the future. + * @throws SchedulerException if anything goes wrong with Quartz + */ + public Optional nextExecutionOfJob(final Long schedulingReportId) throws SchedulerException { + final JobKey jobKey = TriggerPreparator.getScheduledJobKey(schedulingReportId); + List jobKeys = scheduler.getTriggersOfJob(jobKey); + Date nextDate = null; + for (Trigger trigger : jobKeys) { + final Date nextFireTime = trigger.getNextFireTime(); + if (nextDate == null || nextFireTime.before(nextDate)) { + nextDate = nextFireTime; + } + } + return Optional.fromNullable(nextDate); + } + + /** + * Lists all jobs that will be executed tonight. + */ + public List listAllScheduledJobsForTonight(Session session) throws SchedulerException { + GroupMatcher matchSchedulingGroup = GroupMatcher.jobGroupEquals(SCHEDULED_LAUNCH.getGroupName()); + Set jobKeys = scheduler.getJobKeys(matchSchedulingGroup); + + // Prepare a date representing tonight (actually tomorrow at 6am so we findAll all nightly executions) + Calendar calTonight = Calendar.getInstance(); + calTonight.add(Calendar.DAY_OF_MONTH, 1); // Tomorrow before opening hours + calTonight.set(Calendar.HOUR_OF_DAY, PLANIF_EXECUTION_HOUR); + calTonight.set(Calendar.MINUTE, PLANIF_EXECUTION_MINUTES); + calTonight.set(Calendar.SECOND, PLANIF_EXECUTION_SECONDS); + final Date tonight = calTonight.getTime(); + + // Request all jobKeys firing before tonight + Map firingTonight = new HashMap<>(); + for (JobKey jobKey : jobKeys) { + List triggers = scheduler.getTriggersOfJob(jobKey); + for (Trigger trigger : triggers) { + if (trigger.getNextFireTime().before(tonight)) { + firingTonight.put(jobKey, trigger); + break; + } + } + } + + // Obtain additional data + List results = new ArrayList<>(firingTonight.size()); + for (Entry jobFiring : firingTonight.entrySet()) { + JobDetail jobDetail = scheduler.getJobDetail(jobFiring.getKey()); + long schedulingId = jobDetail.getJobDataMap().getLong(JobDataKeys.SCHEDULING_ID.toString()); + DbSchedulingReport reportSchedulingEntry = new MngSchedulingReport().searchById(session, schedulingId); + String reportCode = reportSchedulingEntry.getReportCode(); + ReportEnum reportEnum = ReportEnum.fromCode(reportCode); + final String planifName = jobFiring.getValue().getDescription(); // Scheduling name is stored in its description + JobExecution jobExec = new JobExecution(reportEnum, planifName); + results.add(jobExec); + } + + return results; + } + + /** + * Simple holder to carry a report execution's detail: the {@link ReportEnum}, and the scheduling name. + */ + @Getter + @AllArgsConstructor + public static class JobExecution { + private final ReportEnum reportCode; + private final String planificationName; + } +} diff --git a/kurt-ejb/src/main/java/com/capgemini/reports/quartz/TriggerPreparator.java b/kurt-ejb/src/main/java/com/capgemini/reports/quartz/TriggerPreparator.java new file mode 100644 index 0000000..7fa0215 --- /dev/null +++ b/kurt-ejb/src/main/java/com/capgemini/reports/quartz/TriggerPreparator.java @@ -0,0 +1,378 @@ +package com.capgemini.reports.quartz; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.periodicity.*; +import com.capgemini.reports.periodicity.SchedulingPeriod.PeriodVisitor; +import lombok.extern.slf4j.Slf4j; +import org.quartz.*; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Prepare triggers for the {@link SchedulerServer}. + */ +@Slf4j +public final class TriggerPreparator implements PeriodVisitor { + + // Weekend numbers + private static final int NUM_WEEK_5 = 5; + private static final int NUM_WEEK_4 = 4; + private static final int NUM_WEEK_3 = 3; + private static final int NUM_WEEK_2 = 2; + private static final int NUM_WEEK_1 = 1; + + // PSnecma Priority scale + private static final int SNECMA_LOW_PRIORITY = 1; + private static final int SNECMA_HIGH_PRIORITY = 3; + + // Quartz message priority scale + private static final int QUARTZ_LOW_PRIORITY = 1; + private static final int QUARTZ_MEDIUM_PRIORITY = 5; + private static final int QUARTZ_HIGH_PRIORITY = 10; + + // Others configurations + private static final String PREF_TRIGGER_NAME = "trigger_name_"; + private static final String PREF_JOB_NAME = "job_name_"; + private static final String STR_COLON = ":"; + + // Configuration for delayed launch type. Format: HH:MM + private static final String LAUNCH_HOUR_STR; + private static final int LAUNCH_HOUR; + private static final int LAUNCH_MINUTE; + + static { + LAUNCH_HOUR_STR = SettingsHelper.getDelayedLaunchHour(); + String[] tableStrLaunchTime = LAUNCH_HOUR_STR.split(STR_COLON); + LAUNCH_HOUR = Integer.parseInt(tableStrLaunchTime[0]); + LAUNCH_MINUTE = Integer.parseInt(tableStrLaunchTime[1]); + } + + private final int reportPriority; + private final String strSchedulName; + /** + * The ID of the Scheduling as it appears in the DB. + */ + private final Long schedulingReportId; + + /** + * Private constructor - use static methods to obtain an instance. + * + * @param reportPriority the report priority + * @param strSchedulName + * @param schedulingReportId + */ + private TriggerPreparator(final int reportPriority, final String strSchedulName, final Long schedulingReportId) { + this.reportPriority = reportPriority; + this.strSchedulName = strSchedulName; + this.schedulingReportId = schedulingReportId; + } + + /** + * Prepare a delayed Trigger for the Scheduler. + * + * @param reportUid {@link String} - the report uid + * @param reportPriority [1-3] - the report priority + * @return the trigger + */ + public static Trigger prepareDelayedTrigger(final String reportUid, final int reportPriority) { + // In a mis-fire situation, the SimpleTrigger wants to be fired now by Scheduler + final TriggerKey delayedTriggerKey = getDelayedTriggerKey(reportUid); + final JobKey delayedJobKey = getDelayedJobKey(reportUid); + final SimpleScheduleBuilder tonight = SimpleScheduleBuilder.simpleSchedule().withMisfireHandlingInstructionFireNow(); + final int triggerPriorities = giveTriggerPriorities(reportPriority); + return TriggerBuilder.newTrigger().withIdentity(delayedTriggerKey).startAt(makeDelayedHour(LAUNCH_HOUR_STR)).forJob(delayedJobKey) + .withSchedule(tonight).withPriority(triggerPriorities).build(); + } + + /** + * Prepares a Trigger for a scheduled report. + * + * @param schedulingReportId (Long) the ID of the report (as it appears in DB) + * @param reportPriority [1-3] the priority of the scheduling (1-9) + * @param strScheduleName the name given by the requester + * @param period a {@link SchedulingPeriod} for periodicity + * @return the {@link Trigger} + * @throws InvalidInputException if any input is null + */ + public static Trigger prepareScheduledTrigger(final Long schedulingReportId, final int reportPriority, final String strScheduleName, + final SchedulingPeriod period) throws InvalidInputException { + if (schedulingReportId == null) { + throw new InvalidInputException("Invalid report Id (null)"); + } + if (strScheduleName == null) { + throw new InvalidInputException("Invalid schedulign name (null)"); + } + if (period == null) { + throw new InvalidInputException("Invalid period (null)"); + } + return period.accept(new TriggerPreparator(reportPriority, strScheduleName, schedulingReportId)); + } + + /** + * Prepare a Trigger for a specific date.
+ * + * @param schedulingReportId Long - the report ID + * @param reportPriority [1-3] - the priorities of the report + * @param strSchedulName String - the scheduling name + * @param schedulingDate A string for the scheduling DATE. The format of the date is dd-mm-yyyy. + * @return the built trigger + */ + private static Trigger byDate(final Long schedulingReportId, final int reportPriority, final String strSchedulName, final Date schedulingDate) { + final TriggerKey scheduledTriggerKey = getScheduledTriggerKey(schedulingReportId); + final JobKey scheduledJobKey = getScheduledJobKey(schedulingReportId); + final SimpleScheduleBuilder simpleSchedule = SimpleScheduleBuilder.simpleSchedule().withMisfireHandlingInstructionFireNow(); + final int triggerPriorities = giveTriggerPriorities(reportPriority); + return TriggerBuilder.newTrigger().withIdentity(scheduledTriggerKey).withDescription(strSchedulName).startAt(schedulingDate) + .forJob(scheduledJobKey).withSchedule(simpleSchedule).withPriority(triggerPriorities).build(); + } + + /** + * Prepare a scheduled Trigger for the Scheduler.
+ * + * @param schedulingReportId Long - the report ID + * @param reportPriority [1-3] - the priorities of the report + * @param strSchedulName String - the scheduling name + * @param dayInWeek takes the value 1 to 5 for Monday to Friday. The value is 1 for Monday until 5 for Friday. + * @return the built trigger + */ + public static Trigger weekly(final Long schedulingReportId, final int reportPriority, final String strSchedulName, final int dayInWeek) { + final TriggerKey scheduledTriggerKey = getScheduledTriggerKey(schedulingReportId); + final JobKey scheduledJobKey = getScheduledJobKey(schedulingReportId); + final CronScheduleBuilder weeklySchedule = + CronScheduleBuilder.weeklyOnDayAndHourAndMinute(getDayInWeek(dayInWeek), LAUNCH_HOUR, LAUNCH_MINUTE); + final int triggerPriorities = giveTriggerPriorities(reportPriority); + return TriggerBuilder.newTrigger().withIdentity(scheduledTriggerKey).withDescription(strSchedulName).forJob(scheduledJobKey).startNow() + .withSchedule(weeklySchedule).withPriority(triggerPriorities).build(); + } + + /** + * Prepare a scheduled Trigger for the Scheduler.
+ * + * @param schedulingReportId Long - the report ID + * @param reportPriority [1-3] - the priorities of the report + * @param strSchedulName String - the scheduling name + * @return the built trigger + */ + public static Trigger daily(final Long schedulingReportId, final int reportPriority, final String strSchedulName) { + final TriggerKey scheduledTriggerKey = getScheduledTriggerKey(schedulingReportId); + final JobKey scheduledJobKey = getScheduledJobKey(schedulingReportId); + final CronScheduleBuilder dailySchedule = CronScheduleBuilder.dailyAtHourAndMinute(LAUNCH_HOUR, LAUNCH_MINUTE); + final int triggerPriorities = giveTriggerPriorities(reportPriority); + return TriggerBuilder.newTrigger().withIdentity(scheduledTriggerKey).withDescription(strSchedulName).forJob(scheduledJobKey).startNow() + .withSchedule(dailySchedule).withPriority(triggerPriorities).build(); + } + + /** + * Prepare a scheduled Trigger for the Scheduler.
+ * + * @param schedulingReportId Long - the report ID + * @param reportPriority integer - the priorities of the report + * @param strSchedulName String - the scheduling name + * @param monthType An enumeration of monthly type of scheduling ({@link WeekendPeriod}). May contains an integer for DAY_IN_MONTH (the date in month). In this case, the value should be between 1 and 31. + * @return the built trigger + */ + private static Trigger weekend(final Long schedulingReportId, final int reportPriority, final String strSchedulName, + final WeekendPeriod monthType) { + final TriggerKey scheduledTriggerKey = getScheduledTriggerKey(schedulingReportId); + final JobKey scheduledJobKey = getScheduledJobKey(schedulingReportId); + final TriggerBuilder triggerBuilder = + TriggerBuilder.newTrigger().withIdentity(scheduledTriggerKey).withDescription(strSchedulName).forJob(scheduledJobKey).startNow(); + final String cronExpression; + switch (monthType) { + case END_MONTH: + cronExpression = cronEndOfMonth(); + break; + case FIRST_WEEK_END: + cronExpression = cronWeekendByNum(LAUNCH_HOUR, LAUNCH_MINUTE, NUM_WEEK_1); + break; + case SECOND_WEEK_END: + cronExpression = cronWeekendByNum(LAUNCH_HOUR, LAUNCH_MINUTE, NUM_WEEK_2); + break; + case THIRD_WEEK_END: + cronExpression = cronWeekendByNum(LAUNCH_HOUR, LAUNCH_MINUTE, NUM_WEEK_3); + break; + case FOURTH_WEEK_END: + cronExpression = cronWeekendByNum(LAUNCH_HOUR, LAUNCH_MINUTE, NUM_WEEK_4); + break; + case FIFTH_WEEK_END: + cronExpression = cronWeekendByNum(LAUNCH_HOUR, LAUNCH_MINUTE, NUM_WEEK_5); + break; + default: + // This case shoudn't occur + log.error("An error occured during the creation of the trigger because of the value of the period for the scheduled report {}", + schedulingReportId); + return null; + } + ScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression); + final int triggerPriorities = giveTriggerPriorities(reportPriority); + return triggerBuilder.withSchedule(scheduleBuilder).withPriority(triggerPriorities).build(); + } + + private static String cronEndOfMonth() { + return "0 " + LAUNCH_MINUTE + " " + LAUNCH_HOUR + " L * ?"; + } + + /** + * Prepare a scheduled Trigger for the Scheduler.
+ * + * @param schedulingReportId Long - the report ID + * @param reportPriority [1-3] - the priorities of the report + * @param strSchedulName String - the scheduling name + * @param dayInMonth an integer for DAY_IN_MONTH (the date in month). The value should be between 1 and 31 + * @return the built trigger + */ + private static Trigger dayInMonth(final Long schedulingReportId, final int reportPriority, final String strSchedulName, final int dayInMonth) { + final TriggerKey scheduledTriggerKey = getScheduledTriggerKey(schedulingReportId); + final JobKey scheduledJobKey = getScheduledJobKey(schedulingReportId); + ScheduleBuilder scheduleEveryMonth = CronScheduleBuilder.monthlyOnDayAndHourAndMinute(dayInMonth, LAUNCH_HOUR, LAUNCH_MINUTE); + final int triggerPriorities = giveTriggerPriorities(reportPriority); + return TriggerBuilder.newTrigger().withIdentity(scheduledTriggerKey).withDescription(strSchedulName).forJob(scheduledJobKey).startNow() + .withSchedule(scheduleEveryMonth).withPriority(triggerPriorities).build(); + } + + private static String cronWeekendByNum(final int launchHour, final int launchMinute, final int coeffOfWeek) { + return "0 " + launchMinute + " " + launchHour + " ? * 1#" + coeffOfWeek; + } + + /** + * Can return a result adapted to the scheduler to the following format : + *
    + *
  • 2 for Monday. + *
  • 3 for Tuesday. + *
  • 4 for Wednesday. + *
  • 5 for Thursday. + *
  • 6 for Friday. + *
+ * + * @param dayInWeek integer - the received integer value from the IHM + * @return the adapted integer value + */ + private static int getDayInWeek(final int dayInWeek) { + return dayInWeek + 1; + } + + private static Date makeDelayedHour(final String launchDate) { + // Separate hours and minutes (format hour:minute) + String[] tableStrLaunchTime = launchDate.split(STR_COLON); + int launchHour = Integer.parseInt(tableStrLaunchTime[0]); + int launchMinute = Integer.parseInt(tableStrLaunchTime[1]); + + // Retrieve current time + Date startDate = Calendar.getInstance().getTime(); + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); + String[] tableStrCurrentTime = sdf.format(startDate).split(STR_COLON); + int currentHour = Integer.parseInt(tableStrCurrentTime[0]); + int currentMinute = Integer.parseInt(tableStrCurrentTime[1]); + + // Compare launch time to current time to customize the Trigger + Date result; + if (launchHour > currentHour) { + result = DateBuilder.todayAt(launchHour, launchMinute, 0); + } else if (launchHour < currentHour) { + result = DateBuilder.tomorrowAt(launchHour, launchMinute, 0); + } else if (launchMinute > currentMinute) { + result = DateBuilder.todayAt(launchHour, launchMinute, 0); + } else { + result = DateBuilder.tomorrowAt(launchHour, launchMinute, 0); + } + return result; + } + + /** + * Returns a scheduled report's {@link TriggerKey}. Can be used to create/retrieve a scheduled job's Trigger in Quartz. + * + * @param schedulingReportId the Id (long) of the report to be scheduled + * @return the prepared {@link TriggerKey} + */ + public static TriggerKey getScheduledTriggerKey(final Long schedulingReportId) { + return new TriggerKey(PREF_TRIGGER_NAME + schedulingReportId, ReportLaunchTypeEnum.SCHEDULED.getGroupName()); + } + + // *********************** Instance *************************** + + /** + * Returns a delayed report's {@link TriggerKey}. Can be used to create/retrieve a delayed job's Trigger in Quartz. + * + * @param delayedReportUID the UID (String) of the report to be delayed + * @return the prepared {@link TriggerKey} + */ + private static TriggerKey getDelayedTriggerKey(final String delayedReportUID) { + return new TriggerKey(PREF_TRIGGER_NAME + delayedReportUID, ReportLaunchTypeEnum.DELAYED.getGroupName()); + } + + /** + * Returns a scheduled report's {@link JobKey}. Can be used to create/retrieve a scheduled job in Quartz. + * + * @param schedulingReportId the Id (long) of the report to be scheduled + * @return the prepared {@link JobKey} + */ + public static JobKey getScheduledJobKey(final Long schedulingReportId) { + return new JobKey(PREF_JOB_NAME + schedulingReportId, ReportLaunchTypeEnum.SCHEDULED.getGroupName()); + } + + /** + * Returns a delayed report's {@link JobKey}. Can be used to create/retrieve a delayed job in Quartz. + * + * @param schedulingUID the UID (String) of the report to be scheduled + * @return the prepared {@link JobKey} + */ + private static JobKey getDelayedJobKey(final String schedulingUID) { + return new JobKey(PREF_JOB_NAME + schedulingUID, ReportLaunchTypeEnum.DELAYED.getGroupName()); + } + + /** + * Translate the priorities of the reporting.properties file into the Quartz language to the scheduler.
+ * For the settings file :
+ *
    + *
  • 1 correspond to a high priority + *
  • 2 correspond to a medium priority + *
  • 3 correspond to a low priority + *
+ * For a TriggerBuilder of Quartz : + *
    + *
  • 1 is the highest priority + *
  • 5 is the medium priority + *
  • 10 is the lowest priority + *
+ */ + private static int giveTriggerPriorities(final int reportPriorities) { + switch (reportPriorities) { + case SNECMA_LOW_PRIORITY: + return QUARTZ_LOW_PRIORITY; + case SNECMA_HIGH_PRIORITY: + return QUARTZ_HIGH_PRIORITY; + default: + return QUARTZ_MEDIUM_PRIORITY; + } + } + + // *********************** Visitor Pattern *************************** + @Override + public Trigger visit(final DayInMonth dayInMonth) { + return dayInMonth(schedulingReportId, reportPriority, strSchedulName, dayInMonth.getDayInMonth()); + } + + @Override + public Trigger visit(final WeekendPeriod weekend) { + return weekend(schedulingReportId, reportPriority, strSchedulName, weekend); + } + + @Override + public Trigger visit(final SpecificDay specificDay) { + return byDate(schedulingReportId, reportPriority, strSchedulName, specificDay.getDay()); + } + + @Override + public Trigger visit(final WeeklyPeriod dayInWeek) { + return weekly(schedulingReportId, reportPriority, strSchedulName, dayInWeek.getDayInWeek()); + } + + @Override + public Trigger visit(final DailyPeriod uselessParam) { + return daily(schedulingReportId, reportPriority, strSchedulName); + } +} diff --git a/kurt-ejb/src/main/java/com/capgemini/reports/quartz/jobs/DelayedJob.java b/kurt-ejb/src/main/java/com/capgemini/reports/quartz/jobs/DelayedJob.java new file mode 100644 index 0000000..a3627aa --- /dev/null +++ b/kurt-ejb/src/main/java/com/capgemini/reports/quartz/jobs/DelayedJob.java @@ -0,0 +1,65 @@ +package com.capgemini.reports.quartz.jobs; + +import com.capgemini.reports.database.DataBaseReportHelper; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.posting.DelayedPostingStategy; +import com.capgemini.reports.queuing.EmbeddedServer; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.quartz.*; + +import javax.jms.JMSException; +import javax.naming.NamingException; +import java.io.Serializable; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** This Quartz {@link Job} posts a report into the queue for execution. */ +@PersistJobDataAfterExecution +@DisallowConcurrentExecution +@Slf4j +// Required for Quartz +@NoArgsConstructor +public class DelayedJob implements Job, Serializable { + + private static final long serialVersionUID = -4459018522846677264L; + + /** + * Executes the requested job. The job is a report execution.
+ * This method is triggered automatically by Quartz when the time comes.
+ * An {@link AbstractExecutionReport} instance is obtained, and sent to the HornetQ queue through the {@link EmbeddedServer}. + * + * @param jobExecutionContext a {@link JobExecutionContext} containing a {@link JobDataMap} that explains what report to execute. + */ + @Override + public void execute(final JobExecutionContext jobExecutionContext) throws JobExecutionException { + // Initialize variable + JobDataMap dataMap = jobExecutionContext.getMergedJobDataMap(); + + // Retrieve the Report + AbstractExecutionReport report = (AbstractExecutionReport) dataMap.get(DelayedPostingStategy.JOB_DETAIL_KEY_REPORT); + + // Log the start + Date startDate = Calendar.getInstance().getTime(); + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); + log.info("Execution of the scheduled job for the report {} at {}.", report.getReportIdentifier().getReportName(), sdf.format(startDate)); + + // Put the report in the queues + try { + EmbeddedServer.produce(report); + } catch (JMSException | NamingException e) { + String msg = "Unable to send the report in the queues."; + log.error(msg, e); + throw new JobExecutionException(e); + } + + // Save progress in database + try { + DataBaseReportHelper.updateDelayedLaunch(report.getReportTechnicalUid()); + } catch (NotFoundException e) { + log.warn("Unable to update launch satus of delayed report, UID = " + report.getReportTechnicalUid(), e); + } + } +} diff --git a/kurt-ejb/src/main/java/com/capgemini/reports/quartz/jobs/PurgeJob.java b/kurt-ejb/src/main/java/com/capgemini/reports/quartz/jobs/PurgeJob.java new file mode 100644 index 0000000..8c2084d --- /dev/null +++ b/kurt-ejb/src/main/java/com/capgemini/reports/quartz/jobs/PurgeJob.java @@ -0,0 +1,210 @@ +package com.capgemini.reports.quartz.jobs; + +import com.capgemini.framework.common.DateHelper; +import com.capgemini.framework.common.FileHelper; +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.reports.database.manager.MngReport; +import com.capgemini.reports.database.manager.MngReport.RemovedReportEntry; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.quartz.*; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +/** Class managing the purge jobs for deleting old report files. */ +@PersistJobDataAfterExecution +@DisallowConcurrentExecution +@Slf4j +// Required for Quartz +@NoArgsConstructor +public class PurgeJob implements Job { + + private final boolean isDevMode = SettingsHelper.isDevMode(); + + /** CRON expression for when the schedule should trigger at every instance of this field (every month / every year etc. */ + private static final String CRON_EVERY = "*"; + /** CRON expression for when the schedule should not take the field into consideration (no month constraint, or no day in week constraints etc). */ + private static final String CRON_DOES_NOT_MATTER = "?"; + + private static final boolean FAIL_ON_RECOVERY = true; + + private static final String HUMAN_DESCRIPTION_FOR_PURGE = "Purge des rapports classiques et planfies"; + private static final String JOB_NAME = "job_purge"; + private static final String JOB_GROUP_NAME = "purge_group_name"; + private static final String STR_COLON = ":"; + + // Properties for report and schedulings + private static final int REPORT_NB_DAYS = SettingsHelper.getPurgeDelayReports(); + private static final int SCHEDULING_REPORT_NB_DAYS = SettingsHelper.getPurgeDelayScheduling(); + private static final File REPORT_OUTPUT_FOLDER = new File(SettingsHelper.getReportLocation()); + private static final File SCHEDULING_REPORT_OUTPUT_FOLDER_HISTORY = new File(SettingsHelper.getSchedulingHistoryLocation()); + + private static final String FORMAT_DATE = "dd/MM/yyyy HH:mm"; + + private static final CronScheduleBuilder CRON_SCHEDULE; + + static { + // Configuration for purge launch type (Pattern HH:mm) + String startTimePurge = SettingsHelper.getPurgeHour(); + String purgeSecond = "0"; + String purgeMinute = startTimePurge.split(STR_COLON)[1]; + String purgeHour = startTimePurge.split(STR_COLON)[0]; + + // Cron trigger for purge job + String fullCron = StringHelper.implode(" ", purgeSecond, purgeMinute, purgeHour, CRON_EVERY, CRON_EVERY, CRON_DOES_NOT_MATTER, CRON_EVERY); + + // Space-separated cron expressions + CRON_SCHEDULE = CronScheduleBuilder.cronSchedule(fullCron); + } + + @Override + public void execute(final JobExecutionContext jobExecutionContext) throws JobExecutionException { + if (isDevMode) { + return; // Skip + } + try { + log.info("############################################################################################################"); + log.info("Démarrage de la purge le {}", DateHelper.getDate()); + purgeReportsBefore(); + purgeScheduledReportsBefore(); + // write log to directory + log.info("La purge s'est terminee avec succès...."); + log.info("############################################################################################################"); + } catch (Exception e) { + log.error("An exception occured during purge ", e); + } + } + + private void purgeReportsBefore() { + Calendar deadlineReports = DateHelper.offsetDays(-REPORT_NB_DAYS); + log.info("Nombre de jours définis pour les rapports classiques [" + REPORT_NB_DAYS + "] "); + log.info("Démarrage de la purge des rapports classiques terminés avant le {}", new SimpleDateFormat().format(deadlineReports.getTime())); + + // Delete related data from DB + log.info("Suppression des entrées dans la base de données"); + List removed = new MngReport().deleteReportsBeforeDate(deadlineReports); + for (RemovedReportEntry removedReportsData : removed) { + log.info("\tTrouvé {} datant du [{}], nom du fichier[{}]", removedReportsData.getReport().getReportCode(), + removedReportsData.getReport().getEndGenerationDate(), removedReportsData.getReport().getFileName()); + } + log.info("{} entrées supprimée(s) dans la BDD", removed.size()); + + // Delete all files anterior to the deadline + log.info("Répertoire des rapports classiques [" + REPORT_OUTPUT_FOLDER + "] "); + List deletedReports = deleteFilesBefore(REPORT_OUTPUT_FOLDER, deadlineReports); + log.info("{} fichier(s) ont été supprimés:\n", deletedReports.size()); + log.info(StringHelper.implode("\n + ", deletedReports.toArray(new String[deletedReports.size()]))); + } + + private void purgeScheduledReportsBefore() { + Calendar deadlineSchedulings = DateHelper.offsetDays(-SCHEDULING_REPORT_NB_DAYS); + log.info("Nombre de jours définis pour les rapports planifies [{}]", SCHEDULING_REPORT_NB_DAYS); + log.info("Démarrage de la purge des rapports planifies terminés avant le {}", new SimpleDateFormat().format(deadlineSchedulings.getTime())); + log.info("Répertoire d'archivage des rapports planifiés [{}]", SCHEDULING_REPORT_OUTPUT_FOLDER_HISTORY); + + log.info("Suppression des entrées planifiées dans la base de donnée"); + List removed = new MngReport().deleteScheduledReportsBeforeDate(deadlineSchedulings); + for (RemovedReportEntry removedReportsData : removed) { + log.info("\tTrouvé {} datant du [{}], nom du fichier[{}] (planifié)", removedReportsData.getReport().getReportCode(), + removedReportsData.getReport().getEndGenerationDate(), removedReportsData.getReport().getFileName()); + } + log.info("{} entrées planifiéessupprimée(s) dans la BDD", removed.size()); + + // List files + List toBeDeletedFromHistory = listSchedulingFiles(deadlineSchedulings); + // Delete files + FileHelper.deleteFiles(toBeDeletedFromHistory); + log.info("{} fichier(s) ont été supprimés de l'historique:\n", toBeDeletedFromHistory.size()); + for (File file : toBeDeletedFromHistory) { + log.info(" + {}", file.getName()); + } + } + + private List listSchedulingFiles(Calendar deadlineSchedulings) { + List toBeDeletedFromHistory = FileHelper.listFilesBefore(SCHEDULING_REPORT_OUTPUT_FOLDER_HISTORY, deadlineSchedulings); + if (toBeDeletedFromHistory.isEmpty()) { + log.info("\tAucun fichier de rapport planifié n'est candidat pour la suppression avant la date [{}]", deadlineSchedulings); + return new ArrayList<>(); + } + return toBeDeletedFromHistory; + } + + /** + * Deletes all the files in a folder that have been modified before the provided date. + * + * @param folder the folder + * @param deadlineReports the deadline + * @return a list of all the deleted files' names + */ + private static List deleteFilesBefore(final File folder, final Calendar deadlineReports) { + SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_DATE); + List deletedFileNames = new ArrayList<>(); + for (File file : folder.listFiles()) { + if (!file.isFile()) { + continue; // Looking for a file, not a folder + } + String fileName = file.getName(); + Calendar fileMod = Calendar.getInstance(); + long lastModified = file.lastModified(); + fileMod.setTime(new Date(lastModified)); + if (fileMod.after(deadlineReports)) { + continue; // looking for older files, from BEFORE the deadline + } + if (file.delete()) { + log.info("Le fichier [{}] modifié le [{}] a été supprimé ", fileName, sdf.format(lastModified)); + deletedFileNames.add(fileName); + } else { + log.warn("Le fichier [{}] modifié le [{}] n'a pas pu être supprimé ", fileName, sdf.format(lastModified)); + } + } + return deletedFileNames; + } + + /** + * Build a job detail for Purge job. + * + * @return jobDetail + */ + public static JobDetail getPurgeJobDetail() { + JobKey purgeKey = getPurgeJobKey(); + return JobBuilder.newJob(PurgeJob.class).withIdentity(purgeKey).withDescription(HUMAN_DESCRIPTION_FOR_PURGE).requestRecovery(FAIL_ON_RECOVERY) + .storeDurably(true).build(); + } + + /** + * Build a job trigger for Purge job. + * + * @param jobDetail the requested job + * + * @return trigger + */ + public static Trigger getScheduledTrigger(final JobDetail jobDetail) { + TriggerKey purgeTriggerKey = getPurgeTriggerKey(); + return TriggerBuilder.newTrigger().withIdentity(purgeTriggerKey).forJob(jobDetail).withSchedule(CRON_SCHEDULE).build(); + } + + /** + * Build a job detail for Purge job. + * + * @return jobDetail + */ + public static JobKey getPurgeJobKey() { + return new JobKey(JOB_NAME, JOB_GROUP_NAME); + } + + /** + * Build a job detail for Purge job. + * + * @return jobDetail + */ + private static TriggerKey getPurgeTriggerKey() { + return new TriggerKey(JOB_NAME, JOB_GROUP_NAME); + } + +} diff --git a/kurt-ejb/src/main/java/com/capgemini/reports/quartz/jobs/ScheduledJob.java b/kurt-ejb/src/main/java/com/capgemini/reports/quartz/jobs/ScheduledJob.java new file mode 100644 index 0000000..063a962 --- /dev/null +++ b/kurt-ejb/src/main/java/com/capgemini/reports/quartz/jobs/ScheduledJob.java @@ -0,0 +1,212 @@ +package com.capgemini.reports.quartz.jobs; + +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.framework.common.activedirectory.ActiveDirectory; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.database.DataBaseReportHelper; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.javabean.DbSchedulingReport; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.database.manager.MngSchedulingCriteriaVal; +import com.capgemini.reports.database.manager.MngSchedulingReport; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.strategies.ScheduledExecutionStrategy; +import com.capgemini.reports.logging.ReportLoggerHelper; +import com.capgemini.reports.quartz.JobDataKeys; +import com.capgemini.reports.queuing.EmbeddedServer; +import com.google.common.base.Joiner; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.quartz.*; + +import javax.jms.JMSException; +import javax.naming.NamingException; +import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.List; +import java.util.Map; + +/** + * This Quartz {@link Job} begins the execution of a scheduled report according to a template.
+ * The {@link ScheduledJob#execute(JobExecutionContext) execute} method will be invoked automatically by Quartz when the time is right. + */ +@PersistJobDataAfterExecution +@DisallowConcurrentExecution +@Slf4j +// Required for Quartz +@NoArgsConstructor +public class ScheduledJob implements Job, Serializable { + + private static final long serialVersionUID = -7297770969201094324L; + + private static Long getTemplateID(JobDataMap dataMap) throws JobExecutionException { + if (!dataMap.containsKey(JobDataKeys.SCHEDULING_ID.toString())) { + throw new JobExecutionException("Missing template ID for ScheduledJob execution"); + } + else { + return dataMap.getLong(JobDataKeys.SCHEDULING_ID.toString()); + } + } + + /** + * Configure the {@link JobBuilder} to execute a report. + * + * @param builder the quartz {@link JobBuilder} to configure + * @param templateID the scheduling ID + * @param reportBuilderClassName the name of the class to use to instantiate the report using DB data. + */ + public static void prepareData(JobBuilder builder, Long templateID, String reportBuilderClassName) { + builder.usingJobData(JobDataKeys.SCHEDULING_ID.toString(), templateID).usingJobData(JobDataKeys.REPORT_BUILDER_CLASS_NAME.toString(), + reportBuilderClassName); + } + + /** + * Executes the requested job. The job is a scheduled report's execution.
+ * This method is triggered automatically by Quartz when the time comes. + *

+ * An {@link AbstractExecutionReport} instance is obtained from the {@link JobExecutionContext}, which represent the report template.
+ * It is cloned, the quick checks are performed, and if successful the report is sent to the HornetQ queue.
+ * If the quick checks are unsuccessful, an email is sent to every admin. + * + * @param jobExecutionContext a {@link JobExecutionContext} containing a {@link JobDataMap} that explains what report to execute. + * @throws JobExecutionException when the job could not be performed + */ + @Override + public void execute(final JobExecutionContext jobExecutionContext) throws JobExecutionException { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + // Obtain general info on his job & scheduling + JobDataMap dataMap = jobExecutionContext.getMergedJobDataMap(); + log.trace("Received a ScheduledJob request: " + Joiner.on(", ").withKeyValueSeparator("=").join(dataMap.getWrappedMap())); + Long templateID = getTemplateID(dataMap); + DbSchedulingReport dbTemplate = new MngSchedulingReport().searchById(session, templateID); + + // Get report params from DB + Map templateData = new MngSchedulingCriteriaVal().getFunctionalMap(templateID); + + // Construct the Report + AbstractExecutionReport report = constructReport(dataMap, templateData, dbTemplate); + + log.trace("ScheduledJob: Received report template: {}", dbTemplate.getSchedulingName()); + + report.setExecutionStrategy(new ScheduledExecutionStrategy()); // Override default execution strategy so emails are redirected to admins etc. + log.trace("ScheduledJob: ExecutionStrategy set"); + + // Find the name of the scheduling + String schedulingName = dbTemplate.getSchedulingName(); + // Register scheduling name to treat specific scheduled behaviors without called database + report.setScheduling(templateID, schedulingName); + + // Register current time as the posting time + report.setPostingTime(TeamcenterDateFormatter.getCurrentTime()); + + // Others parameters of the report + List launchData = report.getLaunchData(); + String reportCode = report.getReportIdentifier().getReportCode(); + String reportUid = report.getReportTechnicalUid(); + log.info("Server received a request to perform the scheduled {} report {} with parameters: {}", reportCode, reportUid, + Joiner.on(',').join(launchData)); + + // All the administrators should be subscribed to a scheduled report + List dbAdministrators = ActiveDirectory.getAdminsReportUpdateDatabase(); + log.trace("ScheduledJob: Listed {} administrators", dbAdministrators.size()); + + // Save progress in database + // Record the report launch in the database, and log this + // The user recorded in database is the user which has submitted the report + // Record the report launch in the database, and log this + DbReport theReportEntry = DataBaseReportHelper.registerScheduledLaunch(report, dbAdministrators, templateID); + log.trace("ScheduledJob: Scheduling recorded in DB"); + + // Log the report request + ReportLoggerHelper.logSchedulingRequest(theReportEntry, report); + + // Put the report in the queues for immediate execution + postReportInQueue(report); + log.trace("ScheduledJob: Scheduling posted in queue. Job done."); + } + catch (JobExecutionException e) { + log.error("An error occurred while execution Scheduled Job", e); + throw e; + } + catch (InvalidUserInputException e) { + log.error(e.getMessage(), e); + } + finally { + session.close(); + } + } + + private AbstractExecutionReport constructReport(JobDataMap dataMap, Map templateData, + DbSchedulingReport dbTemplate) throws JobExecutionException { + // Obtain the class name + String reportBuilderClassName = (String) dataMap.get(JobDataKeys.REPORT_BUILDER_CLASS_NAME.toString()); + ReportBuilder builder = obtainBuilder(reportBuilderClassName); + try { + return builder.build(templateData); + } + catch (InsufficientParametersException e) { + throw new JobExecutionException("Insufficient parameters to build a valid report from template " + dbTemplate.getId() + + " (" + dbTemplate.getReportCode() + ")", e); + } + } + + @SuppressWarnings("unchecked") + private ReportBuilder obtainBuilder(String reportBuilderClassName) throws JobExecutionException { + // Obtain the incoming Class object. + Class theClass; + try { + theClass = Class.forName(reportBuilderClassName); + } + catch (SecurityException | ClassNotFoundException e) { + throw new JobExecutionException("Unable to find a class with name " + reportBuilderClassName, e); + } + + // Cast to the ReportBuilder class. + Class reportBuilderClass; + try { + reportBuilderClass = (Class) theClass; + } + catch (ClassCastException e) { + throw new JobExecutionException( + "The provided class " + reportBuilderClassName + " is not a sub-class of " + ReportBuilder.class.getName(), e); + } + // Request a constructor (no-args, no Class params) + Constructor cstr; + try { + cstr = reportBuilderClass.getConstructor(); // Requesting a no-args constructor! + } + catch (SecurityException | NoSuchMethodException e) { + throw new JobExecutionException("Unable to locate a no-args constructor for " + reportBuilderClassName, e); + } + + // Obtain an instance of the Builder + try { + return cstr.newInstance(); + } + catch (SecurityException | InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new JobExecutionException("Unable to create an instance from constructor of " + reportBuilderClassName, e); + } + } + + private void postReportInQueue(final AbstractExecutionReport report) throws JobExecutionException { + try { + EmbeddedServer.produce(report); + } + catch (JMSException | NamingException e) { + String msg = "Unable to send the report in the queues."; + log.error(msg, e); + throw new JobExecutionException(msg, e); + } + } + +} diff --git a/kurt-ejb/src/main/java/com/capgemini/reports/queuing/EmbeddedServer.java b/kurt-ejb/src/main/java/com/capgemini/reports/queuing/EmbeddedServer.java new file mode 100644 index 0000000..9f5c884 --- /dev/null +++ b/kurt-ejb/src/main/java/com/capgemini/reports/queuing/EmbeddedServer.java @@ -0,0 +1,115 @@ +package com.capgemini.reports.queuing; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.ejb.Singleton; +import javax.ejb.Startup; +import javax.jms.JMSException; +import javax.jms.MessageProducer; +import javax.jms.ObjectMessage; +import javax.jms.Queue; +import javax.jms.QueueConnection; +import javax.jms.QueueConnectionFactory; +import javax.jms.QueueSession; +import javax.jms.Session; +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import com.capgemini.reports.execution.AbstractExecutionReport; + +import lombok.extern.slf4j.Slf4j; + +/** This class is responsible for the setup of the Queues, the producers and the consumers. **/ +@Startup +@Singleton +@Slf4j +public class EmbeddedServer { + + private static final int LOW_PRIORITY_VALUE = 3; + private static final int MED_PRIORITY_VALUE = 5; + private static final int HIGH_PRIORITY_VALUE = 7; + + private static QueueConnection jmsConnection; + + /** + * On construction, the connection is set up and started. + * + * @throws JMSException if unable to obtain queue name from JMS + * @throws NamingException of queue name does not exist in JMS + */ + @PostConstruct + public void init() throws JMSException, NamingException { + log.info("Initializing HornetQ session, queues, producers and consumers"); + InitialContext initialContext = new InitialContext(); + + /* + * In standalone-xxxx.xml, there should be a connection factory with an named entry: + * <-- this could be in-vm (accessible from same VM as the server, no outside request) + * [...] + * + * + * + * + */ + QueueConnectionFactory connectionFactory = (QueueConnectionFactory) initialContext.lookup("/ConnectionFactory"); + createQueueConnection(connectionFactory); + + // Begin + jmsConnection.start(); + } + + private static void createQueueConnection(final QueueConnectionFactory connectionFactory) throws JMSException { + EmbeddedServer.jmsConnection = connectionFactory.createQueueConnection(); + } + + /** + * On destroy, the producers, consumers, sessions and the connection to the JMS will be closed. + * + * @throws JMSException if unable to close to jms conection properly + */ + @PreDestroy + public void destroy() throws JMSException { + log.info("Destroying HonetQ session"); + + // Close the connection + jmsConnection.close(); + } + + /** + * Sends a report through to hornetQ for queuing. + * + * @param report the report to post in queue + * @throws JMSException if unable to talk to JMS + * @throws NamingException if unable to find queue in JMS + */ + public static void produce(final AbstractExecutionReport report) throws JMSException, NamingException { + // Open a session just for sending this message + QueueSession jmsSession = jmsConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); + try { + InitialContext initialContext = new InitialContext(); + Queue queue = (Queue) initialContext.lookup("/queues/kurtQueue"); + + ObjectMessage message = jmsSession.createObjectMessage(report); + + // Setup producers and their priorities + MessageProducer producer = jmsSession.createProducer(queue); + switch (report.getReportPriority()) { + case HIGH_PRIORITY: + producer.setPriority(HIGH_PRIORITY_VALUE); + break; + case MED_PRIORITY: + producer.setPriority(MED_PRIORITY_VALUE); + break; + default: + producer.setPriority(LOW_PRIORITY_VALUE); + break; + } + producer.send(message); + } finally { + // We're done sending messages until next request. But the underlying Connection is of course still open. + if (jmsSession != null) { + jmsSession.close(); + } + } + } +} diff --git a/kurt-ejb/src/main/java/com/capgemini/reports/queuing/consumer/ReportConsumer.java b/kurt-ejb/src/main/java/com/capgemini/reports/queuing/consumer/ReportConsumer.java new file mode 100644 index 0000000..059a2a4 --- /dev/null +++ b/kurt-ejb/src/main/java/com/capgemini/reports/queuing/consumer/ReportConsumer.java @@ -0,0 +1,96 @@ +package com.capgemini.reports.queuing.consumer; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NoConfChangesException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import org.jboss.ejb3.annotation.ResourceAdapter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ejb.ActivationConfigProperty; +import javax.ejb.MessageDriven; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.ObjectMessage; + +/** + * This class represents a generic Consumer of messages.
+ * It is a Message-Driven Bean (MDB) whose properties are also defined in ejb-jar.xml (in the war's WEB-INF folder) . + */ +@MessageDriven(name = "jobConsumer", activationConfig = { + @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), + @ActivationConfigProperty(propertyName = "destination", propertyValue = "/queues/kurtQueue"), + @ActivationConfigProperty(propertyName = "consumerWindowSize", propertyValue = "0")}) +@ResourceAdapter("hornetq-ra.rar") +public class ReportConsumer implements MessageListener { + private static final Logger LOGGER = LoggerFactory.getLogger(ReportConsumer.class); + + /** + * This method processes incoming messages containing reports to be performed.
+ * + * @param message a {@link Message} containing an {@link AbstractExecutionReport} to perform. + */ + @Override + public void onMessage(final Message message) { + AbstractExecutionReport report; + + try { + report = obtainReport(message); + } + catch (UnsupportedOperationException e) { + LOGGER.warn("Unable to handle report request, dropping the request", e); + return; + } + + // If CLEANUP is set, ignore the incoming reports. Treat them as a Technical errors in the DB. + if (SettingsHelper.isCleanup()) { + final String optionalStartTime = report.getStartTime() != null ? " Start:" + report.getStartTime() : ""; + LOGGER.error("[CLEANUP] {} {}", report.getReportTechnicalUid(), optionalStartTime); + report.getExecutionStrategy().handleTechnicalError(report, new Throwable("Report cleaned up")); + return; + } + + try (TcSession session = new TcSession()) { + session.login(); + report.doStart(session); + } + catch (NoTeamcenterConnectionException e) { + // Unable to create a connection to the server dispatcher in the first place + report.getExecutionStrategy().handleTechnicalError(report, e); + } + catch (NoConfChangesException e) { + report.getExecutionStrategy().handleFunctionalError(report, e); + } + catch (InvalidUserInputException e) { + report.getExecutionStrategy().handleFunctionalError(report, e); + } + catch (Exception e) { + LOGGER.error("Exception encountered", e); + // This Throwable is caught in order for this message to NOT be re-posted immediately and indefinitely by HornetQ, who thinks the message has not been delivered correctly! + report.getExecutionStrategy().handleTechnicalError(report, e); + } + } + + private AbstractExecutionReport obtainReport(final Message message) { + if (!(message instanceof ObjectMessage)) { + throw new UnsupportedOperationException("onMessage() received an unhandled message: " + message.getClass().getName() + ", expecting an ObjectMessage"); + } + try { + Object object = ((ObjectMessage) message).getObject(); + if (!(AbstractExecutionReport.class.isInstance(object))) { + throw new UnsupportedOperationException("onMessage() received an unhandled object inside the message: " + object.toString() + " of type " + object.getClass().getName() + ", expecting an AbstractExecutionReport"); + } + else { + // message.acknowledge(); <-- No need because the queue was set up using AUTO_ACKNOWLEDGE + return (AbstractExecutionReport) object; + } + } + catch (JMSException e) { + throw new UnsupportedOperationException("onMessage() could not obtain the Object packed inside the message", e); + } + } +} diff --git a/kurt-ejb/src/main/resources/META-INF/beans.xml b/kurt-ejb/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000..3738086 --- /dev/null +++ b/kurt-ejb/src/main/resources/META-INF/beans.xml @@ -0,0 +1,27 @@ + + + + + + diff --git a/kurt-ejb/src/main/resources/log4j.properties b/kurt-ejb/src/main/resources/log4j.properties new file mode 100644 index 0000000..6d5fed6 --- /dev/null +++ b/kurt-ejb/src/main/resources/log4j.properties @@ -0,0 +1,21 @@ +log4j.logger.com.teamcenter.soa=WARN, stdout +log4j.additivity.com.teamcenter.soa=false +log4j.logger.com.teamcenter.soa.client.Connection=INFO, stdout +log4j.additivity.com.teamcenter.soa.client.Connection=false +log4j.logger.org.apache=WARN, stdout +log4j.logger.httpclient=WARN, stdout +log4j.logger.com.capgemini=DEBUG, stdout + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.threshold=DEBUG +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %c{1}:%L - %m%n + +# Root logger option +log4j.rootLogger=ERROR, stdout + +# Remove Arjuna Warnings +log4j.logger.com.arjuna.ats.jta=ERROR + diff --git a/kurt-ejb/src/test/resources/log4j.properties b/kurt-ejb/src/test/resources/log4j.properties new file mode 100644 index 0000000..8f372cd --- /dev/null +++ b/kurt-ejb/src/test/resources/log4j.properties @@ -0,0 +1,13 @@ +log4j.logger.com.teamcenter.soa=WARN +log4j.logger.org.apache=WARN +log4j.logger.httpclient=WARN + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.threshold=DEBUG +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %c{1}:%L - %m%n + +# Root logger option +log4j.rootLogger=DEBUG, stdout diff --git a/kurt-ejb/src/test/resources/logging.properties b/kurt-ejb/src/test/resources/logging.properties new file mode 100644 index 0000000..1983b8d --- /dev/null +++ b/kurt-ejb/src/test/resources/logging.properties @@ -0,0 +1,3 @@ +handlers=java.util.logging.ConsoleHandler +java.util.logging.ConsoleHandler.level=FINEST +com.capgemini.level=FINEST diff --git a/kurt-ejb/src/test/resources/quartz.properties b/kurt-ejb/src/test/resources/quartz.properties new file mode 100644 index 0000000..435f06e --- /dev/null +++ b/kurt-ejb/src/test/resources/quartz.properties @@ -0,0 +1,58 @@ +#========================================================================== +# Configure Main Scheduler Properties +#========================================================================== +org.quartz.scheduler.instanceName: DefaultQuartzScheduler +org.quartz.scheduler.rmi.export: false +org.quartz.scheduler.rmi.proxy: false +org.quartz.scheduler.wrapJobExecutionInUserTransaction: false +org.quartz.scheduler.batchTriggerAcquisitionMaxCount = 100 +org.quartz.scheduler.batchTriggerAcquisitionFireAheadTimeWindow =1 + +# Amount of time in milliseconds that the scheduler will wait before re-queries for available triggers when the scheduler is otherwise idle +org.quartz.scheduler.idleWaitTime: 1000 + +# Amount of time in milliseconds that the scheduler will wait between re-tries when it has detected a loss of connectivity to the database (obviously not meaningful with RamJobStore) +org.quartz.scheduler.dbFailureRetryInterval: 3600 + +#========================================================================== +# Configure ThreadPool +#========================================================================== +org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool + +# Number of threads that are available for concurrent execution of jobs +org.quartz.threadPool.threadCount: 100 + +# Thread priority (Can be any int between Thread.MIN_PRIORITY (which is 1) and Thread.MAX_PRIORITY (which is 10). The default is Thread.NORM_PRIORITY (5)) +org.quartz.threadPool.threadPriority: 5 + +org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true + +#========================================================================== +# Configure JobStore +#========================================================================== +org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX +org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate +org.quartz.jobStore.dataSource = myDS +org.quartz.jobStore.tablePrefix =QRTZ_ +org.quartz.jobStore.useProperties = false +org.quartz.jobStore.misfireThreshold = 60000 +org.quartz.jobStore.isClustered = false +org.quartz.jobStore.maxMisfiresToHandleAtATime = 20 +org.quartz.jobStore.dontSetAutoCommitFalse = false + +# "{0}" is replaced during run-time with the TABLE_PREFIX that you configured above and "{1}" with the scheduler's name +org.quartz.jobStore.selectWithLockSQL = "SELECT * FROM {0}LOCKS WHERE SCHED_NAME = {1} AND LOCK_NAME = ? FOR UPDATE" + +org.quartz.jobStore.txIsolationLevelSerializable = false +org.quartz.jobStore.acquireTriggersWithinLock = true + +#========================================================================== +# Configure Datasources +#========================================================================== +org.quartz.dataSource.myDS.driver = oracle.jdbc.driver.OracleDriver +org.quartz.dataSource.myDS.URL = jdbc:oracle:thin:@10.24.192.36:1521:TC +org.quartz.dataSource.myDS.user =TAC +org.quartz.dataSource.myDS.password =TAC + +# Be configured to be at least the number of worker threads in the thread pool plus three +org.quartz.dataSource.myDS.maxConnections = 103 diff --git a/kurt-ejb/src/test/resources/simplelogger.properties b/kurt-ejb/src/test/resources/simplelogger.properties new file mode 100644 index 0000000..e69de29 diff --git a/kurt-ejb/src/test/resources/test_policy.xml b/kurt-ejb/src/test/resources/test_policy.xml new file mode 100644 index 0000000..e0c3961 --- /dev/null +++ b/kurt-ejb/src/test/resources/test_policy.xml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/pom.xml b/kurt-utility/pom.xml new file mode 100644 index 0000000..6ccb1e8 --- /dev/null +++ b/kurt-utility/pom.xml @@ -0,0 +1,209 @@ + + + 4.0.0 + kurt-utility + jar + kurt-utility + + + com.capgemini.reports + kurt + 1.32.9 + + + + + com.capgemini.reports + teamcenter + 1.32.9 + + + + com.capgemini.reports + jasper + 1.32.9 + + + + junit + junit + test + + + + org.mockito + mockito-core + test + + + + org.assertj + assertj-core + test + + + + + org.slf4j + slf4j-api + + + + org.projectlombok + lombok + + + + org.jboss.spec.javax.annotation + jboss-annotations-api_1.1_spec + + + + commons-io + commons-io + + + com.sun.mail + javax.mail + 1.4.7 + + + commons-net + commons-net + 3.1 + + + + org.hibernate + hibernate-core + + + + com.oracle + ojdbc6 + 11.2.0.3 + provided + + + + com.google.guava + guava + + + + + com.hp.gagawa + gagawa + 1.0.1 + + + + net.lingala.zip4j + zip4j + 1.3.2 + + + com.opencsv + opencsv + 3.10 + + + + org.testng + testng + 6.8 + test + + + org.apache.poi + poi + 3.17 + test + + + org.apache.poi + poi-ooxml + 3.17 + test + + + + + + + + + + + + src/main/resources + true + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + src/val/resources/testng.yaml + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.0.0 + + + add-integration-test-source + generate-test-sources + + add-test-source + + + + src/val/java + + + + + add-integration-test-resources + generate-test-resources + + add-test-resource + + + + + + + src/val/resources + true + + + + + + + + + + diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/AbstractPropertiesManager.java b/kurt-utility/src/main/java/com/capgemini/framework/common/AbstractPropertiesManager.java new file mode 100644 index 0000000..f99c980 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/AbstractPropertiesManager.java @@ -0,0 +1,241 @@ +package com.capgemini.framework.common; + +import lombok.extern.slf4j.Slf4j; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Map.Entry; +import java.util.Properties; + +/** + * Property manager pattern for managing settings.
+ * All methods are protected, please extend this class to present a specific getter method of the right type for each parameter. + **/ +@Slf4j +public abstract class AbstractPropertiesManager { + + private static final String UNEXPECTED_FORMAT_OF_PROPERTY = "Unexpected format of property: "; + + /** File path to the property file. **/ + final String propertyFilePath; + + /** Prefix that should be appended at the beginning of all properties. **/ + private final String propertyCommonPrefix; + + /** Properties resource bundle corresponding to the propertyFilePath. **/ + private final Properties propertyFile; + + /** + * Constructor : load the properties from the property file. + * + * @param aPropertyFilePath File path to the property file + **/ + AbstractPropertiesManager(final String aPropertyFilePath) { + propertyFilePath = aPropertyFilePath; + propertyCommonPrefix = getPropPrefix(); + propertyFile = new Properties(); + // load file + try { + loadServerPopertiesFile(); + } catch (IOException e) { + log.error("Unable to load properties from file: " + propertyFilePath, e); + } + // log properties reado + if (log.isDebugEnabled()) { + log.debug("-- First startup of Properties Manager --"); + for (Entry entry : propertyFile.entrySet()) { + log.debug(String.format(" + Key: %-70s Value: %s", entry.getKey(), entry.getValue())); + } + } + } + + /** + * Get Boolean value from settings. + * + * @param aKey Searched setting key + * @return boolean value matching with searched setting key + */ + protected boolean getBooleanValue(final String aKey) { + boolean theBoolValue = false; + String theValue = getStringValue(aKey); + if ((theValue != null) && (isTrue(theValue))) { + theBoolValue = true; + } + return theBoolValue; + } + + /** + * Check if current value match with a value considered as "true". + * + * @param aValue String value which should be analyzed + * @return Boolean interpretation of current String value + **/ + private static boolean isTrue(final String aValue) { + boolean theStatus = false; + final String[] trueValueArray = {"true", "TRUE", "True", "1"}; + for (String aCurrentValue : trueValueArray) { + if (aCurrentValue.equals(aValue)) { + theStatus = true; + break; + } + } + return theStatus; + } + + /** + * Get Integer value from settings. + * + * @param aKey Searched setting key + * @return integer value matching with searched setting key + */ + int getIntegerValue(final String aKey) { + int theIntValue = 0; + try { + String theValue = getStringValue(aKey); + if (theValue != null) { + theIntValue = Integer.valueOf(theValue); + } + } catch (NumberFormatException e) { + log.error(UNEXPECTED_FORMAT_OF_PROPERTY + aKey + " (it should be an integer)", e); + } + return theIntValue; + } + + /** + * Get a string value from settings. + * + * @param aKey Searched setting key + * @return String value matching with searched setting key + */ + String getStringValue(final String aKey) { + // Read property value + String thePropertyValue = getProperty(aKey); + + // Log warning when a property has not been found + if (thePropertyValue == null) { + log.error("Setting reference: \"" + aKey + "\" has not been found"); + } + + return thePropertyValue; + } + + /** + * Get a property from the reference parameter and set a default value if the reference is not found. + * + * @param aRef Setting key + * @param aDefaultValue Default returned value when setting is not defined + * @return string value matching with searched setting key or default value when key has not been found + */ + String getPropertyWithDefaultValueImpl(final String aRef, final String aDefaultValue) { + // Read property value + String thePropertyValue = getProperty(aRef); + + if (thePropertyValue == null) { + thePropertyValue = aDefaultValue; + } + return thePropertyValue; + } + + /** + * Get a property from the reference parameter and set a default value if the reference is not found. + * + * @param aRef Setting key + * @param aDefaultValue Default returned boolean when setting is not defined + * @return string value matching with searched setting key or default value when key has not been found + */ + boolean getBooleanWithDefaultValueImpl(final String aRef, final boolean aDefaultValue) { + // Read property value + String thePropertyValue = getProperty(aRef); + if (thePropertyValue == null) { + return aDefaultValue; + } else { + return isTrue(thePropertyValue); + } + } + + /** + * Attempt to load server properties. If failed, loads internal EAR properties. + * + * @throws IOException if even the internal file couldn't be read + */ + private void loadServerPopertiesFile() throws IOException { + String theJbossConfPath = System.getenv("JBOSS_HOME") + "/standalone/configuration/" + propertyFilePath; + boolean isConfFile = FileHelper.fileExist(theJbossConfPath); + if (isConfFile) { + log.debug("JBOSS configuration file has been found in: " + theJbossConfPath); + try (FileInputStream thePropStream = new FileInputStream(theJbossConfPath)) { + readPropertiesFile(thePropStream); + } catch (IOException e) { + log.error("JBOSS configuration file has been found but is not readable : " + theJbossConfPath + + " defaulting to internal porperties file", e); + loadinternalPropertiesFile(); + } + } else { + log.info("EAR file will be used, no configuration file found in " + theJbossConfPath); + loadinternalPropertiesFile(); + } + } + + /** + * Loads the internal EAR file. + * @throws IOException if unable to read the file + */ + private void loadinternalPropertiesFile() throws IOException { + try (InputStream stream = AbstractPropertiesManager.class.getResourceAsStream(propertyFilePath)) { + readPropertiesFile(stream); + } + } + + /** + * Reads any {@link InputStream} into a {@link Properties} file using the correct {@link Charset}. + * @param stream the stream to the file + * @throws IOException if unable to load the file + */ + private void readPropertiesFile(InputStream stream) throws IOException { + Reader reader = new InputStreamReader(stream, StandardCharsets.ISO_8859_1); + propertyFile.load(reader); + } + + /** + * Insert a required prefix at the beginning of property reference. Then obtains the value associated with it. Return may be null. + * + * @param aPropRef Property reference to find + * @return String content of searched property, null if no such key found + */ + private String getProperty(final String aPropRef) { + // filter invalid characters in the key + String filteredKey = aPropRef.replaceAll(StringHelper.REGEXP_ALPHANUM, ""); + + // Insert common prefix if not present + String thePropRefWithPrefix; + if ((propertyCommonPrefix != null) && !filteredKey.startsWith(propertyCommonPrefix)) { + thePropRefWithPrefix = propertyCommonPrefix + filteredKey; + } else { + thePropRefWithPrefix = filteredKey; + } + + // Get property content + String propertyValue = propertyFile.getProperty(thePropRefWithPrefix); + if (propertyValue == null) { + return null; + } else { + return new String(propertyValue.getBytes(), StandardCharsets.ISO_8859_1); + } + } + + Properties getPropertyFile() { + return propertyFile; + } + + /** + * Getter for prefix that should be appended at the beginning of all properties. + * + * @return The common prefix value + **/ + protected abstract String getPropPrefix(); +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/DateHelper.java b/kurt-utility/src/main/java/com/capgemini/framework/common/DateHelper.java new file mode 100644 index 0000000..cb4bf03 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/DateHelper.java @@ -0,0 +1,136 @@ +package com.capgemini.framework.common; + +import lombok.extern.slf4j.Slf4j; + +import java.sql.Date; +import java.sql.Time; +import java.sql.Timestamp; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; + +/** + * This class is able to creates dates in a specific format (dd-MM-yyyy HH:mm). + */ +@Slf4j +public final class DateHelper { + + private static final String STD_YEAR_MONTH_FORMAT = "yyyy-MM"; + private static final String STD_DATE_FORMAT = "dd-MM-yyyy"; + + private DateHelper() { + // Private constructor to make this an utility class + } + + /** + * Converts a {@link Calendar} to a sql {@link Timestamp}. + * + * @param cal the {@link Calendar} to convert + * @return the {@link Timestamp} + */ + public static Timestamp toTimestamp(final Calendar cal) { + return new Timestamp(cal.getTime().getTime()); + } + + /** + * Extract current SQL date. + * + * @return the {@link Date} + **/ + public static Date getCurrentSqlDate() { + java.util.Date currentUtilDate = new java.util.Date(); + return new Date(currentUtilDate.getTime()); + } + + /** + * Extract current SQL time stamp. + * + * @return the {@link Time} + **/ + public static Timestamp getCurrentSqlTimestamp() { + java.util.Date currentUtilDate = new java.util.Date(); + return new Timestamp(currentUtilDate.getTime()); + } + + /** + * Compute the code for the current month period (year + "-" + month). + * + * @return the {@link Time} + **/ + public static String getMonthPeriod() { + return new SimpleDateFormat(STD_YEAR_MONTH_FORMAT).format(getCurrentSqlDate()); + } + + /** + * Returns a Date that references today, at 00:00 am. + * + * @return the date of today with the following format (ex : 01-01-2015) + */ + public static String getDate() { + java.util.Date today = new java.util.Date(); + return new SimpleDateFormat(STD_DATE_FORMAT).format(today); + } + + /** + * Returns a Calendar representing the current date, offset by the number of days provided. + * + * @param nbDays nb ofdays to offset from today. psoitive: offset in the future. + * @return a {@link Calendar} + */ + public static Calendar offsetDays(final int nbDays) { + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.DAY_OF_MONTH, nbDays); + return cal; + } + + /** + * Returns tomorrow, at 00:00m. + * + * @return date + */ + public static String getDatePlusOne() { + Calendar today = Calendar.getInstance(); + today.add(Calendar.DATE, 1); + return today.get(Calendar.DATE) + "-" + (today.get(Calendar.MONTH) + 1) + "-" + today.get(Calendar.YEAR); + } + + /** + * Returns the reference date, offset by the provided number of days (positive in the future, negativ ein the past). + * + * @param dateReference the reference date + * @return date +1 + */ + public static Calendar getDatePlusOneWithReferenceCalendar(final Calendar dateReference) { + Calendar aujourdhui = Calendar.getInstance(); + if (dateReference != null) { + aujourdhui.setTime(dateReference.getTime()); + } + aujourdhui.add(Calendar.DATE, 1); + return aujourdhui; + } + + /** + * Allow to findAll the date + 1 of a date which is entry in parameter. + * + * @param ref the reference date + * @return date the input date, offset by the requested amount and formatted + */ + public static String getDatePlusOneWithReferenceString(final String ref) { + SimpleDateFormat curFormater = new SimpleDateFormat(STD_DATE_FORMAT); + Calendar theDate = Calendar.getInstance(); + + try { + java.util.Date dateObj = curFormater.parse(ref); + theDate.setTime(dateObj); + } + catch (ParseException e) { + log.error("Unable to parse the Date : '" + ref + "', defaulting to tomorrow", e); + } + theDate.add(Calendar.DATE, 1); + return theDate.get(Calendar.DATE) + "-" + (theDate.get(Calendar.MONTH) + 1) + "-" + theDate.get(Calendar.YEAR); + } + + public static java.util.Date parseDate(final String ref) throws ParseException { + return new SimpleDateFormat(STD_DATE_FORMAT).parse(ref); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/DoubleFormatter.java b/kurt-utility/src/main/java/com/capgemini/framework/common/DoubleFormatter.java new file mode 100644 index 0000000..0951ecc --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/DoubleFormatter.java @@ -0,0 +1,116 @@ +package com.capgemini.framework.common; + +/** Formats a double to String, allowing specification of a number of significant digits. */ +public final class DoubleFormatter { + + private static final String MINUS = "-"; + private static final String EMPTY_STRING = ""; + private static final String DOT = "."; + private static final char ZERO_CHAR = '0'; + private static final int TEN = 10; + /** Limited by the java Long used to represent the mantissa. */ + private static final int MAX_SIGNIFICANT_DIGITS = 16; + + private DoubleFormatter() { + // nothing in here + } + + /** + * Rounds a double value to a number of significant digits. + *

+ * Examples: + *

    + *
  • {@code toSignificantDigits(20001054, 9)} gives {@code "20001054"}
  • + *
  • {@code toSignificantDigits(-20001054, 9)} gives {@code "-20001054"}
  • + *
  • {@code toSignificantDigits(200010.54, 9)} gives {@code "200010.54"}
  • + *
  • {@code toSignificantDigits(200010.54, 8)} gives {@code "200010.54"}
  • + *
  • {@code toSignificantDigits(200010.54, 3)} gives {@code "200000"}
  • + *
  • {@code toSignificantDigits(200010.54, 7)} gives {@code "200010.5"}
  • + *
  • {@code toSignificantDigits(200010.54, 7)} gives {@code "200010.6"}
  • + *
  • {@code toSignificantDigits(0.00020051024, 6)} gives {@code "0.00020051"}
  • + *
  • {@code toSignificantDigits(-0.00020051054, 3)} gives {@code "-0.000201"}
  • + *
+ * + * @param value the value to be rounded + * @param someSignificantDigits MUST be lower or equal to 16 (limited by the java Long used to represent the mantissa) + * @return the {@link String} representation of the value, with the required digits + */ + public static String toSignificantDigits(final double value, final int someSignificantDigits) { + if (value == 0) { + return "0"; + } + int significantDigits = Math.min(someSignificantDigits, MAX_SIGNIFICANT_DIGITS); + + // Extract sub-components: sign, mantissa and exponent + double abs = Math.abs(value); + int power = (int) Math.floor(Math.log10(abs)); + double mantissa = abs * Math.pow(TEN, -power); + String mantissaStr = Double.toString(mantissa); + + // Exctract the coma position + int numDigits; + String mantissaWithoutDot; + if (mantissaStr.contains(DOT)) { + numDigits = mantissaStr.length() - 1; + mantissaWithoutDot = mantissaStr.replace(DOT, EMPTY_STRING); + } + else { + numDigits = 1; + mantissaWithoutDot = mantissaStr; + } + + // Mantissa cannot exceed 2^63 (about 10^18) which is max value for long + if (mantissaWithoutDot.length() > MAX_SIGNIFICANT_DIGITS) { + mantissaWithoutDot = mantissaWithoutDot.substring(0, MAX_SIGNIFICANT_DIGITS); + numDigits = MAX_SIGNIFICANT_DIGITS; + } + + // Round to the number of significant digits IF there are more digits than significant digits + String truncatedMantissaWithoutDot; + if (numDigits > significantDigits) { + long trueValue = Long.valueOf(mantissaWithoutDot); + double powToRound = (long) Math.pow(TEN, mantissaWithoutDot.length() - significantDigits); + long roundedFinalNumber = Math.round(trueValue / powToRound) * (long) powToRound; + truncatedMantissaWithoutDot = String.valueOf(roundedFinalNumber); + } + else { // No need to round + truncatedMantissaWithoutDot = mantissaWithoutDot; + } + // Remove uneeded zeroes in the mantissa + while (truncatedMantissaWithoutDot.length() > 1 && truncatedMantissaWithoutDot.charAt(truncatedMantissaWithoutDot.length() - 1) == ZERO_CHAR) { + truncatedMantissaWithoutDot = truncatedMantissaWithoutDot.substring(0, truncatedMantissaWithoutDot.length() - 1); + } + + return compileTheNumber(value, power, truncatedMantissaWithoutDot); + } + + private static String compileTheNumber(final double value, final int power, final String truncatedMantissaWithoutDot) { + // Write the number using its sign, mantissa and power + String signum = Math.signum(value) >= 0 ? EMPTY_STRING : MINUS; + if (power >= 0) { + if (power < truncatedMantissaWithoutDot.length() - 1) { + // fractional number 'ABC.XYZ' + String intPart = truncatedMantissaWithoutDot.substring(0, power + 1); + String fracPart = truncatedMantissaWithoutDot.substring(power + 1); + return signum + intPart + DOT + fracPart; + } + else { + // Integer number (significant mantisse is shorter than power) of the form 'ABCXYZ000' + StringBuilder builder = new StringBuilder(signum).append(truncatedMantissaWithoutDot); + for (int additionalZeroes = 0; additionalZeroes < power + 1 - truncatedMantissaWithoutDot.length(); additionalZeroes++) { + builder.append(ZERO_CHAR); + } + return builder.toString(); + } + } + else { + // Leading zeroes, then full significant mantissa: '0.000ABCXYZ' + StringBuilder builder = new StringBuilder(signum).append("0."); + for (int additionalZeroes = 0; additionalZeroes < -power - 1; additionalZeroes++) { + builder.append(ZERO_CHAR); + } + builder.append(truncatedMantissaWithoutDot); + return builder.toString(); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/DynamicErrorTemplateHelper.java b/kurt-utility/src/main/java/com/capgemini/framework/common/DynamicErrorTemplateHelper.java new file mode 100644 index 0000000..aca1337 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/DynamicErrorTemplateHelper.java @@ -0,0 +1,37 @@ +package com.capgemini.framework.common; + +import lombok.Getter; + +/** + * Customizable messages (using tags). + */ +@Getter +public class DynamicErrorTemplateHelper { + + private String refError; + private final String[] tags; + + /** + * Constructor. + * + * @param refError a reference error message (with tags) + * @param tags a list of known tags + */ + public DynamicErrorTemplateHelper(final String refError, final String... tags) { + this.refError = refError; + this.tags = tags; + } + + /** + * Resolve a dynamic error.
+ * Put each tags in theirs places. + * + * @return refErrorString + */ + public String resolve() { + for (String tag : tags) { + refError = refError.replaceFirst("\\{\\}", tag); + } + return refError; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/FileHelper.java b/kurt-utility/src/main/java/com/capgemini/framework/common/FileHelper.java new file mode 100644 index 0000000..71f83db --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/FileHelper.java @@ -0,0 +1,210 @@ +package com.capgemini.framework.common; + +import com.capgemini.reports.exceptions.NotFoundException; +import com.google.common.io.Files; +import lombok.extern.slf4j.Slf4j; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +/** + * Class for common file management. + **/ +@Slf4j +public final class FileHelper { + + /** + * Default char set (ISO format). + **/ + private static final String CHARSET_ISO = "ISO-8859-1"; + private static final String FILE_DOES_NOT_EXIST = "File does not exist: "; + + /** + * Constructor. + **/ + private FileHelper() { + // Constructor of helper classes must be private + } + + /** + * Return the default character encoding. + * + * @return Charset encoding + **/ + private static Charset getDefaultCharset() { + return Charset.forName(CHARSET_ISO); + } + + /** + * Check file existence (with verbose mode by default). + * + * @param aFilePath File which must be checked + * @return True when the file exists + */ + public static boolean fileExist(final String aFilePath) { + return fileExist(aFilePath, true); + } + + /** + * Check file existence. + * + * @param aFilePath File which must be checked + * @param isVerbose True for verbose mode, else the silent mode is used + * @return True when the file exists + */ + public static boolean fileExist(final String aFilePath, final boolean isVerbose) { + boolean status = true; + + if (aFilePath == null) { + if (isVerbose) { + log.debug("File name is null"); + } + return false; + } + + File theFile = new File(aFilePath); + if (!theFile.exists() || theFile.isDirectory()) { + if (isVerbose) { + log.debug(FILE_DOES_NOT_EXIST + theFile.getAbsolutePath()); + } + status = false; + } + + return status; + } + + /** + * Read a text file and findAll its content. + * + * @param aSourceFilePath parsed source file path + * @return string with text file content + */ + public static String read(final String aSourceFilePath) { + + // Check file existence + if (!fileExist(aSourceFilePath)) { + log.error(FILE_DOES_NOT_EXIST + aSourceFilePath); + return null; + } + + // Read file content + return read(getStream(aSourceFilePath)); + } + + /** + * Read a text file and findAll its content. + * + * @param aFileReader File reader + * @return string with text file content + */ + public static String read(final InputStreamReader aFileReader) { + StringBuilder theContent = new StringBuilder(); + + try (BufferedReader reader = new BufferedReader(aFileReader)) { + + // Browse lines of file + String theCurrentLine = reader.readLine(); + while (theCurrentLine != null) { + theContent.append(theCurrentLine); + theContent.append(StringHelper.LINE_FEED); + theCurrentLine = reader.readLine(); + + } + } catch (IOException e) { + log.error("Unable to read file", e); + } finally { + try { + if (aFileReader != null) { + aFileReader.close(); + } + } catch (IOException e) { + log.error("Unable to close the file", e); + } + } + + // Return lines list + return theContent.toString(); + } + + /** + * Instantiate an input stream from a specific input file path. + * + * @param aSourceFilePath File path of the stream + * @return Created instance of InputStreamReader + **/ + private static InputStreamReader getStream(final String aSourceFilePath) { + InputStreamReader theFileReader = null; + try (FileInputStream theInputStream = new FileInputStream(aSourceFilePath)) { + // Do not use FileReader it use default encoding of platform + theFileReader = new InputStreamReader(theInputStream, getDefaultCharset()); + } catch (IOException e) { + log.error("Unable to access file: " + aSourceFilePath, e); + } + // Do not close theFileReader stream, it should be closed later by calling method + + return theFileReader; + } + + /** + * Deletes all the files in a folder that have been modified before the provided date. + * + * @param files a {@link List} of {@link File}s + * @return a list of all the deleted files' names + */ + public static List deleteFiles(final List files) { + List deletedFileNames = new ArrayList<>(); + for (File file : files) { + if (file.isFile()) { + final String fileName = file.getName(); + if (file.delete()) { + log.info("Le fichier [{}] a été supprimé ", fileName); + deletedFileNames.add(fileName); + } else { + log.warn("Le fichier [{}] n'a pas pu être supprimé ", fileName); + } + } + } + return deletedFileNames; + } + + /** + * Lists all the {@link File}s in a folder that have been modified before the provided date. + * + * @param folder the flder + * @param deadline the deadline + * @return a list of all the {@link File}s + */ + public static List listFilesBefore(final File folder, final Calendar deadline) { + List listing = new ArrayList<>(); + for (File file : folder.listFiles()) { + if (file.isFile()) { + Calendar fileMod = Calendar.getInstance(); + final long lastModified = file.lastModified(); + fileMod.setTime(new Date(lastModified)); + if (fileMod.before(deadline)) { + listing.add(file); + } + } + } + return listing; + } + + /** + * Copy an original file to a target location. + * + * @param original the original {@link File} + * @param target the target {@link File} + * @throws NotFoundException if the original does not exist or similar kind of I/O error occurs + */ + public static void copy(final File original, final File target) throws NotFoundException { + try { + Files.copy(original, target); + } catch (IOException e) { + throw new NotFoundException("Unable to copy the file from " + original.toString() + " to " + target.toString(), e); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/FileTemplate.java b/kurt-utility/src/main/java/com/capgemini/framework/common/FileTemplate.java new file mode 100644 index 0000000..c18deea --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/FileTemplate.java @@ -0,0 +1,137 @@ +package com.capgemini.framework.common; + +import com.capgemini.reports.exceptions.FileLoadingException; +import lombok.extern.slf4j.Slf4j; + +import java.util.HashMap; +import java.util.Map; + +/** + * Class managing substitutions of certain tags found in a template file. + **/ +@Slf4j +public class FileTemplate { + + /** + * Starting separator for query parameter. + **/ + private static final String PARAM_START = "[["; + + /** + * Ending separator for query parameter. + **/ + private static final String PARAM_END = "]]"; + + /** + * Mapping between tags and their values. + **/ + private Map tagValues = new HashMap<>(); + + /** + * Template file path. + **/ + private String templateFilePath; + + /** + * Template content. + **/ + private String templateContent; + + /** + * Default empty constructor. + **/ + protected FileTemplate() { + // Nothing to do + } + + /** + * Compute a tag from its name. + * + * @param aTagName Name of the tag + * @return Name encapsulated by starting and ending markers + **/ + private static String getTag(final String aTagName) { + return PARAM_START + aTagName + PARAM_END; + } + + /** + * Generate file content for a specific class. + * + * @return Template code + **/ + public String generateCode() { + // Check if template is correctly initialized + if (templateContent == null) { + log.error("Unable to generate the code, the template content is empty"); + return null; + } + + String theFinalContent = templateContent; + + // Replace template tags + for (String theCurrentTag : tagValues.keySet()) { + // Get next tag value + String currentTagValue = tagValues.get(theCurrentTag); + + // Check if tag value is set properly + if (currentTagValue == null) { + log.warn("Tag value is null for " + theCurrentTag); + } else { + // Replace current tag with its value + theFinalContent = theFinalContent.replace(getTag(theCurrentTag), currentTagValue); + } + } + + // Check content after tag replacement and display a warning if there is a missing tag value + isMissingTag(theFinalContent); + return theFinalContent; + } + + /** + * Add a new parameter. + * + * @param aTagName Parameter name + * @param aReplacedValue Parameter value + */ + protected void setTagValue(final String aTagName, final String aReplacedValue) { + tagValues.put(aTagName, aReplacedValue); + } + + /** + * Check if there is a remaining tag value which has not been replaced. + * + * @param aTemplateContent Template code + * @return True when a missing tag has been detected + **/ + private boolean isMissingTag(final String aTemplateContent) { + boolean isMissing = false; + int theStartPos = aTemplateContent.indexOf(PARAM_START); + int theEndPos = aTemplateContent.indexOf(PARAM_END); + if ((theStartPos >= 0) && (theEndPos > 0)) { + String theTagName = aTemplateContent.substring(theStartPos + PARAM_START.length(), theEndPos); + log.warn("Tag value is missing for {} in file {}", theTagName, templateFilePath); + isMissing = true; + } + return isMissing; + } + + /** + * Setter for template file. + * + * @param aTemplateFilePath Template file path + **/ + protected final void setTemplateFilePath(final String aTemplateFilePath) { + templateFilePath = aTemplateFilePath; + if (templateFilePath != null) { + try { + templateContent = ResourceHelper.getResourceContent(aTemplateFilePath); + } catch (FileLoadingException e) { + log.error("Unable to initialize template, the required file at: " + templateFilePath + " is missing", e); + } + } + } + + protected final void setTemplateContent(final String content) { + this.templateContent = content; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/FolderHelper.java b/kurt-utility/src/main/java/com/capgemini/framework/common/FolderHelper.java new file mode 100644 index 0000000..f7a93e0 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/FolderHelper.java @@ -0,0 +1,112 @@ +package com.capgemini.framework.common; + +import lombok.extern.slf4j.Slf4j; + +import java.io.File; + +/** Class for folder management. **/ +@Slf4j +public final class FolderHelper { + + /** Constructor. **/ + private FolderHelper() { + // Constructor of helper classes must be private + } + + /** + * Check directory existence. + * + * @param aDirPath Directory which must be checked + * @return True when the file exists + */ + private static boolean dirExist(final String aDirPath) { + return dirExist(aDirPath, true); + } + + /** + * Check directory existence with logger option. + * + * @param isVerbose True for verbose mode, else the silent mode is used + * @param aDirPath Directory which must be checked + * @return True when the file exists + */ + private static boolean dirExist(final String aDirPath, final boolean isVerbose) { + + boolean status = true; + + if (aDirPath == null) { + if (isVerbose) { + log.debug("Directory name is null"); + } + return false; + } + + File theDir = new File(aDirPath); + if (!theDir.exists() || theDir.isFile()) { + if (isVerbose) { + log.debug("Directory does not exist: " + theDir.getAbsolutePath()); + } + status = false; + } + + return status; + } + + /** + * Delete all files and sub-directories from a directory. + * + * @param aDirectoryPath Path of the directory + * @return True if delete operation is successful + */ + public static boolean delete(final String aDirectoryPath) { + + boolean isSuccess = true; + + /* Check if folder has not been already deleted */ + if (dirExist(aDirectoryPath)) { + + File theMainDirectory = new File(aDirectoryPath); + + String[] theFileEntries = theMainDirectory.list(); + for (String currentFileEntry : theFileEntries) { + File currentFile = new File(theMainDirectory.getPath(), currentFileEntry); + if (currentFile.isDirectory()) { + isSuccess = isSuccess && delete(currentFile.getPath()); + isSuccess = isSuccess && currentFile.delete(); + } + else { + isSuccess = isSuccess && currentFile.delete(); + } + } + } + + return isSuccess; + } + + /** + * Create all directories if needed, return true when they already exist. + * + * @param aDirectory path for created directory + * @return false when create operation has failed + */ + public static boolean mkdir(final File aDirectory) { + + boolean status = true; + + if (!aDirectory.isDirectory()) { + + /* Recursive creation if needed */ + File theParentDirectory = aDirectory.getParentFile(); + if ((theParentDirectory != null) && !theParentDirectory.isDirectory()) { + status = mkdir(theParentDirectory); + } + + status &= aDirectory.mkdirs(); + if (!status) { + log.error("Unable to create parent directory: " + aDirectory.getAbsolutePath()); + } + } + + return status; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/HashMapComparingStringIDs.java b/kurt-utility/src/main/java/com/capgemini/framework/common/HashMapComparingStringIDs.java new file mode 100644 index 0000000..32af60d --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/HashMapComparingStringIDs.java @@ -0,0 +1,226 @@ +package com.capgemini.framework.common; + +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.util.*; + +/** + * This class is a {@link Map} which authorizes a weak object comparison, that is provided by an {@link IdMaker} object.
+ * This class allows you to bypass your key's implementation of equals(Object), and make it change according to your needs. + *

+ * You can for instance keep your key object's compare method as a comparator of all the key's relevant fields (Item id + item rev + uid +...), but by providing this map with an IdMaker which uses only the item id, two objects with differing revisions but same item id will be considered the same + * (the map will have unique Items as Keys, not unique ItemRevisions as keys). + * + * @param this Map's Keys type + * @param This Map's Values type + */ +@Slf4j +public class HashMapComparingStringIDs, V> implements Map, Serializable { + + private static final String VALUE_IS_NOT_OF_THE_CORRECT_TYPE = "Value is not of the correct type"; + private static final String KEY_IS_NOT_OF_THE_CORRECT_TYPE = "Key is not of the correct type"; + + private static final long serialVersionUID = 3826358508367637107L; + + private final HashMap stringToKey = new HashMap<>(); + private final HashMap stringToValue = new HashMap<>(); + private final Class keyClass; + private final Class valueClass; + private final IdMaker idMaker; + + /** + * This interface provides a way to make a unique identifier for a Key, to be used in the {@link HashMapComparingStringIDs}. + * + * @param the Keys type + */ + public interface IdMaker extends Serializable { + + /** + * Provides a unique {@link String} identifier for any key. + * + * @param key the key for which this class should make an identifier. + * @return the identifier String + */ + String makeId(final K key); + } + + /** + * Creates an instance of this HashMap. + * + * @param idMaker this object will be use to identify any incoming key.
+ * If two different Keys produce the same Identifier through this IdMaker, the keys will be considered equal. This way, the key's own eqauls method is bypassed. + * @param keyClass the common class instance of all the Key. + * @param valueClass the common class instance of all the Values. + */ + public HashMapComparingStringIDs(final IdMaker idMaker, final Class keyClass, final Class valueClass) { + this.keyClass = keyClass; + this.valueClass = valueClass; + this.idMaker = idMaker; + } + + @Override + public boolean isEmpty() { + return stringToKey.isEmpty(); + } + + @Override + public int size() { + return stringToKey.size(); + } + + @Override + public boolean containsKey(final Object key) { + if (isEmpty()) { + return false; + } + try { + K aKey = keyClass.cast(key); + String strKey = idMaker.makeId(aKey); + return stringToKey.containsKey(strKey); + } catch (ClassCastException e) { + log.trace(KEY_IS_NOT_OF_THE_CORRECT_TYPE, e); + return false; // wrong type + } + } + + @Override + public boolean containsValue(final Object value) { + if (isEmpty()) { + return false; + } + try { + V aValue = valueClass.cast(value); + return stringToValue.containsValue(aValue); + } catch (ClassCastException e) { + log.trace(VALUE_IS_NOT_OF_THE_CORRECT_TYPE, e); + return false; // wrong type + } + } + + @Override + public V get(final Object key) { + if (isEmpty()) { + return null; + } + try { + K aKey = keyClass.cast(key); + String strKey = idMaker.makeId(aKey); + return stringToValue.get(strKey); + } catch (ClassCastException e) { + log.trace(KEY_IS_NOT_OF_THE_CORRECT_TYPE, e); + return null; // wrong type + } + } + + @Override + public V put(final K key, final V value) { + String identifier = idMaker.makeId(key); + if (containsKey(key)) { + return stringToValue.put(identifier, value); + } else { + stringToKey.put(identifier, key); + stringToValue.put(identifier, value); + return null; + } + } + + @Override + public V remove(final Object key) { + if (isEmpty()) { + return null; + } + try { + if (containsKey(key)) { + K aKey = keyClass.cast(key); + String identifier = idMaker.makeId(aKey); + stringToKey.remove(identifier); + return stringToValue.remove(identifier); + } + } catch (ClassCastException e) { + log.trace(KEY_IS_NOT_OF_THE_CORRECT_TYPE, e); + } + return null; // Not found or ClassCastException + } + + @Override + public void putAll(final Map map) { + for (Entry entry : map.entrySet()) { + String identifier = idMaker.makeId(entry.getKey()); + K key = entry.getKey(); + stringToKey.put(identifier, key); + stringToValue.put(identifier, entry.getValue()); + } + } + + @Override + public void clear() { + stringToKey.clear(); + stringToValue.clear(); + } + + @Override + public Set keySet() { + return new TreeSet<>(stringToKey.values()); // This set is also sorted + } + + @Override + public Collection values() { + return stringToValue.values(); + } + + @Override + public Set> entrySet() { // This set is also sorted + Set> entrySet = new TreeSet<>(); + for (Entry keyEntry : stringToKey.entrySet()) { + K key = keyEntry.getValue(); + String identifier = keyEntry.getKey(); + V value = stringToValue.get(identifier); + entrySet.add(new MyEntry(key, value, identifier, this)); + } + return entrySet; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder("{"); + for (Entry entry : entrySet()) { + builder.append(entry.getKey()).append(':').append(entry.getValue()).append(", "); + } + return builder.append("}").toString(); + } + + private class MyEntry implements Entry, Comparable { + private final K key; + private final V value; + private final String identifier; + private final HashMapComparingStringIDs theBackingMap; + + protected MyEntry(final K key, final V value, final String identifier, final HashMapComparingStringIDs theBackingMap) { + this.key = key; + this.value = value; + this.identifier = identifier; + this.theBackingMap = theBackingMap; + } + + @Override + public K getKey() { + return key; + } + + @Override + public V getValue() { + return value; + } + + @Override + public V setValue(final V value) { + return theBackingMap.stringToValue.put(identifier, value); + } + + @Override + public int compareTo(final MyEntry other) { + return key.compareTo(other.getKey()); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/MailHelper.java b/kurt-utility/src/main/java/com/capgemini/framework/common/MailHelper.java new file mode 100644 index 0000000..da020ed --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/MailHelper.java @@ -0,0 +1,156 @@ +package com.capgemini.framework.common; + +import lombok.extern.slf4j.Slf4j; + +import javax.mail.*; +import javax.mail.internet.AddressException; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; +import java.util.List; +import java.util.Properties; + +/** + * Utility class for sending email. + **/ +@Slf4j +public final class MailHelper { + /** + * Default email destinator for administration messages. + **/ + public static final List DEFAULT_DESTINATORS = SettingsHelper.getDefaultDestinatorEmail(); + private static final String MAIL_SMTP_PASSWORD = "mail.smtp.password"; + private static final String MAIL_SMTP_USER = "mail.smtp.user"; + private static final String MAIL_SMTP_AUTH = "mail.smtp.auth"; + private static final String MAIL_TRANSPORT_PROTOCOL = "mail.transport.protocol"; + private static final String MAIL_SMTP_SSL_TRUST = "mail.smtp.ssl.trust"; + private static final String MAIL_SMTP_PORT = "mail.smtp.port"; + private static final String MAIL_SMTP_HOST = "mail.smtp.host"; + private static final String MAIL_SMTP_ENABLE_STARTTLS = "mail.smtp.starttls.enable"; + private static final String FALSE = "false"; + private static final String TRUE = "true"; + // Standard connection settings + private static final String DEFAULT_MAIL_USER = SettingsHelper.getDefaultExpeditorMailUsername(); + private static final String DEFAULT_MAIL_PASS = SettingsHelper.getDefaultExpeditorMailPassword(); + private static final String DEFAULT_SMTP_HOST = SettingsHelper.getDefaultSmtpHost(); + private static final String DEFAULT_SMTP_PORT = SettingsHelper.getDefaultSmtpPort(); + + /** + * Private constructor. + **/ + private MailHelper() { + // Hide constructor of utility classes + } + + /** + * Method sending email from the default sender. + * + * @param aDestinatorMail Email of the destinator + * @param aSubject Text content for the email subject + * @param aContent Text for the email content + **/ + public static void send(final String aDestinatorMail, final String aSubject, final String aContent) { + log.debug("Sending an email to user " + aDestinatorMail); + + // Check argument + if (aDestinatorMail.isEmpty()) { + log.warn("The mail destinator is empty, no message will be sent"); + return; + } + + // Define JAVAX required properties + Properties props = setupMailProperties(); + + // For some specific servers, the authenticator should be set too + Authenticator auth = new MailAuthenticator(); + + // Set session + Session theJavaxSession = Session.getInstance(props, auth); + Transport transport = null; + try { + // Format email message + MimeMessage message = new MimeMessage(theJavaxSession); + message.setFrom(new InternetAddress(DEFAULT_MAIL_USER)); + message.addRecipient(Message.RecipientType.TO, new InternetAddress(aDestinatorMail)); + message.setSubject(aSubject); + message.setContent(aContent, "text/html"); + message.saveChanges(); + + // Set connection to SMTP server + if (isAuthenticationMode()) { + transport = theJavaxSession.getTransport("smtp"); + transport.connect(DEFAULT_SMTP_HOST, DEFAULT_MAIL_USER, DEFAULT_MAIL_PASS); + transport.sendMessage(message, message.getAllRecipients()); + } + else { + Transport.send(message); + } + + // When no error occurred at this point, the email has been sent properly + log.debug("Mail sent to: {}", aDestinatorMail); + } + catch (AddressException e) { + log.error("Unable to send email one of email adresses is invalid: " + DEFAULT_MAIL_USER + " or " + aDestinatorMail, e); + } + catch (MessagingException e) { + log.error("Unable to send email", e); + } + finally { + if (transport != null) { + try { + transport.close(); + } + catch (MessagingException e) { + log.error("Unable to close transport connection", e); + } + } + } + } + + /** + * Method for batch-sending an email to several destinators. + * + * @param destinators List containing the Email of all the destinators + * @param aSubject Text content for the email subject + * @param aContent Text for the email content + **/ + public static void sendAll(final List destinators, final String aSubject, final String aContent) { + for (String destinator : destinators) { + MailHelper.send(destinator, aSubject, aContent); + } + } + + private static Properties setupMailProperties() { + Properties props = new Properties(); + props.put(MAIL_SMTP_ENABLE_STARTTLS, TRUE); + props.put(MAIL_SMTP_HOST, DEFAULT_SMTP_HOST); + props.put(MAIL_SMTP_PORT, DEFAULT_SMTP_PORT); + props.put(MAIL_SMTP_SSL_TRUST, DEFAULT_SMTP_HOST); + props.put(MAIL_TRANSPORT_PROTOCOL, "smtp"); + + if (isAuthenticationMode()) { + props.put(MAIL_SMTP_AUTH, TRUE); + props.put(MAIL_SMTP_USER, DEFAULT_MAIL_USER); + props.put(MAIL_SMTP_PASSWORD, DEFAULT_MAIL_PASS); + } + else { + props.put(MAIL_SMTP_AUTH, FALSE); + } + return props; + } + + /** + * Check a user and a password are defined for the SMTP connection. + * + * @return True when the user should be authenticated + */ + private static boolean isAuthenticationMode() { + return !DEFAULT_MAIL_USER.isEmpty() && !DEFAULT_MAIL_PASS.isEmpty(); + } + + private static final class MailAuthenticator extends Authenticator { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(DEFAULT_MAIL_USER, DEFAULT_MAIL_PASS); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/MapHelper.java b/kurt-utility/src/main/java/com/capgemini/framework/common/MapHelper.java new file mode 100644 index 0000000..98c5287 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/MapHelper.java @@ -0,0 +1,55 @@ +package com.capgemini.framework.common; + +import java.util.*; + +/** + * Utility class for Maps. + **/ +public final class MapHelper { + + /** + * Constructor. + **/ + private MapHelper() { + // Constructor of helper classes must be private + } + + /** + * String displaying of a Map. + * + * @param aMap Map which should be displayed + * @return String representation of the map + **/ + public static String toString(final Map aMap) { + + StringBuilder theStringBuilder = new StringBuilder(); + + // Get map key values and sort them + Set theKeySet = aMap.keySet(); + List theSortedSet = sortSet(theKeySet); + + // Browse sorted values + for (String currentKey : theSortedSet) { + theStringBuilder.append(currentKey).append('=').append(aMap.get(currentKey)).append(StringHelper.LINE_FEED); + } + + return theStringBuilder.toString(); + } + + /** + * Sort a set of strings. + * + * @param aValuesSet Set to sort + * @return sorted list + */ + private static List sortSet(final Set aValuesSet) { + + String[] stArray = aValuesSet.toArray(new String[aValuesSet.size()]); + + // Convert array of elements to sort to a list + List sortedList = Arrays.asList(stArray); + + Collections.sort(sortedList); + return sortedList; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/MemoryHelper.java b/kurt-utility/src/main/java/com/capgemini/framework/common/MemoryHelper.java new file mode 100644 index 0000000..a2a2c8b --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/MemoryHelper.java @@ -0,0 +1,75 @@ +package com.capgemini.framework.common; + +import com.capgemini.reports.database.manager.MngMemMonitor; + +import java.math.BigDecimal; + +/** + * Utility class for memory monitoring. + **/ +public final class MemoryHelper { + + private static final double TO_PERCENT = 100D; + private static final double BYTES_TO_MB = 1024D * 1024D; + + private MemoryHelper() { + // Makes this class static + } + + /** + * Log debug message when memory monitoring is enabled. + * + * @return Memory message state + **/ + public static String monitorMemory() { + Double theTotalMemory = formatByte(Runtime.getRuntime().totalMemory()); + Double theMaxMemory = formatByte(Runtime.getRuntime().maxMemory()); + Double theFreeMemory = getFreeMemory(); + + Double theUsedMemory = floor(theMaxMemory - theFreeMemory, 1); + Double theMaxPercent = floor(theUsedMemory / theMaxMemory, 1) * TO_PERCENT; + + /* Persist current memory state. */ + MngMemMonitor theMemMonitorManager = new MngMemMonitor(); + theMemMonitorManager.insert(theFreeMemory, theUsedMemory, theMaxMemory, theMaxPercent, theTotalMemory); + return "Mémoire consommée : " + theUsedMemory + " (" + theMaxPercent + "% max)
Allouée : " + theTotalMemory + + " / Capacité maximale : " + theMaxMemory; + } + + /** + * Get the available memory amount by MBytes. + **/ + private static Double getFreeMemory() { + + /* Get the available memory in allocated space */ + Double freeMemory = floor(Runtime.getRuntime().freeMemory() / BYTES_TO_MB, 1); + + /* Add complementary memory which could be allocated (when XMS is different than XMX) */ + freeMemory += floor((Runtime.getRuntime().maxMemory() - Runtime.getRuntime().totalMemory()) / BYTES_TO_MB, 1); + + return freeMemory; + } + + /** + * Format memory value from Bytes to MegaBytes. + * + * @param aValue with Mbs + * @return Formated value + */ + private static Double formatByte(final double aValue) { + return floor(aValue / BYTES_TO_MB, 0); + } + + /** + * Round numeric value to lower value. + * + * @param aValue Converted value. + * @param aScale Preserved values. + * @return Round value. + */ + private static double floor(final double aValue, final int aScale) { + BigDecimal bigD = BigDecimal.valueOf(aValue); + BigDecimal bigD2 = bigD.setScale(aScale, BigDecimal.ROUND_DOWN); + return bigD2.doubleValue(); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/QuartzHelper.java b/kurt-utility/src/main/java/com/capgemini/framework/common/QuartzHelper.java new file mode 100644 index 0000000..2f153f7 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/QuartzHelper.java @@ -0,0 +1,45 @@ +package com.capgemini.framework.common; + +import lombok.EqualsAndHashCode; + +/** Static class managing all properties from quartz.properties file. **/ +@EqualsAndHashCode(callSuper = true) +public class QuartzHelper extends AbstractPropertiesManager { + + /** Singleton instance. **/ + private static QuartzHelper instance; + + /** Prefix that should be appended at the beginning of all properties. **/ + private static final String PROP_PREFIX = "org.quartz."; + + /** Constructor : load the properties from the property file. **/ + private QuartzHelper() { + super("/quartz.properties"); + } + + /** @return the instance. **/ + public static synchronized QuartzHelper getInstance() { + if (instance == null) { + instance = new QuartzHelper(); + } + return instance; + } + + @Override + protected String getPropPrefix() { + return PROP_PREFIX; + } + + /** + * Get the file path of the quartz.properties file. + * + * @return string value of the file path + */ + public static String getPropertiesFilePath() { + return getInstance().getPropertiesFilePathImpl(); + } + + private String getPropertiesFilePathImpl() { + return propertyFilePath; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/ReportFolderOutputHelper.java b/kurt-utility/src/main/java/com/capgemini/framework/common/ReportFolderOutputHelper.java new file mode 100644 index 0000000..cf8a44e --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/ReportFolderOutputHelper.java @@ -0,0 +1,117 @@ +package com.capgemini.framework.common; + +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.manager.MngReport; +import com.capgemini.reports.exceptions.NotFoundException; +import org.apache.commons.io.FileUtils; +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +/** + * Helper used for returning the appropriate location of folder. + */ +public final class ReportFolderOutputHelper { + + /** + * The default location of the folder which contains all the IMMEDIATE or DELAYED reports.
+ * This value is loaded in the reporting.properties file. + */ + private static final String DEFAULT_LOCATION_OUTPUT = SettingsHelper.getReportLocation(); + /** + * The specific location of the folder which contains the recent scheduled reports.
+ * This value is loaded in the reporting.properties file. + */ + public static final String SCHEDULING_LOCATION_OUTPUT = SettingsHelper.getSchedulingLocation(); + /** + * The specific location of a specific folder which have to record all the scheduled reports.
+ * This value is loaded in the reporting.properties file. + */ + private static final String SCHEDULING_HISTORY_LOCATION_OUTPUT = SettingsHelper.getSchedulingHistoryLocation(); + + /** + * Private constructor. + **/ + private ReportFolderOutputHelper() { + // Hide constructor of utility classes + } + + /** + * Return the appropriate location of folder associated to the report.
+ * The main purpose is to separate scheduled reports's folder with the other folder. + * + * @param launchType {@link ReportLaunchTypeEnum} - the launch type of a report + * @return the String location of folder + */ + public static String getStorageFolderLocation(final ReportLaunchTypeEnum launchType) { + if (ReportLaunchTypeEnum.SCHEDULED.equals(launchType)) { + return SCHEDULING_LOCATION_OUTPUT; + } + else { + return DEFAULT_LOCATION_OUTPUT; + } + } + + /** + * Check if the report has already been launched before in database. + * + * @param schedulingId Long - the ID of the scheduled report + * @return true if the report has already been launched before, else false. + */ + public static boolean checkIfAlreadyLaunched(final Long schedulingId) { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + List schedulingReports = new MngReport().searchBySchedulingId(schedulingId, session); + return schedulingReports != null && schedulingReports.size() > 1; // At least two entries + } + finally { + session.close(); + } + } + + /** + * Delete a specific scheduled report in the scheduled output. + * + * @param reportFileName String - the name of the file to delete + * @throws NotFoundException if unable to delete the file + */ + public static void deleteScheduledReportFile(final String reportFileName) throws NotFoundException { + deleteFile(SCHEDULING_LOCATION_OUTPUT, reportFileName); + } + + /** + * Delete a report from his file name in the entry folder location. + * + * @param folderLocation String - the folder location + * @param reportFileName String - the name of the file to delete + * @throws NotFoundException if unable to delete the file + */ + private static void deleteFile(final String folderLocation, final String reportFileName) throws NotFoundException { + File fileToDelete = new File(folderLocation + reportFileName); + + // Try to delete the file and return true if it is done + if (!fileToDelete.delete()) { + throw new NotFoundException("Unable to delete the file " + reportFileName + " in folder " + folderLocation); + } + } + + /** + * Copy a generated scheduled report in the archive folder.
+ * This scheduled report should have be printed before and should be located in the scheduled output. + * + * @param original the file to copy + * @param reportFileName String - the name of the report + * @throws IOException may occur if the copy or the creation of the file doesn't work + */ + public static void copyToHistoryFolder(File original, final String reportFileName) throws IOException { + File archive = new File(SCHEDULING_HISTORY_LOCATION_OUTPUT + reportFileName); + FileUtils.copyFile(original, archive); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/ResourceHelper.java b/kurt-utility/src/main/java/com/capgemini/framework/common/ResourceHelper.java new file mode 100644 index 0000000..ab7fc27 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/ResourceHelper.java @@ -0,0 +1,134 @@ +package com.capgemini.framework.common; + +import com.capgemini.reports.exceptions.FileLoadingException; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; + +/** Helper clas which can load resource files in various forms. */ +@Slf4j +public final class ResourceHelper { + + /** + * 4 double-dots: starting at src / main / resources / com / capgemini/ framework / common.
+ * After that, the Resource Loader will be at the root of src/main/resources + */ + private static final String PATH_TO_SRC_MAIN_RESOURCES = "../../../.."; + + /** Private constructor to make the class "static". */ + private ResourceHelper() { + + } + + /** + * Returns a URL to a resource in src/main/resources/*ABSOLUTEPATH*. + * + * @param absolutePath the path with the src/main/resources + * @return the {@link URL} + * @throws FileLoadingException if the file could not be loaded + */ + private static URL getResourceAsURL(final String absolutePath) throws FileLoadingException { + URL resource = ResourceHelper.class.getResource(PATH_TO_SRC_MAIN_RESOURCES + absolutePath); + if (resource == null) { + throw new FileLoadingException("Could not find file at : " + absolutePath); + } + return resource; + } + + /** + * Returns the {@link InputStream} for a resource in src/main/resources/*ABSOLUTEPATH*. + * + * @param absolutePath the path with the src/main/resources + * @return the {@link InputStream} + * @throws FileLoadingException if the file could not be loaded + */ + public static InputStream getResourceAsStream(final String absolutePath) throws FileLoadingException { + InputStream resourceAsStream = ResourceHelper.class.getResourceAsStream(PATH_TO_SRC_MAIN_RESOURCES + absolutePath); + if (resourceAsStream == null) { + throw new FileLoadingException("Could not load InputStream : " + absolutePath); + } + return resourceAsStream; + } + + /** + * Returns a {@link URI} to a resource in src/main/resources/*ABSOLUTEPATH*. + * + * @param absolutePath the path with the src/main/resources + * @return the {@link URI} + * @throws FileLoadingException thrown when the file could not be read. + */ + private static URI getResourceAsURI(final String absolutePath) throws FileLoadingException { + try { + return getResourceAsURL(absolutePath).toURI(); + } catch (URISyntaxException e) { + throw new FileLoadingException("Could not load URI " + absolutePath, e); + } + } + + /** + * Returns a {@link File} linking to a resource in src/main/resources/*ABSOLUTEPATH*. + * + * @param absolutePath the path with the src/main/resources + * @return the {@link File} + * @throws FileLoadingException thrown when the file could not be read. + */ + public static File getResourceAsFile(final String absolutePath) throws FileLoadingException { + return new File(getResourceAsURI(absolutePath)); + + } + + /** + * Returns a String with the full content of a resource in src/main/resources/*ABSOLUTEPATH*. + * + * @param absolutePath the path with the src/main/resources + * @return the content + * @throws FileLoadingException if the file could not be loaded + */ + public static String getResourceContent(final String absolutePath) throws FileLoadingException { + try (InputStream stream = getResourceAsStream(absolutePath); InputStreamReader reader = new InputStreamReader(stream)) { + return FileHelper.read(reader); + } catch (IOException e) { + throw new FileLoadingException("Something happened while trying to close a reader to " + absolutePath, e); + } + } + + /** + * Returns an image ({@link BufferedImage}) located in resource in src/main/resources/*IMAGEPATH*. + * + * @param imagePath the path with the src/main/resources + * @return the content + * @throws FileLoadingException if the file could not be loaded + */ + public static BufferedImage loadImage(final String imagePath) throws FileLoadingException { + try (InputStream imageStream = ResourceHelper.getResourceAsStream(imagePath)) { + return readImage(imageStream); + } catch (IOException e) { + throw new FileLoadingException("Could not close an image resource properly", e); + } + } + + /** + * Reads the content of a Stream, expecting an image and generating a {@link BufferedImage}.
+ * This does NOT close the inputStream, it is the responsibility of the caller to perform the close. + * + * @param imageStream + * @return the {@link BufferedImage} + * @throws FileLoadingException if the stream could not be read as an image + */ + private static BufferedImage readImage(final InputStream imageStream) throws FileLoadingException { + try { + return ImageIO.read(imageStream); + } catch (IOException e) { + throw new FileLoadingException("Unable to read InputStream into an image", e); + } + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/SerializationHelper.java b/kurt-utility/src/main/java/com/capgemini/framework/common/SerializationHelper.java new file mode 100644 index 0000000..a7a792d --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/SerializationHelper.java @@ -0,0 +1,53 @@ +package com.capgemini.framework.common; + +import lombok.extern.slf4j.Slf4j; + +import java.io.*; + +/** Serialization of a BOMLineHolder tree for tests. */ +@Slf4j +public final class SerializationHelper { + + private SerializationHelper() { + // Nothing to do! + } + + /** + * Serialize an Object.
+ * + * @param object Object the object to serialize. + * @param filePath String the chosen file path, starting from the root of the project (explicitly needs src/main/resource/etc) + * + * @throws FileNotFoundException if the provided file path does not point to a readable file (or it may not exist) + * @throws IOException if the file read fails, or the serialization fails + */ + public static void serialize(final Object object, final String filePath) throws IOException { + // Opening of a Stream on a file + File file = new File(filePath); + try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))) { + // Serialization of the object + oos.writeObject(object); + log.info("File written at: " + file.getCanonicalPath()); + } + } + + /** + * Deserialize an {@link Object}. + * + * @param filePath String the file path, starting from the root of the project (explicitly needs src/main/resource/etc) + * @return the serialized object + * + * @throws FileNotFoundException if the provided file path does not point to a readable file (or it may not exist) + * @throws IOException if the file read fails or deserialization fails + * @throws ClassNotFoundException if the class of the object is no longer found/available/compatible + */ + public static Object deserialize(final String filePath) throws IOException, ClassNotFoundException { + File file = new File(filePath); + Object obj; + try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) { // Opening of the flows on a file + // Deserialization of the object + obj = ois.readObject(); + return obj; + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/SettingsHelper.java b/kurt-utility/src/main/java/com/capgemini/framework/common/SettingsHelper.java new file mode 100644 index 0000000..ac121d5 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/SettingsHelper.java @@ -0,0 +1,577 @@ +package com.capgemini.framework.common; + +import com.capgemini.framework.common.security.AesEncoded; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.ReportEnum; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.TreeMap; + +/** + * Static class managing all properties from reporting.properties file. + **/ +@EqualsAndHashCode(callSuper = true) +@Slf4j +public final class SettingsHelper extends AbstractPropertiesManager { + + + /** + * Domain name (e.g. snecma.local). + */ + private static final String KEY_DOMAIN_NAME = "authent.domain"; + /** + * Prefix that should be appended at the beginning of all properties. + **/ + private static final String PROP_PREFIX = "com.capgemini.report."; + // Global modes + private static final String KEY_CLEANUP = "report.cleanup"; + private static final String KEY_DEV_MODE = "devmode"; + private static final String KEY_VAL_MODE = "valmode"; + // Memory monitor + private static final String KEY_MEM_MAX_MONITOR_TRACE_COUNT = "MngMemMonitor.maxTraceCount"; + private static final String KEY_MEM_FREQUENCY = "MngMemMonitor.frequency"; + // Email + private static final String KEY_DEFAULT_DESTINATOR_EMAIL = "common.MailHelper.defaultDestinatorMail"; + private static final String KEY_DEFAULT_MAIL_USER = "common.MailHelper.defaultExpeditorMail"; + private static final String KEY_DEFAULT_MAIL_PASS = "common.MailHelper.defaultExpeditorPassword"; + private static final String KEY_DEFAULT_SMTP_HOST = "common.MailHelper.defaultSmtpHost"; + private static final String KEY_DEFAULT_SMTP_PORT = "common.MailHelper.defaultSmtpPort"; + // File retrieval + private static final String KEY_DOWNLOAD_URL = "download.URL"; + // JSP Presentation + private static final String KEY_JSP_PAGING = "jsp.defaultPaging"; + // Purge + private static final String KEY_PURGE_DELAY_REPORTS = "nb.days"; + private static final String KEY_PURGE_DELAY_SCHEDULING = "nb.days.scheduling"; + // Launch times + private static final String KEY_PURGE_HOUR = "common.launch.purge.hour"; + private static final String KEY_DELAYED_LAUNCH_HOUR = "common.launch.delayed.hour"; + private static final String KEY_DEFAULT_LAUNCH_TYPE = "common.launch.launchType.default"; + // Scheduling save location + private static final String KEY_OUTPUT_FOLDER_REPORT = "location.default.output"; + private static final String KEY_OUTPUT_FOLDER_SCHEDULING = "location.scheduling.output"; + private static final String KEY_OUTPUT_FOLDER_SCHEDULING_HISTORY = "location.scheduling.history.output"; + // Functional values + private static final String KEY_PRODUCT_LIST = "product.list"; + private static final String KEY_DEFAULT_REVISION_RULE = "common.bom.revisionRule.default"; + private static final String KEY_PREFIX_REPORT_TITLE = "title."; + private static final String KEY_TECH_LOGIN = "authent.tech.login"; + private static final String KEY_TECH_PASSWORD = "authent.tech.password"; + /** + * Provider URL+port. Ex: "LDAP://snecmadc.snecma.local:389/". + */ + private static final String KEY_PROVIDER_URL = "authent.provider.url"; + private static final String KEY_PROVIDER_PORT = "authent.provider.port"; + /** + * Organisational unit for user OU. e.g. 'OU=TechnicalAccounts'. + */ + private static final String KEY_MAIL_ATTRIBUTE = "authent.user.attributes.email"; + private static final String KEY_LOGIN_ATTRIBUTE = "authent.user.attributes.login"; + private static final String KEY_FIRST_NAME_ATTRIBUTE = "authent.user.attributes.firstName"; + private static final String KEY_LAST_NAME_ATTRIBUTE = "authent.user.attributes.lastname"; + // ACTIVE DIRECTORY : Admin data + private static final String KEY_ADMIN_GROUP = "authent.admin.group"; + private static final String KEY_ADMIN_ORGANISATIONAL_UNIT = "authent.admin.organisationalunit"; + + private static final String KEY_OPTIMIZED_FOLDER_R23 = "optimized.folder.R23"; + private static final String KEY_OPTIMIZED_FOLDER_R24 = "optimized.folder.R24"; + /** + * Singleton instance. + **/ + private static AbstractPropertiesManager instance; + + /** + * Constructor : load the properties from the property file. + **/ + private SettingsHelper() { + super("/reporting.properties"); + } + + /** + * Returns the current dev mode status. + * + * @return true is the dev mode is active, false otherwise + */ + public static boolean isDevMode() { + return Boolean.parseBoolean(System.getProperty(KEY_DEV_MODE)); + } + + /** + * Returns the current val mode status. + * + * @return true is the val mode is active, false otherwise + */ + public static boolean isValMode() { + return Boolean.parseBoolean(System.getProperty(KEY_VAL_MODE)); + } + + /** + * Returns the current cleanup mode. If mode is unspecified, defaults to false. + * + * @return true iff the cleanup is activated + */ + public static boolean isCleanup() { + return getBooleanWithDefaultValue(KEY_CLEANUP, false); + } + + /** + * The max number of traces to keep in DB for {@link MemoryHelper}. + * + * @return an int + */ + public static int getMemoryMaxCount() { + return getInteger(KEY_MEM_MAX_MONITOR_TRACE_COUNT); + } + + /** + * The memory update frequency for {@link MemoryHelper}. + * + * @return an int + */ + public static int getMemoryFrequency() { + return getInteger(KEY_MEM_FREQUENCY); + } + + /** + * Maximum number of JSP result per page, when said page contains a table. + * + * @return number of rows + */ + public static int getJspPaging() { + return Integer.parseInt(System.getProperty(KEY_JSP_PAGING)); + } + + /** + * Returns the number of days after which usual reports are considered stale and will be deleted. + * + * @return a number of days (positive) + */ + public static int getPurgeDelayReports() { + return Integer.parseInt(System.getProperty(KEY_PURGE_DELAY_REPORTS)); + } + + /** + * Returns the number of days after which scheduled reports kept in history are considered stale and will be deleted. + * + * @return a number of days (positive) + */ + public static int getPurgeDelayScheduling() { + return Integer.parseInt(System.getProperty(KEY_PURGE_DELAY_SCHEDULING)); + } + + /** + * REturns the full title of the report. + * + * @param reportEnum the report whose title is requested + * @return the title + */ + public static String getTitle(ReportEnum reportEnum) { + return getInstance().getStringValue(KEY_PREFIX_REPORT_TITLE + reportEnum.toString()); + } + + /** + * The Default launch type (immediate). + * + * @return the folder + */ + public static String getDefaultLaunchType() { + return getInstance().getStringValue(KEY_DEFAULT_LAUNCH_TYPE); + } + + /** + * The folder location where reports are kept. + * + * @return the folder + */ + public static String getReportLocation() { + return System.getProperty(KEY_OUTPUT_FOLDER_REPORT); + } + + /** + * The folder location where the latest report of each scheduling is kept. + * + * @return the folder + */ + public static String getSchedulingLocation() { + return System.getProperty(KEY_OUTPUT_FOLDER_SCHEDULING); + } + + /** + * The folder location where scheduling history is kept. + * + * @return the folder + */ + public static String getSchedulingHistoryLocation() { + return System.getProperty(KEY_OUTPUT_FOLDER_SCHEDULING_HISTORY); + } + + /** + * The time a which the purge begins every day. format "HH:mm". + * + * @return the String time + */ + public static String getPurgeHour() { + return System.getProperty(KEY_PURGE_HOUR); + } + + // FTP CREDENTIALS FOR VALIDATION, NOT PRODUCTION + + /** + * The time a which the purge begins every day. format "HH:mm". + * + * @return the String time + */ + public static String getDelayedLaunchHour() { + return System.getProperty(KEY_DELAYED_LAUNCH_HOUR); + } + + /** + * The default email recipients when no email address is found. + * + * @return a String {@link List} + */ + public static List getDefaultDestinatorEmail() { + return getStringList(KEY_DEFAULT_DESTINATOR_EMAIL); + } + + + // ACTIVE DIRECTORY CREDENTIALS + + // ACTIVE DIRECTORY : Technical account data + + /** + * The default email recipients when no email address is found. + * + * @return a String with all recipients, com-separated + */ + public static String getDefaultDestinatorEmailFull() { + return System.getProperty(KEY_DEFAULT_DESTINATOR_EMAIL); + } + + /** + * Obtain a report's priority. + * + * @param report the report to investigate + * @return its priority : 1(high) - 3(low) + */ + public static int getPriority(ReportEnum report) { + String completeReportKey = "priority." + report.toString(); + return getInteger(completeReportKey); + } + + /** + * Reads the properties file, to obtain the list of product types.
+ * The list must be comma-separated, without spaces, like 120,238,410,700,80C,80E,850,8LM,900,970 + * + * @return the individual product types that are authorized, in a {@link List}. They are non-null, not empty. + */ + public static List getProductTypes() { + return getStringList(KEY_PRODUCT_LIST); + } + + /** + * Obtain the URL at which documents may be retrieved. The URL must still be appended with the document name. + * + * @return the root download URL. + */ + public static String getDownloadUrlRoot() { + return getString(KEY_DOWNLOAD_URL); + } + + /** + * Obtain the URL at which documents may be retrieved. The URL must still be appended with the document name. + * + * @return the root download URL. + */ + public static String getDefaultRevisionRule() { + return getInstance().getStringValue(KEY_DEFAULT_REVISION_RULE); + } + + // ACTIVE DIRECTORY : User informations + + /** + * Obtain the username of the expeditor for mails, when none is provided. + * + * @return the username. + */ + public static String getDefaultExpeditorMailUsername() { + return getString(KEY_DEFAULT_MAIL_USER); + } + + /** + * Obtain the password of the expeditor for mails, when none is provided. + * + * @return the password. + */ + public static String getDefaultExpeditorMailPassword() { + return getString(KEY_DEFAULT_MAIL_PASS); + } + + /** + * Obtain the SMTP host for emailing. + * + * @return the host. + */ + public static String getDefaultSmtpHost() { + return getString(KEY_DEFAULT_SMTP_HOST); + } + + /** + * Obtain the SMTP port for emailing. + * + * @return the port. + */ + public static String getDefaultSmtpPort() { + return getString(KEY_DEFAULT_SMTP_PORT); + } + + public static String getOptimizedFolderR23() { + return getString(KEY_OPTIMIZED_FOLDER_R23); + } + + public static String getOptimizedFolderR24() { + return getString(KEY_OPTIMIZED_FOLDER_R24); + } + + + /** + * Obtain the credentials to access the ActiveDirectory for authentication. + * + * @return the credentials + */ + public static ActiveDirectoryCredentials getActiveDirectoryCredentials() { + // Domain name. Ex: "snecma.local". + String domain = System.getProperty(KEY_DOMAIN_NAME); + String login = System.getProperty(KEY_TECH_LOGIN); + String pass; + try { + pass = new AesEncoded(System.getProperty(KEY_TECH_PASSWORD)).decode(); + } + catch (KurtException e) { + log.error("Error decoding " + KEY_TECH_PASSWORD, e); + pass = ""; + } + // Provider URL. Ex: "LDAP://snecmadc.snecma.local". + String providerURL = System.getProperty(KEY_PROVIDER_URL); + // Provider port. Ex: "389". + String providerPort = System.getProperty(KEY_PROVIDER_PORT); + return new ActiveDirectoryCredentials(domain, login, pass, providerURL, providerPort); + } + + /** + * Obtain the ActiveDirectory Attributes names to request some data. + * + * @return the attibutes names + */ + public static ActiveDirectoryAttributes getActiveDirectoryAttributes() { + String mail = System.getProperty(KEY_MAIL_ATTRIBUTE); + String login = System.getProperty(KEY_LOGIN_ATTRIBUTE); + String firstName = System.getProperty(KEY_FIRST_NAME_ATTRIBUTE); + String lastName = System.getProperty(KEY_LAST_NAME_ATTRIBUTE); + return new ActiveDirectoryAttributes(mail, login, firstName, lastName); + } + + /** + * Obtain the ActiveDirectory Attributes names to request some data. + * + * @return the attibutes names + */ + public static ActiveDirectoryAdministration getActiveDirectoryAdministration() { + String group = System.getProperty(KEY_ADMIN_GROUP); + String organisationalUnit = System.getProperty(KEY_ADMIN_ORGANISATIONAL_UNIT); + return new ActiveDirectoryAdministration(group, organisationalUnit); + } + + /** + * Returns a {@link List} of comma-separated values. The values are trimmed, and empty values are omitted. + * + * @param aKey Searched setting key + * @return a List of non-empty values + */ + private static List getStringList(String aKey) { + String rawList = System.getProperty(aKey); + if (rawList == null) { + log.warn("Could not find the property list " + aKey); + return new ArrayList<>(); + } + // Trim and split + String[] split = rawList.trim().split(","); + // Browse values + List list = new ArrayList<>(); + for (String elem : split) { + if (elem != null) { // Remove null + String trimmedElem = elem.trim(); // Trim + if (!trimmedElem.isEmpty()) { // Remove empty values + list.add(elem); + } + } + } + return list; + } + + /** + * Get Integer value from settings. + * + * @param aKey Searched setting key + * @return integer value matching with searched setting key + */ + public static int getInteger(final String aKey) { + return getInstance().getIntegerValue(aKey); + } + + /** + * Get a string value from settings. + * + * @param aKey Searched setting key + * @return String value matching with searched setting key + */ + public static String getString(final String aKey) { + return System.getProperty(aKey); + } + + /** + * Get a property from the reference parameter and set a default value if the reference is not found. + * + * @param aRef Setting key + * @param aDefaultValue Default returned value when setting is not defined + * @return string value matching with searched setting key or default value when key has not been found + */ + public static String getPropertyWithDefaultValue(final String aRef, final String aDefaultValue) { + return getInstance().getPropertyWithDefaultValueImpl(aRef, aDefaultValue); + } + + /** + * Get a boolean from the reference parameter and set a default value if the reference is not found. + * + * @param aRef Setting key + * @param aDefaultValue Default returned value when setting is not defined + * @return boolean value matching with searched setting key or default value when key has not been found + */ + private static boolean getBooleanWithDefaultValue(final String aRef, final boolean aDefaultValue) { + return getInstance().getBooleanWithDefaultValueImpl(aRef, aDefaultValue); + } + + /** + * @return the instance. + **/ + private static synchronized AbstractPropertiesManager getInstance() { + if (instance == null) { + instance = new SettingsHelper(); + } + return instance; + } + + /** + * Getter for the properties common prefixes. + * + * @return PROP_PREFIX value + **/ + @Override + protected String getPropPrefix() { + return PROP_PREFIX; + } + + /** + * Display the string content of a property file. + * + * @return String representation of sorted properties + **/ + @Override + public String toString() { + + StringBuilder thePropValues = new StringBuilder(); + + // Browse all properties for sorting them in memory + Map theSortedMap = new TreeMap<>(); + Properties propertyFile2 = getPropertyFile(); + for (Entry currentEntry : propertyFile2.entrySet()) { + theSortedMap.put(currentEntry.getKey().toString(), currentEntry.getValue().toString()); + } + + // Browse all sorted properties + for (Entry currentEntry : theSortedMap.entrySet()) { + thePropValues.append(currentEntry.getKey()).append('=').append(currentEntry.getValue()).append(StringHelper.LINE_FEED); + } + + return thePropValues.toString(); + } + + /** + * POJO holding ActiveDirectory credential data. + */ + @Getter + public static final class ActiveDirectoryCredentials { + /** + * Domain name (e.g. snecma.local). + */ + private final String domainName; + private final String techLogin; + private final String techPassword; + private final String providerURL; + private final String providerPort; + + public ActiveDirectoryCredentials(String domainName, String techLogin, String techPassword, String providerURL, String providerPort) { + this.domainName = domainName; + this.techLogin = techLogin; + this.techPassword = techPassword; + this.providerURL = providerURL; + this.providerPort = providerPort; + } + } + + /** + * POJO holding ActiveDirectory credential data. + */ + public static final class ActiveDirectoryAttributes { + private final String email; + private final String login; + private final String firstName; + private final String lastName; + + public ActiveDirectoryAttributes(String email, String login, String firstName, String lastName) { + this.email = email; + this.login = login; + this.firstName = firstName; + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public String getLogin() { + return login; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + + } + + /** + * POJO holding ActiveDirectory credential data. + */ + @Getter + public static final class ActiveDirectoryAdministration { + private final String adminGroup; + private final String adminOU; + + public ActiveDirectoryAdministration(String adminGroup, String adminOU) { + this.adminGroup = adminGroup; + this.adminOU = adminOU; + } + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/TimeHelper.java b/kurt-utility/src/main/java/com/capgemini/framework/common/TimeHelper.java new file mode 100644 index 0000000..1568eea --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/TimeHelper.java @@ -0,0 +1,103 @@ +package com.capgemini.framework.common; + +/** + * Class for time management (conversions...). + **/ +public final class TimeHelper { + + /** + * Milliseconds count by second. + **/ + private static final long MS_TO_SEC = 1000L; + /** + * Seconds count per hour. + **/ + private static final long SEC_PER_HOUR = 3600L; + /** + * Seconds count per minute. + **/ + private static final long SEC_PER_MIN = 60L; + private static final int TWO_DIGITS = 2; + private static final int THREE_DIGITS = 3; + + private TimeHelper() { + // Nothing to do + } + + /** + * Set default unit for timeStamp. + * + * @param aDuration long value (seconds) + * @return formated duration (by hours, minutes...) + */ + public static String formatDuration(final Long aDuration) { + return formatDuration(aDuration, false); + } + + /** + * Return the current date with a timeStamp. + * + * @param aDuration long value (seconds) + * @param isMsUnit Flag setting if milliseconds should be displayed + * @return formated duration (by hours, minutes...) + */ + private static String formatDuration(final Long aDuration, final boolean isMsUnit) { + + double nbMilliseconds = 0; + StringBuilder theStringValue = new StringBuilder(); + + /* Manage null values */ + if (aDuration == null) { + return StringHelper.EMPTY; + } + + long remainingSeconds = aDuration; + + /* Only required to parse milliseconds */ + if (isMsUnit) { + nbMilliseconds = remainingSeconds % MS_TO_SEC; + remainingSeconds = remainingSeconds / MS_TO_SEC; + } + + /* Compute duration components */ + long nbHours = remainingSeconds / SEC_PER_HOUR; + remainingSeconds = remainingSeconds % SEC_PER_HOUR; + long nbMinutes = remainingSeconds / SEC_PER_MIN; + remainingSeconds = remainingSeconds % SEC_PER_MIN; + + /* Hours */ + if (nbHours > 0) { + theStringValue.append(nbHours).append('h'); + } + + /* Minutes */ + if ((nbMinutes > 0) || (nbHours > 0)) { + theStringValue.append(StringHelper.fixedDigits(nbMinutes, TWO_DIGITS)).append('m'); + } + + /* Seconds */ + if (!((remainingSeconds == 0) && isMsUnit)) { + + if (nbMinutes > 0) { + theStringValue.append(StringHelper.fixedDigits(remainingSeconds, TWO_DIGITS)); + } else { + theStringValue.append(remainingSeconds); + } + theStringValue.append('s'); + } + + /* Milliseconds */ + if (isMsUnit) { + + String theMsValue; + if (aDuration > MS_TO_SEC) { + theMsValue = StringHelper.fixedDigits(nbMilliseconds, THREE_DIGITS); + } else { + theMsValue = String.valueOf((int) nbMilliseconds); + } + theStringValue.append(theMsValue).append("ms"); + } + + return theStringValue.toString(); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/activedirectory/ActiveDirectory.java b/kurt-utility/src/main/java/com/capgemini/framework/common/activedirectory/ActiveDirectory.java new file mode 100644 index 0000000..343a299 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/activedirectory/ActiveDirectory.java @@ -0,0 +1,409 @@ +package com.capgemini.framework.common.activedirectory; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.common.SettingsHelper.ActiveDirectoryAdministration; +import com.capgemini.framework.common.SettingsHelper.ActiveDirectoryAttributes; +import com.capgemini.framework.common.SettingsHelper.ActiveDirectoryCredentials; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.database.javabean.DbUser.UserData; +import com.capgemini.reports.database.manager.MngUser; +import com.capgemini.reports.exceptions.InvalidActiveDirectorySearchException; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.NoConnectionToActiveDirectoryException; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +import javax.naming.Context; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.PartialResultException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; +import java.io.Closeable; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +/** + * Query Active Directory for user data. + */ +@Slf4j +public class ActiveDirectory implements Closeable { + + /** + * The default login for non-authenticated users. + */ + public static final String GUEST_LOGIN = "Invité(e)"; + // Attribute names + static final ActiveDirectoryAttributes ATTRIBUTES = SettingsHelper.getActiveDirectoryAttributes(); + // Admin data + static final ActiveDirectoryAdministration ADMINISTRATION = SettingsHelper.getActiveDirectoryAdministration(); + private static final int SEARCH_TIMEOUT = 30000; // 30s + private static final String AD_SEPARATOR = ": "; + // Technical account data + private static final ActiveDirectoryCredentials CREDENTIALS = SettingsHelper.getActiveDirectoryCredentials(); + /** + * Domain Controller. Ex: "DC=SNECMA,DC=LOCAL". + */ + static final String DOMAIN_CONTROLLER = getDomainBase(CREDENTIALS.getDomainName()); + private static final String MEMBER_OF_ATTRIBUTE = "memberOf"; // Default value for this attribute in LDAP + private static final String[] REQUESTED_ATTRIBUTES = + {ATTRIBUTES.getLogin(), ATTRIBUTES.getEmail(), ATTRIBUTES.getFirstName(), ATTRIBUTES.getLastName(), MEMBER_OF_ATTRIBUTE}; + // Guest + private static final String DEFAULT_DESTINATOR_EMAIL = SettingsHelper.getDefaultDestinatorEmailFull(); + private static final UserData GUEST = new UserData(GUEST_LOGIN, DEFAULT_DESTINATOR_EMAIL, "Not", "Found", false); + // required private variables + private final DirContext dirContext; + + /* + * Working request exemple: + * + * ========= REQUEST ========== + * Base DN : DC=SNECMA,DC=LOCAL + * Filter : (&(objectClass=user)(cn=snecmauser)) + * Scope : Subtree + * Attributes: cn;mail; + * ========= RESPONSE ========= + * Result: + * Searching... + * ldap_search_s(ld, "DC=SNECMA,DC=LOCAL", 2, "(&(objectClass=user)(cn=snecmauser))", attrList, 0, &msg) + * Getting 1 entries: + * Dn: CN=SnecmaUser,OU=Snecma,OU=Utilisateurs,DC=snecma,DC=local + * cn: SnecmaUser; + * mail: SnecmaUser@snecma.local; + */ + + /** + * Constructor with parameter for initializing a LDAP context. + */ + protected ActiveDirectory() throws NoConnectionToActiveDirectoryException { + Properties properties = new Properties(); + + // Provider URL+port. Ex: "LDAP://snecmadc.snecma.local:389/" + String providerUrlBase = CREDENTIALS.getProviderURL() + ":" + CREDENTIALS.getProviderPort() + "/"; + String providerURL = providerUrlBase + DOMAIN_CONTROLLER; + // Precise security login. Ex: "sa-bind@snecma.local" + String securityPrincipal = CREDENTIALS.getTechLogin() + "@" + CREDENTIALS.getDomainName(); + + properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + properties.put(Context.PROVIDER_URL, providerURL); + properties.put(Context.SECURITY_AUTHENTICATION, "simple"); + properties.put(Context.SECURITY_PRINCIPAL, securityPrincipal); + properties.put(Context.SECURITY_CREDENTIALS, CREDENTIALS.getTechPassword()); + properties.put("sun.security.krb5.debug", SettingsHelper.getPropertyWithDefaultValue("devmode", "false")); + properties.put("java.naming.ldap.derefAliases", "never"); + properties.put("java.naming.ldap.version", "3"); + + // Initializing active directory LDAP connection + try { + dirContext = new InitialDirContext(properties); + } + catch (NamingException e) { + throw new NoConnectionToActiveDirectoryException("Could not connect the app to the Active Directory", e); + } + } + + /** + * Returns the GUEST user, to be used when authentication failed, for any reason. + * + * @return the GUEST user. + */ + public static UserData getGuestUser() { + return GUEST; + } + + /** + * Returns the user's email address. + * + * @param userLogin the user login + * @return the user data. Never null, would (throw an exception first but may contain null fields + * @throws NoConnectionToActiveDirectoryException thrown if no connection could be found (appli might not be in same doain as AD?) + * @throws InvalidActiveDirectorySearchException thrown if search was rejected by AD (check syntax?) + * @throws InvalidInputException thrown if provided username was null: no data may be retrieved then + */ + public static UserData obtainUserData(final String userLogin) + throws NoConnectionToActiveDirectoryException, InvalidActiveDirectorySearchException, InvalidInputException { + if (userLogin == null) { + throw new InvalidInputException("Null login received from request header. Cannot identify the user."); + } + + // Connect to the AD + try (ActiveDirectory activeDirectory = new ActiveDirectory()) { + + // Search the user + SearchFilter searchLogin = SearchFilter.searchLogin(userLogin); + + // Obtain user data + UserData userData; + Attributes attrs = activeDirectory.getUserAttributes(searchLogin); + if (attrs == null) { + log.info("Obtained no results from ActiveDirectory search for login '{}', defaulting to GUEST", userLogin); + userData = GUEST; + } + else { + // Retrieve AD login, because teamcenter uses lower case, but in AD its Capitalization may vary! + String loginAD = getAttribute(attrs, ATTRIBUTES.getLogin()); + String firstName = getAttribute(attrs, ATTRIBUTES.getFirstName()); + String lastName = getAttribute(attrs, ATTRIBUTES.getLastName()); + String userEmail = getAttribute(attrs, ATTRIBUTES.getEmail()); + + // If the user was found, keep searching for its potential admin status + boolean adminStatus = isAdmin(activeDirectory, searchLogin); + + userData = new UserData(loginAD, userEmail, firstName, lastName, adminStatus); // Use only AD-provided data + log.info("Identified user: {}={}, {}={}, {}={}", ATTRIBUTES.getLogin(), userLogin, ATTRIBUTES.getFirstName(), firstName, + ATTRIBUTES.getLastName(), lastName, ATTRIBUTES.getEmail(), userEmail); + } + return userData; + } + } + + /** + * Connect to Active Directory and return a list of Admins Report. + * + * @return List DbUser + * @throws NoConnectionToActiveDirectoryException if unable to connect to the AD + * @throws InvalidActiveDirectorySearchException if the search for the admin group is ill-formed + * @throws NamingException if the name of the admin group is invalid + */ + private static List obtainAdminReport() + throws NoConnectionToActiveDirectoryException, InvalidActiveDirectorySearchException, NamingException { + List adminDbUserList = new ArrayList<>(); + + // Connect to the AD + try (ActiveDirectory activeDirectory = new ActiveDirectory()) { + + // Filter Search in Group Administrator + NamingEnumeration searchEnum = activeDirectory.search(SearchFilter.searchInGroup(ADMINISTRATION.getAdminGroup())); + + while (searchEnum.hasMoreElements()) { + Attributes attrs = searchEnum.next().getAttributes(); + + if (attrs == null) { + log.info("Obtained no results from ActiveDirectory search for users of ou='{}' ou='{}' ", ADMINISTRATION.getAdminOU(), + ADMINISTRATION.getAdminGroup()); + } + else { + String login = getAttribute(attrs, ATTRIBUTES.getLogin()); + String firstName = getAttribute(attrs, ATTRIBUTES.getFirstName()); + String lastName = getAttribute(attrs, ATTRIBUTES.getLastName()); + String email = getAttribute(attrs, ATTRIBUTES.getEmail()); + UserData admin = new UserData(login, email, firstName, lastName, true); // these are all admins of course + + // add to list admin report + adminDbUserList.add(admin); + } + } + } + return adminDbUserList; + } + + private static boolean isAdmin(final ActiveDirectory activeDirectory, final SearchFilter searchLogin) + throws InvalidActiveDirectorySearchException { + SearchFilter searchInAdminGroup = SearchFilter.searchInGroup(ADMINISTRATION.getAdminGroup()); + NamingEnumeration adminResult = activeDirectory.search(searchLogin, searchInAdminGroup); + return adminResult.hasMoreElements(); + } + + private static String getAttribute(final Attributes attrs, final String attribute) { + if (!isValidAttribute(attribute)) { + log.warn("Attribute '{}' is asked from the Active Directory search results, but is not part of the attributes list", attribute); + } + Attribute keyValue = attrs.get(attribute); + if (keyValue == null) { + return StringHelper.EMPTY; + } + else { + String userEmailResponse = keyValue.toString(); + String email; + if (userEmailResponse.contains(AD_SEPARATOR)) { + // expecting 'KEY: VALUE' pair from AD (note the double double dots, AND the whitespace) + email = userEmailResponse.substring(userEmailResponse.indexOf(AD_SEPARATOR) + AD_SEPARATOR.length()); + } + else { + email = StringHelper.EMPTY; + } + return email; + } + } + + private static boolean isValidAttribute(final String attribute) { + for (String requestedAttribute : REQUESTED_ATTRIBUTES) { + if (requestedAttribute.equals(attribute)) { + return true; + } + } + return false; + } + + /** + * Creating a domain base value (e.g. DC=SNECMA,DC=LOCAL) from domain controller name (e.g. snecma.local) + * + * @param domain a {@link String} object - name of the domain controller + * @return a {@link String} object - base name for eg. DC=SNECMA,DC=LOCAL + */ + private static String getDomainBase(final String domain) { + return makeBase(domain, "DC"); + } + + /** + * Creating a Organisational Unit base value.
+ * ex: + *

    + *
  • 'TechnicalAccounts' becomes 'OU=TECHNICALACCOUNTS'
  • + *
  • 'snecma.utilisateurs' becomes 'OU=Snecma,OU=Utilisateurs'
  • + *
+ * + * @param organisationalUnit a {@link String} object - name of the domain controller + * @return a {@link String} object - base name for eg. DC=SNECMA,DC=LOCAL + */ + static String getOrganisationalUnitBase(final String organisationalUnit) { + return makeBase(organisationalUnit, "OU"); + } + + private static String makeBase(final String original, final String key) { + String separator = ',' + key + '='; + StringBuilder result = new StringBuilder(key).append('='); + String upper = original.toUpperCase(); + result.append(upper.replace(".", separator)); + return result.toString(); + } + + /** + * Return list contains object {@link DbUser} which are administrators report, quiet fail.
+ * If unable to connect to active directory, or unable to obtain a user from ActiveDirectory, returns the default user (Guest). + * + * @return a {@link List} of admins {@link DbUser}s + */ + public static List getAdminsReportUpdateDatabase() { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + try { + List adAdmins = ActiveDirectory.obtainAdminReport(); + List dbAdmins = new MngUser().fetchOrUpdateOrCreateUsers(session, adAdmins); + if (!dbAdmins.isEmpty()) { + return dbAdmins; + } + else { + log.warn("No administrators retrieved from AD! inserting default user (guest)"); + } + } + catch (NoConnectionToActiveDirectoryException e) { + log.warn("Could not connect to the AD to findAll the list of Administrators ", e); + } + catch (NamingException e) { + log.warn("AD Could not locate the Administrators group in the AD", e); + } + catch (InvalidActiveDirectorySearchException e) { + log.warn("Could not perform a search on the AD, to findAll the list of Administrators", e); + } + // Use default user (something happened) + ArrayList defaultUsers = new ArrayList<>(); + defaultUsers.add(new MngUser().fetchOrUpdateOrCreateUser(session, ActiveDirectory.getGuestUser())); + return defaultUsers; + } + finally { + session.close(); + } + } + + private Attributes getUserAttributes(final SearchFilter searchLogin) throws InvalidActiveDirectorySearchException { + NamingEnumeration result = search(searchLogin); + if (result == null) { + log.debug("Filter '{}' provided null results from the Active Directory, defaulting to GUEST", searchLogin.makeFilterComponent()); + return null; + } + // Parse the results + try { + if (result.hasMoreElements()) { + SearchResult searchResult = result.next(); + return searchResult.getAttributes(); + } + else { + log.info("Filter '{}' provided no result from the Active Directory, defaulting to GUEST", searchLogin.makeFilterComponent()); + return null; + } + } + catch (PartialResultException pre) { + // If a result exists, it is correctly handled in the 'try' above. if the user was not found, we will end up here upon calling hasMore() + String errorMsg = "PartialResultException caught while obtaining data from the Active Directory"; + throw new InvalidActiveDirectorySearchException(errorMsg, pre); + } + catch (NamingException e) { + String errorMsg = "Could not obtain further results from the Active Directory search results"; + throw new InvalidActiveDirectorySearchException(errorMsg, e); + } + } + + /** + * Search the Active directory by username/email id for given search base. + * + * @param searchValues one or more {@link SearchFilter}s - to search things like login, group membership etc. + * @return search result a {@link javax.naming.NamingEnumeration} object - active directory search result + * @throws InvalidActiveDirectorySearchException if the search is ill-formed + */ + + public NamingEnumeration search(final SearchFilter... searchValues) throws InvalidActiveDirectorySearchException { + String filter = getFilter(searchValues); + log.trace("Trying to perform a search with filter: " + filter); + // Initializing search controls + SearchControls searchCtls = new SearchControls(); + searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE); + searchCtls.setReturningAttributes(REQUESTED_ATTRIBUTES); + searchCtls.setTimeLimit(SEARCH_TIMEOUT); + + if (this.dirContext == null) { + log.warn("Trying to perform an ActiveDirectory search, but DirContext is null"); + return null; + } + else { + try { + log.info("Performing search Using filter: " + filter); + return this.dirContext.search("", filter, searchCtls); + } + catch (NamingException e) { + throw new InvalidActiveDirectorySearchException("Could not perform a login search in the Active Directory", e); + } + } + } + + /** + * Closes the LDAP connection with Domain controller. + */ + @Override + public void close() { + if (dirContext != null) { + try { + dirContext.close(); + } + catch (NamingException e) { + log.warn("Could not close LDAP connection properly", e); + } + } + } + + /** + * Active directory filter. + * + * @param searchBy a series of {@link SearchFilter} object - scope of search by username or email id + * @return a {@link String} object - filter string + */ + private String getFilter(final SearchFilter... searchBy) { + // Open filter: search for a user + StringBuilder filter = new StringBuilder("(&(objectClass=User)"); // <-- verifier avec SNECMA + for (SearchFilter criteria : searchBy) { + filter.append(criteria.makeFilterComponent()); + } + // End filter + filter.append(')'); + return filter.toString(); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/activedirectory/SearchCriteria.java b/kurt-utility/src/main/java/com/capgemini/framework/common/activedirectory/SearchCriteria.java new file mode 100644 index 0000000..01db836 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/activedirectory/SearchCriteria.java @@ -0,0 +1,6 @@ +package com.capgemini.framework.common.activedirectory; + +enum SearchCriteria { + LOGIN, + GROUP +} diff --git a/kurt-utility/src/main/java/com/capgemini/framework/common/activedirectory/SearchFilter.java b/kurt-utility/src/main/java/com/capgemini/framework/common/activedirectory/SearchFilter.java new file mode 100644 index 0000000..484ef98 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/framework/common/activedirectory/SearchFilter.java @@ -0,0 +1,58 @@ +package com.capgemini.framework.common.activedirectory; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; + +/** + * Helper class to generate filters for Active Directory, e.g. looking for a specific username, etc. + */ +@AllArgsConstructor(access = AccessLevel.PRIVATE) +class SearchFilter { + + private final String value; + private final SearchCriteria criteria; + + /** + * Restricts the Search to a user login. + * + * @param login the user's login + * @return a search filter + */ + public static SearchFilter searchLogin(final String login) { + return new SearchFilter(login, SearchCriteria.LOGIN); + } + + /** + * Restricts the search to a specific Group (such as admin group). + * + * @param group the name of the group + * @return a search filter + */ + public static SearchFilter searchInGroup(final String group) { + return new SearchFilter(group, SearchCriteria.GROUP); + } + + /** + * Makes a filter component. Various filter components may be chained inside parentheses to construct a powerful filter.
+ * For example, a filter component for filtering logins might look like:
+ * (cn=THE_LOGIN) + * + * @return the filter component + */ + public String makeFilterComponent() { + String filterComp; + switch (criteria) { + case LOGIN: + filterComp = "(" + ActiveDirectory.ATTRIBUTES.getLogin() + "=" + value + ")"; + break; + case GROUP: + String orgUnitFilter = ActiveDirectory.getOrganisationalUnitBase(ActiveDirectory.ADMINISTRATION.getAdminOU()); + filterComp = "(memberOf=CN=" + value + "," + orgUnitFilter + "," + ActiveDirectory.DOMAIN_CONTROLLER + ")"; + break; + default: + filterComp = ""; + break; + } + return filterComp; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/JasperTemplate.java b/kurt-utility/src/main/java/com/capgemini/reports/JasperTemplate.java new file mode 100644 index 0000000..f8d57fc --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/JasperTemplate.java @@ -0,0 +1,68 @@ +package com.capgemini.reports; + +import lombok.Getter; + +/** Enumeration of the different Jasper's templates. */ +@Getter +public enum JasperTemplate { + + // Some useful file locations + /** The template of the R01 report. */ + TEMPLATE_R01("/Jasper/template/report_r01.jrxml"), + /** The template of the R03 report. */ + TEMPLATE_R03("/Jasper/template/report_r03.jrxml"), + /** The template of the R10 report. */ + TEMPLATE_R10("/Jasper/template/report_r10.jrxml"), + /** The template of the R11 report. */ + TEMPLATE_R11("/Jasper/template/report_r11.jrxml"), + /** The template of the R13 report for a CR object. */ + TEMPLATE_R13_CR("/Jasper/template/report_r13/report_r13_cr.jrxml"), + /** The template of the R13 report fro a FPP object. */ + TEMPLATE_R13_FPP("/Jasper/template/report_r13/report_r13_fpp.jrxml"), + /** The template of the R15 and R16 reports. */ + TEMPLATE_R15R16("/Jasper/template/report_r15r16.jrxml"), + /** The template of the R17 report. */ + TEMPLATE_R17("/Jasper/template/report_r17.jrxml"), + /** The template of the R19 report. */ + TEMPLATE_R19("/Jasper/template/report_r19.jrxml"), + // Template R20 resource files + /** The template of the R20 report, page 1. */ + TEMPLATE_R20_PAGE1("/Jasper/template/report_r20/report_r20_p1.jrxml"), + /** The template of the R20 report, page 2 master. */ + TEMPLATE_R20_PAGE2("/Jasper/template/report_r20/report_r20_p2.jrxml"), + /** The template of the R20 report, page 4. */ + TEMPLATE_R20_PAGE4("/Jasper/template/report_r20/report_r20_p4.jrxml"), + /** The template of the R20 report, page 2 part 1. */ + TEMPLATE_R20_PAGE2_GENERIC("/Jasper/template/report_r20/page2/r20_p2_generics.jrxml"), + /** The template of the R20 report, page 2 part 2. */ + TEMPLATE_R20_PAGE2_IMPACTS("/Jasper/template/report_r20/page2/r20_p2_impacts.jrxml"), + /** The template of the R20 report, page 2 part 3. */ + TEMPLATE_R20_PAGE2_NOIMPACTS("/Jasper/template/report_r20/page2/r20_p2_noimpacts.jrxml"), + /** The Master template of the R20 report. */ + TEMPLATE_R20_MASTER("/Jasper/template/report_r20/report_r20_master.jrxml"), + /** The template of the R21 report. */ + TEMPLATE_R21("/Jasper/template/report_r21.jrxml"), + /** The template of the R22 report. */ + TEMPLATE_R22("/Jasper/template/report_r22.jrxml"), + /** The template of the R23 report. */ + TEMPLATE_R23("/Jasper/template/report_r23.jrxml"), + /** The template of the R24 report. */ + TEMPLATE_R24("/Jasper/template/report_r24.jrxml"), + /** The template of the R25 report. */ + TEMPLATE_R25("/Jasper/template/report_r25.jrxml"), + /** The Master template of the R26 report. */ + TEMPLATE_R26_MASTER("/Jasper/template/report_r26/report_r26_master.jrxml"), + /** The sub report template of the R26 report. */ + TEMPLATE_R26_SUBREPORT("/Jasper/template/report_r26/report_r26_subreport.jrxml"), + /** The template of the R27 report. */ + TEMPLATE_R27("/Jasper/template/report_r27.jrxml"), + /** The template of the R28 report. */ + TEMPLATE_R28("/Jasper/template/report_r28.jrxml"); + + + private final String filepath; + + JasperTemplate(final String filepath) { + this.filepath = filepath; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/ReportEnum.java b/kurt-utility/src/main/java/com/capgemini/reports/ReportEnum.java new file mode 100644 index 0000000..90f6381 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/ReportEnum.java @@ -0,0 +1,106 @@ +package com.capgemini.reports; + +import com.capgemini.framework.common.SettingsHelper; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +/** + * Lists all existing reports, using the format REPORT_Rxy. + */ +@AllArgsConstructor +@Getter +public enum ReportEnum { + REPORT_R01(null), + REPORT_R03(null), + REPORT_R05(null), + REPORT_R06(null), + REPORT_R07(null), + REPORT_R10(null), + REPORT_R11(null), + REPORT_R13(null), + REPORT_R15(null), + REPORT_W15("autoR15real"), + REPORT_R16(null), + REPORT_R17(null), + REPORT_R19(null), + REPORT_R20(null), + REPORT_R21(null), + REPORT_R22(null), + REPORT_W22("autoR22"), + REPORT_R23(null), + REPORT_R24(null), + REPORT_R25(null), + REPORT_R26(null), + REPORT_R27(null), + REPORT_R28(null); + + private final String urlForAutomaticGeneration; + + /** + * Returns the corresponding report Code (i.e. 'RB1', or 'R07'). + * + * @return the report code + */ + public String getReportCode() { + return toString().replace("REPORT_", ""); + } + + /** + * Returns the report short name, in french.
+ * Exemple with the R01: 'Rapport R01'. + * + * @return the report code + */ + public StringBuilder getReportName() { + String reportCode = getReportCode(); + return new StringBuilder("Rapport ").append(reportCode.toUpperCase()); + } + + /** + * Returns the official report title.
+ * Exemple for R01: 'BOM assemblage PU'.
+ * Title is extracted from the reporting.properties file. + * + * @return the report title + */ + public String getReportTitle() { + return SettingsHelper.getTitle(this); + } + + /** + * Returns the full report identifier and title.
+ * Exemple for R01: 'Rapport R01 "BOM assemblage PU"' + * + * @return the report identifier + */ + public StringBuilder buildCompleteReportName() { + return getReportName().append(" \"").append(getReportTitle()).append('"'); + } + + /** + * Returns the {@link ReportEnum} of this report, if you provide its report Code. + * + * @param reportCode the report code, like 'R01' or 'RB1' + * @return the matching {@link ReportEnum} + */ + public static ReportEnum fromCode(final String reportCode) { + return valueOf("REPORT_" + reportCode.toUpperCase()); + } + + /** + * Returns the official list of report code.
+ * Exemple : Rxx + * + * @return list + */ + public static List getListReportCode() { + List allReportCode = new ArrayList<>(); + for (ReportEnum value : ReportEnum.values()) { + allReportCode.add(value.getReportCode()); + } + return allReportCode; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/ReportLaunchTypeEnum.java b/kurt-utility/src/main/java/com/capgemini/reports/ReportLaunchTypeEnum.java new file mode 100644 index 0000000..d3f96c0 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/ReportLaunchTypeEnum.java @@ -0,0 +1,57 @@ +package com.capgemini.reports; + +import com.capgemini.framework.common.SettingsHelper; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +/** Enumeration of the different launch type of a report. */ +@Slf4j +@Getter +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public enum ReportLaunchTypeEnum { + + /** The immediate launch type. */ + IMMEDIATE("immediate", "none"), + /** The delayed launch type. */ + DELAYED("delayed", "delayed"), + /** The scheduled launch type. */ + SCHEDULED("scheduled", "scheduled"), + /** The scheduled launch type. */ + AUTOMATIC("automatic", "immediate"); + + private final String launchType; + private final String groupName; + + private static final String DEFAULT_LAUNCH_TYPE = SettingsHelper.getDefaultLaunchType(); + + /** + * Give the appropriate {@link ReportLaunchTypeEnum} associate to the string value.
+ * Else return null. + * + * @param personnalizeValueIfExist String - the string value + * @return the appropriate {@link ReportLaunchTypeEnum}. Return null if the string value doesn't exist. + */ + public static ReportLaunchTypeEnum getReportLaunchType(final String personnalizeValueIfExist) { + // Determine the string value of the type + String realValue = SettingsHelper.getPropertyWithDefaultValue(personnalizeValueIfExist, DEFAULT_LAUNCH_TYPE); + + // Determine the enumeration value + ReportLaunchTypeEnum launchType; + if ("immediate".equals(realValue)) { + launchType = ReportLaunchTypeEnum.IMMEDIATE; + } else if ("delayed".equals(realValue)) { + launchType = ReportLaunchTypeEnum.DELAYED; + } else if ("scheduled".equals(realValue)) { + launchType = ReportLaunchTypeEnum.SCHEDULED; + } else if ("automatic".equals(realValue)) { + launchType = ReportLaunchTypeEnum.AUTOMATIC; + } else { + log.error("No status found. The string {} is not valid.", realValue); + launchType = null; + } + return launchType; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/AbstractR13Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/AbstractR13Builder.java new file mode 100644 index 0000000..324d0f7 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/AbstractR13Builder.java @@ -0,0 +1,40 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r13report.execution.AbstractExecutionR13; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.reports.parameters.EffectivityDate; + +import java.util.Map; + +/** + * Reconstructs a R13 (CR) report from two delimiter dates. + * + * @param the sub-type of R13 report (CR/FPP) + */ +public abstract class AbstractR13Builder> implements ReportBuilder { + + @Override + public T build(Map data) throws InsufficientParametersException { + // Get the request raw data + String dateDebutStr = data.get(ReportCriteriaEnum.DATE_DEBUT); + String dateFinStr = data.get(ReportCriteriaEnum.DATE_FIN); + + // no mandatory args + EffectivityDate dateDebut = dateDebutStr == null ? null : new EffectivityDate(dateDebutStr); // defautlt is null + EffectivityDate dateFin = dateFinStr == null ? new EffectivityDate() : new EffectivityDate(dateFinStr); // default is no args Ctor + + // Build the report + return this.make(dateDebut, dateFin); + } + + /** + * Create an Execution instance of the right type, using the verified parameters as-is. + * + * @param dateDebut a beginning date (checked) + * @param dateFinStr an end date (checked) + * @return the Execution. + */ + protected abstract T make(EffectivityDate dateDebut, EffectivityDate dateFinStr); + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/AbstractR15R16R17Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/AbstractR15R16R17Builder.java new file mode 100644 index 0000000..b3f3a44 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/AbstractR15R16R17Builder.java @@ -0,0 +1,34 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r15r16r17reports.AbstractExecutionR15R16R17; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.google.common.base.Joiner; + +import java.util.Map; + +/** + * Mother class for R15/16/17 Report Builders. Language parameters is safely extracted here. + * + * @param the real report type (R15/16/17) + */ +public abstract class AbstractR15R16R17Builder> implements ReportBuilder { + + @Override + public T build(Map data) throws InsufficientParametersException { + // Get the request raw data + String language = data.get(ReportCriteriaEnum.LANGUAGE); + + // Check presence of all required args + if (language == null) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Missing parameter for R15/16/17 launch. Obtained: " + dataStr); + } + + // Build the report + return make(data, language); + } + + protected abstract T make(Map data, String language) throws InsufficientParametersException; + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/AbstractR15R17Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/AbstractR15R17Builder.java new file mode 100644 index 0000000..d461ec9 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/AbstractR15R17Builder.java @@ -0,0 +1,35 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r15r16r17reports.r15r17reports.AbstractExecutionR15R17; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.google.common.base.Joiner; + +import java.util.Map; + +/** + * Mother class for R15/17 Report Builders. Part id & revision are safely extracted here. + * + * @param the real report type (R15/17) + */ +public abstract class AbstractR15R17Builder> extends AbstractR15R16R17Builder { + + @Override + protected T make(Map data, String language) throws InsufficientParametersException { + // Get the request raw data + String partId = data.get(ReportCriteriaEnum.PART_ID); + String partRevision = data.get(ReportCriteriaEnum.PART_REVISION); + + // Check presence of all required args + if (partId == null || partRevision == null) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Missing parameter for R15/R17 launch. Obtained: " + dataStr); + } + + // Build the report + return make(language, partId, partRevision); + } + + protected abstract T make(String language, String partId, String partRevision); + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R01Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R01Builder.java new file mode 100644 index 0000000..eba8c87 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R01Builder.java @@ -0,0 +1,50 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r01report.ExecutionR01; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.reports.parameters.Generics; +import com.capgemini.reports.reports.parameters.MonoMulti; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.google.common.base.Joiner; + +import java.util.Map; + +/** Reconstructs a R01 report from BOM parameters. Generic parameters are optional. */ +public class R01Builder implements ReportBuilder { + + @Override + public ExecutionR01 build(Map data) throws InsufficientParametersException { + // Get the request raw data + String product = data.get(ReportCriteriaEnum.PRODUCT); + String unitStr = data.get(ReportCriteriaEnum.UNIT); + String monoMultiStr = data.get(ReportCriteriaEnum.MONO_MULTI); + String generic = data.get(ReportCriteriaEnum.GENERIC); + String genericAssemb = data.get(ReportCriteriaEnum.GENERIC_ASSEMB); + String effectivityStr = data.get(ReportCriteriaEnum.EFFECTIVITY_DATE); + String superModelStr = data.get(ReportCriteriaEnum.SUPERMODEL); + + + // Check presence of all required args + if (product == null || unitStr == null || monoMultiStr == null) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Missing parameter for R01 launch. Obtained: " + dataStr); + } + int unit; + try { + unit = Integer.parseInt(unitStr); + } catch (NumberFormatException e) { + throw new InsufficientParametersException("Unit parameter is not an int: " + unitStr, e); + } + ProductUnit aProductUnit = new ProductUnit(product, unit); + Generics aGeneric = new Generics(aProductUnit, generic, genericAssemb); + MonoMulti aMonoMulti = MonoMulti.build(monoMultiStr); + EffectivityDate anEffectivity = new EffectivityDate(effectivityStr); + boolean isSuperModelBOM = Boolean.parseBoolean(superModelStr); + + // Build the report + return new ExecutionR01(aProductUnit, aGeneric, aMonoMulti, anEffectivity, isSuperModelBOM); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R03Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R03Builder.java new file mode 100644 index 0000000..f100c2a --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R03Builder.java @@ -0,0 +1,29 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r03report.ExecutionR03; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.google.common.base.Joiner; + +import java.util.Map; + +/** Reconstructs a R03 report from Part Id and rev. */ +public class R03Builder implements ReportBuilder { + + @Override + public ExecutionR03 build(Map data) throws InsufficientParametersException { + // Get the request raw data + String partId = data.get(ReportCriteriaEnum.PART_ID); + String partRev = data.get(ReportCriteriaEnum.PART_REVISION); + + // Check presence of all required args + if (partId == null || partRev == null) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Missing parameter for R03 launch. Obtained: " + dataStr); + } + + // Build the report + return new ExecutionR03(partId, partRev); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R07Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R07Builder.java new file mode 100644 index 0000000..4b8cc1a --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R07Builder.java @@ -0,0 +1,50 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r07report.ExecutionR07; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.reports.parameters.Generics; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.google.common.base.Joiner; + +import java.util.Map; + +/** Reconstructs a R01 report from two BOM configuration parameters. Generic parameters are optional. */ +public class R07Builder implements ReportBuilder { + + @Override + public ExecutionR07 build(Map data) throws InsufficientParametersException { + // Get the request raw data + String product = data.get(ReportCriteriaEnum.PRODUCT); + String unitStr1 = data.get(ReportCriteriaEnum.UNIT_CONFIGURATION_1); + String unitStr2 = data.get(ReportCriteriaEnum.UNIT_CONFIGURATION_2); + String generic = data.get(ReportCriteriaEnum.GENERIC); + String genericAssemb = data.get(ReportCriteriaEnum.GENERIC_ASSEMB); + + // Check presence of all required args + if (product == null || unitStr1 == null || unitStr2 == null) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Missing parameter for R07 launch. Obtained: " + dataStr); + } + int unit1; + try { + unit1 = Integer.parseInt(unitStr1); + } catch (NumberFormatException e) { + throw new InsufficientParametersException("Unit parameter 1 is not an int: " + unitStr1, e); + } + int unit2; + try { + unit2 = Integer.parseInt(unitStr2); + } catch (NumberFormatException e) { + throw new InsufficientParametersException("Unit parameter 2 is not an int: " + unitStr2, e); + } + ProductUnit aProductUnit1 = new ProductUnit(product, unit1); + ProductUnit aProductUnit2 = new ProductUnit(product, unit2); + Generics gen1 = new Generics(aProductUnit1, generic, genericAssemb); // only difference should be unit # + Generics gen2 = new Generics(aProductUnit2, generic, genericAssemb); // Generics are optional + + // Build the report + return new ExecutionR07(gen1, gen2); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R10Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R10Builder.java new file mode 100644 index 0000000..c9c2953 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R10Builder.java @@ -0,0 +1,47 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r10report.ExecutionR10; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.reports.parameters.Generics; +import com.capgemini.reports.reports.parameters.MonoMulti; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.google.common.base.Joiner; + +import java.util.Map; + +/** Reconstructs a R10 report from BOM parameters. Generic parameters are optional. */ +public class R10Builder implements ReportBuilder { + + @Override + public ExecutionR10 build(Map data) throws InsufficientParametersException { + // Get the request raw data + String product = data.get(ReportCriteriaEnum.PRODUCT); + String unitStr = data.get(ReportCriteriaEnum.UNIT); + String monoMultiStr = data.get(ReportCriteriaEnum.MONO_MULTI); + String generic = data.get(ReportCriteriaEnum.GENERIC); + String genericAssemb = data.get(ReportCriteriaEnum.GENERIC_ASSEMB); + String effectivityStr = data.get(ReportCriteriaEnum.EFFECTIVITY_DATE); + + // Check presence of all required args + if (product == null || unitStr == null || monoMultiStr == null) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Missing parameter for R10 launch. Obtained: " + dataStr); + } + int unit; + try { + unit = Integer.parseInt(unitStr); + } catch (NumberFormatException e) { + throw new InsufficientParametersException("Unit parameter is not an int: " + unitStr, e); + } + ProductUnit aProductUnit = new ProductUnit(product, unit); + Generics aGeneric = new Generics(aProductUnit, generic, genericAssemb); + MonoMulti aMonoMulti = MonoMulti.build(monoMultiStr); + EffectivityDate anEffectivity = new EffectivityDate(effectivityStr); + + // Build the report + return new ExecutionR10(aGeneric, aMonoMulti, anEffectivity); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R11Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R11Builder.java new file mode 100644 index 0000000..6333126 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R11Builder.java @@ -0,0 +1,48 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r11report.ExecutionR11; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.reports.parameters.Generics; +import com.capgemini.reports.reports.parameters.MonoMulti; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.google.common.base.Joiner; + +import java.util.Map; + + +/** Reconstructs a R11 report from BOM parameters. Generic parameters are optional. */ +public class R11Builder implements ReportBuilder { + + @Override + public ExecutionR11 build(Map data) throws InsufficientParametersException { + // Get the request raw data + String product = data.get(ReportCriteriaEnum.PRODUCT); + String unitStr = data.get(ReportCriteriaEnum.UNIT); + String monoMultiStr = data.get(ReportCriteriaEnum.MONO_MULTI); + String generic = data.get(ReportCriteriaEnum.GENERIC); + String genericAssemb = data.get(ReportCriteriaEnum.GENERIC_ASSEMB); + String effectivityStr = data.get(ReportCriteriaEnum.EFFECTIVITY_DATE); + + // Check presence of all required args + if (product == null || unitStr == null || monoMultiStr == null || effectivityStr == null) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Missing parameter for R11 launch. Obtained: " + dataStr); + } + int unit; + try { + unit = Integer.parseInt(unitStr); + } catch (NumberFormatException e) { + throw new InsufficientParametersException("Unit parameter is not an int: " + unitStr, e); + } + ProductUnit aProductUnit = new ProductUnit(product, unit); + Generics aGeneric = new Generics(aProductUnit, generic, genericAssemb); + MonoMulti aMonoMulti = MonoMulti.build(monoMultiStr); + EffectivityDate anEffectivity = new EffectivityDate(effectivityStr); + + // Build the report + return new ExecutionR11(aGeneric, aMonoMulti, anEffectivity); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R13CrBuilder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R13CrBuilder.java new file mode 100644 index 0000000..3ec9e86 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R13CrBuilder.java @@ -0,0 +1,14 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.definition.r13report.execution.ExecutionR13CR; +import com.capgemini.reports.reports.parameters.EffectivityDate; + +/** Reconstructs a R13 (CR) report from two delimiter dates. */ +public class R13CrBuilder extends AbstractR13Builder { + + @Override + protected ExecutionR13CR make(EffectivityDate beginDate, EffectivityDate finalDate) { + return new ExecutionR13CR(finalDate, beginDate); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R13FppBuilder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R13FppBuilder.java new file mode 100644 index 0000000..bd4ce7b --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R13FppBuilder.java @@ -0,0 +1,14 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.definition.r13report.execution.ExecutionR13FPP; +import com.capgemini.reports.reports.parameters.EffectivityDate; + +/** Reconstructs a R13 (CR) report from two delimiter dates. */ +public class R13FppBuilder extends AbstractR13Builder { + + @Override + protected ExecutionR13FPP make(EffectivityDate beginDate, EffectivityDate finalDate) { + return new ExecutionR13FPP(finalDate, beginDate); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R15Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R15Builder.java new file mode 100644 index 0000000..3e77584 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R15Builder.java @@ -0,0 +1,14 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.definition.r15r16r17reports.r15r17reports.r15report.ExecutionR15; + +/** Builds a R15 Report from language, part Id & rev. */ +public class R15Builder extends AbstractR15R17Builder { + + @Override + protected ExecutionR15 make(String language, String partId, String partRevision) { + return new ExecutionR15(partId, partRevision, language); + } + + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R16Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R16Builder.java new file mode 100644 index 0000000..516d8ca --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R16Builder.java @@ -0,0 +1,40 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r15r16r17reports.r16report.ExecutionR16; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.google.common.base.Joiner; + +import java.util.Map; + +/** Builds a R15 Report from language, part Id, product, unit, and "type d'impression". */ +public class R16Builder extends AbstractR15R16R17Builder { + + @Override + protected ExecutionR16 make(Map data, String language) throws InsufficientParametersException { + // Get the request raw data + String idTopGeneric = data.get(ReportCriteriaEnum.PART_ID); // It's actually a Gen for R16 + String product = data.get(ReportCriteriaEnum.PRODUCT); + String unitStr = data.get(ReportCriteriaEnum.UNIT); + String typeImpression = data.get(ReportCriteriaEnum.TYPE_IMPRESSION); + + // Check presence of all required args + if (idTopGeneric == null || product == null || unitStr == null || typeImpression == null) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Missing parameter for R01 launch. Obtained: " + dataStr); + } + int unit; + try { + unit = Integer.parseInt(unitStr); + } catch (NumberFormatException e) { + throw new InsufficientParametersException("Unit parameter is not an int: " + unitStr, e); + } + ProductUnit aProductUnit = new ProductUnit(product, unit); + + // Build the report + return new ExecutionR16(aProductUnit, idTopGeneric, typeImpression, language); + } + + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R17Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R17Builder.java new file mode 100644 index 0000000..969a481 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R17Builder.java @@ -0,0 +1,14 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.definition.r15r16r17reports.r15r17reports.r17report.ExecutionR17; + +/** Builds a R15 Report from language, part Id & rev. */ +public class R17Builder extends AbstractR15R17Builder { + + @Override + protected ExecutionR17 make(String language, String partId, String partRevision) { + return new ExecutionR17(partId, partRevision, language); + } + + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R19Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R19Builder.java new file mode 100644 index 0000000..75c4bbe --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R19Builder.java @@ -0,0 +1,46 @@ +package com.capgemini.reports.builder; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r19report.ExecutionR19; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.google.common.base.Joiner; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import java.util.List; +import java.util.Map; + +/** + * Builds a R19 Report from document ID, Document revision, and document type. + */ +public class R19Builder implements ReportBuilder { + + @Override + public ExecutionR19 build(Map data) throws InsufficientParametersException { + // Get the request raw data + String documentId = data.get(ReportCriteriaEnum.DOCUMENT_ID); + String documentRev = data.get(ReportCriteriaEnum.DOCUMENT_REVISION); + String documentType = data.get(ReportCriteriaEnum.TYPE_OBJET); + + // Check presence of all required args + if (documentId == null || documentRev == null || documentType == null) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Missing parameter for R19 launch. Obtained: " + dataStr); + } + + try (TcSession session = new TcSession()) { + session.login(); + ItemRevisionQuery query = new ItemRevisionQuery(session); + query.searchType(documentType); + query.searchIDAndRevision(documentId, documentRev); + List results = query.findAll(); + ItemRevision doc = results.get(0); + return new ExecutionR19(documentId, documentRev, documentType, doc.getUid()); + } catch (NoTeamcenterConnectionException e) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Unable to retrieve document UID from id+rev. Request : " + dataStr, e); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R20Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R20Builder.java new file mode 100644 index 0000000..10670eb --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R20Builder.java @@ -0,0 +1,104 @@ +package com.capgemini.reports.builder; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r20report.Classe; +import com.capgemini.reports.definition.r20report.ConjointUnique; +import com.capgemini.reports.definition.r20report.ExecutionR20; +import com.capgemini.reports.definition.r20report.MajorMinor; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.google.common.base.Joiner; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** Builds a R20 Report from product/unit before & after, a String LMR list, plus various printing data. */ +public class R20Builder implements ReportBuilder { + + private static final String NO_LMR = "-"; + + @Override + public ExecutionR20 build(Map data) throws InsufficientParametersException { + // Get the request raw data + String productBefore = data.get(ReportCriteriaEnum.PRODUCT_BEFORE); + String productAfter = data.get(ReportCriteriaEnum.PRODUCT_AFTER); + String unitBeforeStr = data.get(ReportCriteriaEnum.UNIT_BEFORE); + String unitAfterStr = data.get(ReportCriteriaEnum.UNIT_AFTER); + String matricule = data.get(ReportCriteriaEnum.MATRICULE); + String lmrStr = data.get(ReportCriteriaEnum.LMR); + String classeStr = data.get(ReportCriteriaEnum.CLASSE); + String majorMinorStr = data.get(ReportCriteriaEnum.MAJOR_MINOR); + String conjointUniqueStr = data.get(ReportCriteriaEnum.CONJOINT_UNIQUE); + + // Check presence of all required args + if (productBefore == null || productAfter == null || unitBeforeStr == null || unitAfterStr == null || lmrStr == null || classeStr == null + || majorMinorStr == null || conjointUniqueStr == null) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Missing parameter for R20 launch. Obtained: " + dataStr); + } + + // Replacing null optional values by empty + if (matricule == null) { + matricule = StringHelper.EMPTY; + } + + // Present args in correct format + int unitBefore; + try { + unitBefore = Integer.parseInt(unitBeforeStr); + } catch (NumberFormatException e) { + throw new InsufficientParametersException("Unit Before is not an int: " + unitBeforeStr, e); + } + int unitAfter; + try { + unitAfter = Integer.parseInt(unitAfterStr); + } catch (NumberFormatException e) { + throw new InsufficientParametersException("Unit After is not an int: " + unitAfterStr, e); + } + MajorMinor majorMinor = MajorMinor.parse(majorMinorStr); + ProductUnit aProductUnitBefore = new ProductUnit(productBefore, unitBefore); + ProductUnit aProductUnitAfter = new ProductUnit(productAfter, unitAfter); + ConjointUnique conjointUnique = ConjointUnique.parse(conjointUniqueStr); + Classe classe = Classe.parse(classeStr); + List lmr = unpackLMR(lmrStr); + + // Build the report + return new ExecutionR20(aProductUnitBefore, aProductUnitAfter, matricule, lmr, classe, majorMinor, conjointUnique); + } + + private static final String LMR_SEPARATOR = ";"; // A semicolon (;) character + + + /** + * Unpacks a {@link #packLMR(List) packed} LMR list from the DB back to a {@link List} of strings. + * @param allLmrs a single String of all LMRs separated by a semicolon (or a simple dash if no LMR are found) + * @return a {@link List} of {@link String} MOD names + */ + private static List unpackLMR(final String allLmrs) { + List lmrList = new ArrayList<>(); + if (allLmrs == null || allLmrs.isEmpty() || NO_LMR.equals(allLmrs)) { + return lmrList; + } + String[] list = allLmrs.split(LMR_SEPARATOR); + Collections.addAll(lmrList, list); + return lmrList; + } + + /** + * Takes a List of String MOD names, packs it all in a single String to be saved to DB.
+ * Use {@link #unpackLMR(String)} to recover the original List. + * @param lmr the {@link List} of MOD names, as {@link String}s + * @return a single String with every LMR semicolon-separated (';'). If no LMRs, then outputs a dash '-'. + */ + public static String packLMR(final List lmr) { + String strLmr = ""; + for (String aMod : lmr) { + strLmr = aMod + LMR_SEPARATOR; + } + return strLmr.isEmpty() ? NO_LMR : strLmr; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R21Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R21Builder.java new file mode 100644 index 0000000..0aed29e --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R21Builder.java @@ -0,0 +1,46 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r21report.ExecutionR21; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.reports.parameters.DualGenerics; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.google.common.base.Joiner; + +import java.util.Map; + +/** Builds a R21 Report from BOM Configuration. Both Gen & GenAssemb must be there. */ +public class R21Builder implements ReportBuilder { + + @Override + public ExecutionR21 build(Map data) throws InsufficientParametersException { + // Get the request raw data + String product = data.get(ReportCriteriaEnum.PRODUCT); + String unitStr = data.get(ReportCriteriaEnum.UNIT); + String generic = data.get(ReportCriteriaEnum.GENERIC); + String genericAssemb = data.get(ReportCriteriaEnum.GENERIC_ASSEMB); + String effectivityStr = data.get(ReportCriteriaEnum.EFFECTIVITY_DATE); + + // Check presence of all required args + if (product == null || unitStr == null || generic == null || genericAssemb == null) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Missing parameter for R21 launch. Obtained: " + dataStr); + } + + // Present args in correct format + int unit; + try { + unit = Integer.parseInt(unitStr); + } catch (NumberFormatException e) { + throw new InsufficientParametersException("Unit parameter is not an int: " + unitStr, e); + } + ProductUnit aProductUnit = new ProductUnit(product, unit); + DualGenerics aGeneric = new DualGenerics(aProductUnit, generic, genericAssemb); + EffectivityDate anEffectivity = new EffectivityDate(effectivityStr); + + // Build the report + return new ExecutionR21(aProductUnit, aGeneric, anEffectivity); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R22Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R22Builder.java new file mode 100644 index 0000000..53bf5d0 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R22Builder.java @@ -0,0 +1,29 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r22report.ExecutionR22; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.google.common.base.Joiner; + +import java.util.Map; + +/** Builds a R22 Report from Part Id & rev. */ +public class R22Builder implements ReportBuilder { + + @Override + public ExecutionR22 build(Map data) throws InsufficientParametersException { + // Get the request raw data + String partId = data.get(ReportCriteriaEnum.PART_ID); + String partRevision = data.get(ReportCriteriaEnum.PART_REVISION); + + // Check presence of all required args + if (partId == null || partRevision == null) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Missing parameter for R22 launch. Obtained: " + dataStr); + } + + // Build the report + return new ExecutionR22(partId, partRevision); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R23Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R23Builder.java new file mode 100644 index 0000000..704efb4 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R23Builder.java @@ -0,0 +1,52 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r23report.ExecutionR23; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.reports.parameters.Generics; +import com.capgemini.reports.reports.parameters.MonoMulti; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.google.common.base.Joiner; + +import java.util.Map; + +/** + * Reconstructs a R23 report from BOM parameters. Generic parameters are optional. + */ +public class R23Builder implements ReportBuilder { + + @Override + public ExecutionR23 build(Map data) throws InsufficientParametersException { + // Get the request raw data + String product = data.get(ReportCriteriaEnum.PRODUCT); + String monoMultiStr = data.get(ReportCriteriaEnum.MONO_MULTI); + String generic = data.get(ReportCriteriaEnum.GENERIC); + String genericAssemb = data.get(ReportCriteriaEnum.GENERIC_ASSEMB); + String effectivityStr = data.get(ReportCriteriaEnum.EFFECTIVITY_DATE); + String superModelStr = data.get(ReportCriteriaEnum.SUPERMODEL); + String isWithFrozenUnitStr = data.get(ReportCriteriaEnum.WITH_FROZEN_UNIT); + String unitStr = data.get(ReportCriteriaEnum.UNIT); + String fromUnitStr = data.get(ReportCriteriaEnum.FROM_UNIT); + String frozenSinceLessThanStr = data.get(ReportCriteriaEnum.UNITS_FROZEN_SINCE_LESS_THAN); + + // Check presence of all required args + if (product == null || monoMultiStr == null) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Missing parameter for R23 launch. Obtained: " + dataStr); + } + ProductUnit aProductUnit = new ProductUnit(product, null); + Generics aGeneric = new Generics(aProductUnit, generic, genericAssemb); + MonoMulti aMonoMulti = MonoMulti.build(monoMultiStr); + EffectivityDate anEffectivity = new EffectivityDate(effectivityStr); + boolean isSuperModelBOM = Boolean.parseBoolean(superModelStr); + boolean isWithFrozenUnit = Boolean.parseBoolean(isWithFrozenUnitStr); + ProductUnit productUnitForUnit = new ProductUnit(product, unitStr); + ProductUnit productUnitFromUnit = new ProductUnit(product, fromUnitStr); + + + // Build the report + return new ExecutionR23(aProductUnit, aGeneric, aMonoMulti, anEffectivity, isSuperModelBOM, isWithFrozenUnit, productUnitForUnit, productUnitFromUnit, frozenSinceLessThanStr); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R24Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R24Builder.java new file mode 100644 index 0000000..60b2650 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R24Builder.java @@ -0,0 +1,52 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r24report.ExecutionR24; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.google.common.base.Joiner; + +import java.util.Map; + +/** Builds a R24 Report from language, part Id, product, unit, and "type d'impression". */ +public class R24Builder implements ReportBuilder { + + @Override + public AbstractExecutionReport build(Map data) throws InsufficientParametersException { + // Get the request raw data + String language = data.get(ReportCriteriaEnum.LANGUAGE); + + // Check presence of all required args + if (language == null) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Missing parameter for R24 launch. Obtained: " + dataStr); + } + + // Build the report + return make(data, language); + } + + protected ExecutionR24 make(Map data, String language) throws InsufficientParametersException { + /* Get the request raw data */ + String product = data.get(ReportCriteriaEnum.PRODUCT); + String unitStr = data.get(ReportCriteriaEnum.UNIT); + String typeImpression = data.get(ReportCriteriaEnum.TYPE_IMPRESSION); + + /* Check presence of all required args */ + if (product == null || unitStr == null || typeImpression == null) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Missing parameter for R24 launch. Obtained: " + dataStr); + } + int unit; + try { + unit = Integer.parseInt(unitStr); + } catch (NumberFormatException e) { + throw new InsufficientParametersException("Unit parameter is not an int: " + unitStr, e); + } + ProductUnit aProductUnit = new ProductUnit(product, unit); + + /* Build the report */ + return new ExecutionR24(aProductUnit, typeImpression, language); + } +} \ No newline at end of file diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R25Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R25Builder.java new file mode 100644 index 0000000..1244123 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R25Builder.java @@ -0,0 +1,46 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r25report.ExecutionR25; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.google.common.base.Joiner; + +import java.util.Map; + +/** Builds a R25 Report from language, part Id, product, unit, and "type d'impression". */ +public class R25Builder implements ReportBuilder { + + @Override + public AbstractExecutionReport build(Map data) throws InsufficientParametersException { + // Get the request raw data + String language = data.get(ReportCriteriaEnum.LANGUAGE); + + // Check presence of all required args + if (language == null) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Missing parameter for R25 launch. Obtained: " + dataStr); + } + + // Build the report + return make(data, language); + } + + + protected ExecutionR25 make(Map data, String language) throws InsufficientParametersException { + /* Get the request raw data */ + String product = data.get(ReportCriteriaEnum.PRODUCT); + String unitStr = data.get(ReportCriteriaEnum.UNIT); + String typeImpression = data.get(ReportCriteriaEnum.TYPE_IMPRESSION); + ProductUnit aProductUnit = new ProductUnit(product, unitStr); + + /* Check presence of all required args */ + if (product == null || typeImpression == null) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Missing parameter for R25 launch. Obtained: " + dataStr); + } + return new ExecutionR25(aProductUnit, typeImpression, language); + + } +} \ No newline at end of file diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R26Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R26Builder.java new file mode 100644 index 0000000..8c2e322 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R26Builder.java @@ -0,0 +1,31 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r26report.ExecutionR26; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.google.common.base.Joiner; + +import java.util.Map; + +/** Builds a R26 report from part Id and effectivity date (initialized to sysdate). */ +public class R26Builder implements ReportBuilder { + + @Override + public ExecutionR26 build(Map data) throws InsufficientParametersException { + // Get the request raw data + String component = data.get(ReportCriteriaEnum.PART_ID); + String effectivityStr = data.get(ReportCriteriaEnum.EFFECTIVITY_DATE); + + // Check presence of all required args + if (component == null) { + String dataStr = Joiner.on('|').withKeyValueSeparator("=").useForNull("null").join(data); + throw new InsufficientParametersException("Missing parameter for R26 launch. Obtained: " + dataStr); + } + + EffectivityDate anEffectivity = new EffectivityDate(effectivityStr); + + // Build the report + return new ExecutionR26(component, anEffectivity); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R27Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R27Builder.java new file mode 100644 index 0000000..09c62b6 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R27Builder.java @@ -0,0 +1,19 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r27report.ExecutionR27; + +import java.util.Map; + +/** + * Reconstructs a R27 report. + */ +public class R27Builder implements ReportBuilder { + + + @Override + public ExecutionR27 build(Map data) { + return new ExecutionR27(); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/R28Builder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/R28Builder.java new file mode 100644 index 0000000..897d86d --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/R28Builder.java @@ -0,0 +1,19 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r28report.ExecutionR28; + +import java.util.Map; + +/** + * Reconstructs a R28 report. + */ +public class R28Builder implements ReportBuilder { + + + @Override + public ExecutionR28 build(Map data) { + return new ExecutionR28(); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/builder/ReportBuilder.java b/kurt-utility/src/main/java/com/capgemini/reports/builder/ReportBuilder.java new file mode 100644 index 0000000..b4e4c11 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/builder/ReportBuilder.java @@ -0,0 +1,26 @@ +package com.capgemini.reports.builder; + +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.execution.AbstractExecutionReport; + +import java.util.Map; + +/** + * This interface allows creating a report from a map of functional {@link ReportCriteriaEnum}s and values.
+ * All ReportBuilders will be accessed via Reflection, so for future compatibility DO NOT move this package.
+ * Otherwise the fully-qualified class names (saved in DB for scheduled reports) will be lost.
+ * Also, all implementations must have a no-args constructor. + */ +public interface ReportBuilder { + /** + * Re-construct a report from its DB parameters. + * + * @param data the necessary data for reconstructing the report, obtained from the DB. + * + * @return the re-constructed report. + * + * @throws InsufficientParametersException if some required arguments are missing/non-understandable. + */ + AbstractExecutionReport build(Map data) throws InsufficientParametersException; +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/checkdata/CheckingDataHelper.java b/kurt-utility/src/main/java/com/capgemini/reports/checkdata/CheckingDataHelper.java new file mode 100644 index 0000000..20638ea --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/checkdata/CheckingDataHelper.java @@ -0,0 +1,77 @@ +package com.capgemini.reports.checkdata; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.database.DataBaseReportHelper; +import com.capgemini.reports.database.javabean.enumeration.ReportErrorTypeEnum; +import com.capgemini.reports.exceptions.FileLoadingException; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.reports.parameters.IChecker; +import lombok.extern.slf4j.Slf4j; + +/** This class allow to make a control on the user input parameters. */ +@Slf4j +public final class CheckingDataHelper { + private static final String COULD_NOT_LOAD_PROPERTY_POLICIES = "Could not load property policies"; + + private CheckingDataHelper() { + // nothing to do... + } + + /** + * Perform a quick check on each of the user input parameters.
+ * This method must return quickly, so the check may not be thorough. + * + * @param session the teamcenter session to use to check the parameters. + * @param abstractExecutionReport the report used to check parameters + * @throws FileLoadingException if unable to read policies + * @throws InvalidUserInputException if anything goes wrong with the checks + */ + public static void doQuickCheck(final TcSession session, final AbstractExecutionReport abstractExecutionReport) + throws InvalidUserInputException, FileLoadingException { + PolicyLocation propertyPolicyForChecks = abstractExecutionReport.getPropertyPolicyForLongChecks(); + + try { + session.setObjectPropPolicy(propertyPolicyForChecks); + } catch (InvalidConfigurationException e) { + throw new InvalidUserInputException(UserInputErrorEnum.INTERNAL_ERROR, e); + } + + // Perform each quick check + for (IChecker parameter : abstractExecutionReport.getQuickChecks()) { + parameter.check(session); + } + } + + /** + * Perform some in-depth checks of each of the user input parameters.
+ * + * @param session the teamcenter session to use to check the parameters. + * @param aAbstractExecutionReport the report on which the tests should be made + * @throws InvalidUserInputException if the checks failed (wrong parameters, or >maybe< the tc servers were busy) + */ + public static void doLongCheck(final TcSession session, + final AbstractExecutionReport aAbstractExecutionReport) throws InvalidUserInputException { + try { + session.setObjectPropPolicy(aAbstractExecutionReport.getPropertyPolicyForLongChecks()); + } catch (InvalidConfigurationException e) { + log.error(COULD_NOT_LOAD_PROPERTY_POLICIES); + throw new InvalidUserInputException(UserInputErrorEnum.INTERNAL_ERROR, e); + } + try { + /* Execute each long check */ + for (IChecker parameter : aAbstractExecutionReport.getLongChecks()) { + parameter.check(session); + } + } catch (InvalidUserInputException e) { + log.error("Some Long check highlighted anF error in the user-provided parameters", e); + DataBaseReportHelper.registerError(e.getErrorMessageForUser(), ReportErrorTypeEnum.FUNCTIONAL, + aAbstractExecutionReport.getReportTechnicalUid()); + throw e; + } + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/DataBaseReportHelper.java b/kurt-utility/src/main/java/com/capgemini/reports/database/DataBaseReportHelper.java new file mode 100644 index 0000000..aa720dd --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/DataBaseReportHelper.java @@ -0,0 +1,282 @@ +package com.capgemini.reports.database; + +import com.capgemini.framework.common.DateHelper; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.javabean.DbSchedulingReport; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.database.javabean.enumeration.ReportErrorTypeEnum; +import com.capgemini.reports.database.javabean.enumeration.ReportStateEnum; +import com.capgemini.reports.database.manager.AbstractHibernateManager; +import com.capgemini.reports.database.manager.MngReport; +import com.capgemini.reports.database.manager.MngSchedulingCriteriaVal; +import com.capgemini.reports.database.manager.MngSchedulingCriteriaVal.SchedulingCriteriaValue; +import com.capgemini.reports.database.manager.MngSchedulingReport; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.periodicity.SchedulingPeriod; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; + +import java.util.List; + +/** + * This class will allow to record every steps of the report's execution. + */ +@Slf4j +public final class DataBaseReportHelper { + + private DataBaseReportHelper() { + // Nothing to do here... + } + + /** + * Create the database record for the launch of this immediate or delayed report.
+ * This method is called in the report's servlet and save an image of this report in database after submitting it via the IHM. + * + * @param aAbstractExecutionReport will provide the report concerned + * @param userWhoRequestedTheLaunch the user that requested the launch + * @return the saved Report (image of the DB) + */ + public static DbReport registerLaunch(final AbstractExecutionReport aAbstractExecutionReport, final DbUser userWhoRequestedTheLaunch) { + DbReport theCreatedReport = null; + MngReport theReportManager = new MngReport(); + String theCode = aAbstractExecutionReport.getReportIdentifier().getReportCode(); + String theUid = aAbstractExecutionReport.getReportTechnicalUid(); + ReportLaunchTypeEnum launchType = aAbstractExecutionReport.getLaunchType(); + + // Specific status : must be WAIT or delayed reports or READY for immediate reports + ReportStateEnum reportState = (ReportLaunchTypeEnum.DELAYED.equals(launchType)) ? ReportStateEnum.WAIT : ReportStateEnum.READY; + + // Insert data in database + try { + theCreatedReport = theReportManager.insertWithCriteriaAndOwner(theCode, theUid, reportState, aAbstractExecutionReport.getLaunchData(), + userWhoRequestedTheLaunch); + String launchTypeStr = null; + switch (launchType) { + case DELAYED: + launchTypeStr = "Delayed report "; + break; + case IMMEDIATE: + launchTypeStr = "Report "; + break; + case SCHEDULED: + launchTypeStr = "Scheduled report "; + break; + case AUTOMATIC: + launchTypeStr = "Automatic report "; // Shouldn't happen + break; + } + log.info(launchTypeStr + theCode + " saved in database with UID: " + theUid); + } + catch (InvalidUserInputException e) { + log.error("Unable to store the report in database", e); + } + + return theCreatedReport; + } + + /** + * Update the database record of the delayed report.
+ * This method is called after waiting in Quartz queue. + * + * @param aReportTechnicalUid gives the report technical ID + * @return the saved Report (image of the DB) + * @throws NotFoundException if the report could not be found in the DB + */ + public static DbReport updateDelayedLaunch(final String aReportTechnicalUid) throws NotFoundException { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + Transaction transaction = session.beginTransaction(); + MngReport theReportManager = new MngReport(); + // Find the report to update + DbReport theExecutingReport = theReportManager.searchByUid(aReportTechnicalUid, session); + theExecutingReport.setState(ReportStateEnum.READY.toString()); + theReportManager.update(session, theExecutingReport); + transaction.commit(); + return theExecutingReport; + } + finally { + session.close(); + } + } + + /** + * Create the database record for the launch of this scheduled report.
+ * This method is called in the scheduled servlet of the report and save an image of the scheduling template of report in database after submitting it via the IHM. + * + * @param aAbstractExecutionReport will provide the report concerned + * @param userWhoRequestedTheLaunch the user that requested the launch + * @param schedulingCriteriaValues List<{@link SchedulingCriteriaValue}> - all the criteria associated to the report + * @param schedulingName String - the unique scheduling name + * @return the saved Report (image of the DB) + */ + public static DbSchedulingReport registerScheduledTemplate(final AbstractExecutionReport aAbstractExecutionReport, + final DbUser userWhoRequestedTheLaunch, final List schedulingCriteriaValues, final String schedulingName) { + MngSchedulingReport theReportManager = new MngSchedulingReport(); + ReportEnum theCode = aAbstractExecutionReport.getReportIdentifier(); + String theUid = aAbstractExecutionReport.getReportTechnicalUid(); + + // Insert data in database + DbSchedulingReport theCreatedReport = theReportManager.insertSchedulingReportWithCriteriaAndOwner(schedulingName, schedulingCriteriaValues, + aAbstractExecutionReport.getLaunchData(), userWhoRequestedTheLaunch, theCode); + + log.info("Scheduled report {} saved in database with UID: {}", theCode, theUid); + return theCreatedReport; + } + + /** + * Create the database record for the launch of this immediate or delayed report.
+ * This method is called in the report's servlet and save an image of this report in database after submitting it via the IHM. + * + * @param aAbstractExecutionReport will provide the report concerned + * @param usersWhoRequestedTheLaunch all the users that requested the launch + * @param schedulingReportId Long - the id of the scheduling if it exists + * @return the saved Report (image of the DB) + */ + public static DbReport registerScheduledLaunch(final AbstractExecutionReport aAbstractExecutionReport, + final List usersWhoRequestedTheLaunch, final Long schedulingReportId) throws InvalidUserInputException { + String theCode = aAbstractExecutionReport.getReportIdentifier().getReportCode(); + String theUid = aAbstractExecutionReport.getReportTechnicalUid(); + + // Insert data in database + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + Transaction transaction = session.beginTransaction(); + DbReport theCreatedReport = new MngReport().insertWithCriteriaAndOwners(session, theCode, theUid, ReportStateEnum.READY, aAbstractExecutionReport.getLaunchData(), + usersWhoRequestedTheLaunch, schedulingReportId); + transaction.commit(); + log.info("Scheduled report saved in database with UID: " + theUid); + return theCreatedReport; + } + finally { + session.close(); + } + } + + /** + * Create the database record for the start of the execution of this report. + * + * @param theReportManager the {@link MngReport} which will provide this report's UID in the DB, and is able to update its infos. + * @param aReportTechnicalUid gives the report technical ID + * @return the saved Report (image of the DB), never null + * @throws NotFoundException if the report Entry could not be found in the DB + */ + public static DbReport registerStart(final MngReport theReportManager, final String aReportTechnicalUid) throws NotFoundException { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + Transaction transaction = session.beginTransaction(); + DbReport theExecutingReport = theReportManager.searchByUid(aReportTechnicalUid, session); + theExecutingReport.setStartGenerationDate(DateHelper.getCurrentSqlTimestamp()); + theExecutingReport.setState(ReportStateEnum.EXECUTING.toString()); + theReportManager.update(session, theExecutingReport); + transaction.commit(); + return theExecutingReport; + } + finally { + session.close(); + } + } + + /** + * Create the database record for the successful completion of the execution of this report. + * + * @param theExecutingReport the dbReport entry + * @param fileNameWithExtension the file name of the created report + * @param theReportManager the {@link MngReport} which is able to update the report's infos. + */ + public static void registerCompletion(final DbReport theExecutingReport, final String fileNameWithExtension, final AbstractHibernateManager theReportManager) { + if (theExecutingReport != null) { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + Transaction transaction = session.beginTransaction(); + theExecutingReport.setEndGenerationDate(DateHelper.getCurrentSqlTimestamp()); + theExecutingReport.setState(ReportStateEnum.FINISHED.toString()); + theExecutingReport.setFileName(fileNameWithExtension); + theReportManager.update(session, theExecutingReport); + transaction.commit(); + } + finally { + session.close(); + } + } + } + + /** + * Save an error message for an executed report in the SB. + * + * @param anErrorMessage Content of the error message for the current executed report + * @param anErrorType Type of error (FUNCTIONAL or TECHNICAL) + * @param aReportTechnicalUid gives the report technical ID + */ + public static void registerError(final String anErrorMessage, final ReportErrorTypeEnum anErrorType, final String aReportTechnicalUid) { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + Transaction transaction = session.beginTransaction(); + MngReport theReportManager = new MngReport(); + DbReport theExecutingReport = theReportManager.searchByUid(aReportTechnicalUid, session); + theExecutingReport.setErrorMessage(anErrorMessage); + theExecutingReport.setErrorType(anErrorType.toString()); + theExecutingReport.setState(ReportStateEnum.FAILED.toString()); + theExecutingReport.setEndGenerationDate(DateHelper.getCurrentSqlTimestamp()); + theReportManager.update(session, theExecutingReport); + transaction.commit(); + } + catch (NotFoundException e) { + log.warn("Unable to find report " + aReportTechnicalUid + ", could not register this error: " + + anErrorMessage, e); + } + finally { + session.close(); + } + } + + /** + * Update the database record of a scheduled report. + * + * @param aSchedulingTemplateId the ID of the schedulingReport entry + * @param report the execution + * @param schedulingName the name of the scheduling (will overwrite the existing name + * @param period a {@link SchedulingPeriod} that will replace the existing periodicity + * @param dbUser the user who created r last updated the scheduling + * @return the saved {@link DbSchedulingReport} (image of the DB) + */ + public static DbSchedulingReport updateScheduling(final Long aSchedulingTemplateId, final AbstractExecutionReport report, + final String schedulingName, final SchedulingPeriod period, DbUser dbUser) { + log.debug("Updating scheduling: {}({}) at {} for {}({})", aSchedulingTemplateId, schedulingName, period.toString(), dbUser.getId(), + dbUser.getLogin()); + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + Transaction transaction = session.beginTransaction(); + // Find the report to update with the scheduling id received from the IHM (selected by the user) + MngSchedulingReport theReportManager = new MngSchedulingReport(); + DbSchedulingReport theScheduledReport = theReportManager.searchById(session, aSchedulingTemplateId); + theScheduledReport.setLastUpdate(DateHelper.getCurrentSqlTimestamp()); // Update LastUpdate time + theScheduledReport.setSchedulingName(schedulingName); // May have changed? Overwrite anyway + theScheduledReport.setAdminResponsibleId(dbUser.getId()); // Update responsible user + theReportManager.update(session, theScheduledReport); + + // Update all old criteria + MngSchedulingCriteriaVal theSchedulingCriteriaValManager = new MngSchedulingCriteriaVal(); + theSchedulingCriteriaValManager.updatePeriod(session, aSchedulingTemplateId, period); + theSchedulingCriteriaValManager.updateFunctionalParameters(session, aSchedulingTemplateId, report.getLaunchData()); + + // Commit all changes in DB + transaction.commit(); + return theScheduledReport; + } + finally { + session.close(); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/DbInit.java b/kurt-utility/src/main/java/com/capgemini/reports/database/DbInit.java new file mode 100644 index 0000000..04c7e7e --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/DbInit.java @@ -0,0 +1,107 @@ +package com.capgemini.reports.database; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.*; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; + +/** + * Database initialization using Hibernate. + **/ +@Slf4j +public class DbInit { + + private final MngCriteria criteriaManager; + private final MngCriteriaVal criteriaValManager; + private final MngReportType reportTypeManager; + private final MngReportOwner reportOwnerManager; + private final MngReport reportManager; + private final MngUser userManager; + + private static final String[] reports = + new String[]{"R01", "R03", "R05", "R06", "R07", "R10", "R11", "R13", "R15", "R16", "R17", "R19", "R20", "R21", "R22", "R23", "R24", "R26", "R27", "R28"}; + + /** + * Main entry point for initializer. + * + * @param args JAVA command arguments (should be empty) + */ + public static void main(final String[] args) { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + Transaction transaction = session.beginTransaction(); + try { + DbInit theInitializer = new DbInit(); + log.info("Create all objects"); + theInitializer.createAllObjects(session); + + log.info("Commit transaction"); + transaction.commit(); + + log.info("Display record count"); + theInitializer.displayRecordCount(session); + } + catch (Exception e) { + log.error("Unexpected error occured during database initialization", e); + log.warn("Rollback transaction"); + transaction.rollback(); + } + finally { + log.info("End of initialization"); + session.close(); + } + } + + private DbInit() { + criteriaManager = new MngCriteria(); + criteriaValManager = new MngCriteriaVal(); + reportManager = new MngReport(); + reportTypeManager = new MngReportType(); + userManager = new MngUser(); + reportOwnerManager = new MngReportOwner(); + } + + /** + * Sample objects creation. + */ + private void createAllObjects(Session session) { + log.info("Create users"); + userManager.insert(session, "infodba", "System", "Administrator", SettingsHelper.getDefaultExpeditorMailPassword()); + + log.info("Create criteria"); + for (ReportCriteriaEnum currentEnum : ReportCriteriaEnum.values()) { + String currentType = "string"; + String currentStrValue = currentEnum.toString(); + if (currentStrValue.startsWith("Unit")) { + currentType = "integer"; + } + else if (currentStrValue.startsWith("Date")) { + currentType = "date"; + } + criteriaManager.insert(session, currentEnum, currentType); + } + + log.info("Create report types"); + String defaultRevRule = SettingsHelper.getDefaultRevisionRule(); + for (String report : reports) { + reportTypeManager.insert(session, report, SettingsHelper.getString("title.REPORT_" + report), + Long.valueOf(SettingsHelper.getString("priority.REPORT_" + report)), + SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_" + report, defaultRevRule)); + } + } + + /** + * Display a summary of loaded objects. + * + * @param session*/ + private void displayRecordCount(Session session) { + log.info("Loaded user(s) count: " + reportManager.getList(session).size()); + log.info("Loaded criteria(s) count: " + criteriaManager.getList(session).size()); + log.info("Loaded criteria value(s) count: " + criteriaValManager.getList(session).size()); + log.info("Loaded report(s) count: " + userManager.getList(session).size()); + log.info("Loaded reportOwner(s) count: " + reportOwnerManager.getList(session).size()); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/HibernateUtil.java b/kurt-utility/src/main/java/com/capgemini/reports/database/HibernateUtil.java new file mode 100644 index 0000000..930fbdc --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/HibernateUtil.java @@ -0,0 +1,35 @@ +package com.capgemini.reports.database; + +import org.hibernate.SessionFactory; +import org.hibernate.cfg.Configuration; +import org.hibernate.service.ServiceRegistryBuilder; + +/** + * Utility class for Hibernate accesses. + **/ +public final class HibernateUtil { + private static final SessionFactory SESSION_FACTORY = buildSessionFactory(); + + private HibernateUtil() { + // Nothing to do... + } + + /** + * Creating a session factory, if not already loaded. + **/ + private static SessionFactory buildSessionFactory() { + Configuration configuration = new Configuration(); + configuration.configure(); + return configuration.buildSessionFactory(new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry()); + } + + /** + * Getter for the factory instance. + * + * @return Factory instance + **/ + public static SessionFactory getSessionFactory() { + return SESSION_FACTORY; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbCriteria.java b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbCriteria.java new file mode 100644 index 0000000..5e46fe7 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbCriteria.java @@ -0,0 +1,34 @@ +package com.capgemini.reports.database.javabean; + +import java.io.Serializable; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** Persisted object in table CRITERIA. **/ +@Getter +@Setter +@ToString +public class DbCriteria implements Serializable, IPersistedObject { + + /** Required by serialization. **/ + private static final long serialVersionUID = 1L; + + /** Unique identifier recommended for using all features from Hibernate. **/ + private Long id; + + /** Criteria label. **/ + private String criteriaName; + + /** Data type. **/ + private String criteriaType; + + /** Data type. default false **/ + private String isTemporel; + + /** JAVA convention requires an empty constructor for each JAVA bean. **/ + public DbCriteria() { + // Nothing to see, move along... + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbCriteriaVal.java b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbCriteriaVal.java new file mode 100644 index 0000000..1e01dd2 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbCriteriaVal.java @@ -0,0 +1,34 @@ +package com.capgemini.reports.database.javabean; + +import java.io.Serializable; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** Persisted object in table CRITERIA_VAL for criteria values. **/ +@Getter +@Setter +@ToString +public class DbCriteriaVal implements Serializable, IPersistedObject { + + /** Required by serialization. **/ + private static final long serialVersionUID = 1L; + + /** Unique identifier recommended for using all features from Hibernate. **/ + private Long id; + + /** Linked criteria. **/ + private DbCriteria criteria; + + /** Criteria value. **/ + private String criteriaValue; + + /** Identifier of the linked report. **/ + private Long reportId; + + /** JAVA convention requires an empty constructor for each JAVA bean. **/ + public DbCriteriaVal() { + // Nothing to see, move along... + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbMemMonitor.java b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbMemMonitor.java new file mode 100644 index 0000000..ec4b4a2 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbMemMonitor.java @@ -0,0 +1,39 @@ +package com.capgemini.reports.database.javabean; + +import java.io.Serializable; +import java.sql.Timestamp; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** Persisted object in table MEM_MONITOR. **/ +@Getter +@Setter +@ToString +public class DbMemMonitor implements Serializable, IPersistedObject { + + /** Required by serialization. **/ + private static final long serialVersionUID = 1L; + + /** Unique identifier recommended for using all features from Hibernate. **/ + private Long id; + + /** Current date when the trace has been saved in database. **/ + private Timestamp monitorDate; + + /** Global amount of reserved memory. **/ + private Double totalMemory; + + /** Maximum amount of memory which could be reserved. **/ + private Double maxMemory; + + /** Current amount of free memory. **/ + private Double freeMemory; + + /** Current amount of used memory. **/ + private Double usedMemory; + + /** Percent of memory used compared to maximum limit. **/ + private Double maxPercent; +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbReport.java b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbReport.java new file mode 100644 index 0000000..4cfc0c1 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbReport.java @@ -0,0 +1,77 @@ +package com.capgemini.reports.database.javabean; + +import java.io.Serializable; +import java.sql.Timestamp; + +import com.capgemini.framework.common.DateHelper; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** Persisted object in table REPORT. **/ +@Getter +@Setter +@ToString +public class DbReport implements Serializable, IPersistedObject { + + /** Required by serialization. **/ + private static final long serialVersionUID = 1L; + + /** Unique identifier recommended for using all features from Hibernate. **/ + private Long id; + + /** Identification code for the report, ie: R01, R22... **/ + private String reportCode; + + /** Date when the generation started. **/ + private Timestamp startGenerationDate; + + /** Date when the generation ended. **/ + private Timestamp endGenerationDate; + + /** Duration of the generation. **/ + private Long generationDuration; + + /** Unique identifier of the report. **/ + private String reportUid; + + /** Current report state (WAITING, INWORK, FAILED, COMPLETED). **/ + private String state; + + /** Content of error message when state is "FAILED". **/ + private String errorMessage; + + /** Type of the error: FUNCTIONAL or TECHNICAL (ie: JAVA Exception). **/ + private String errorType; + + /** Physical file name on disk. **/ + private String fileName; + + /** Technical field only for filtering for statistics. **/ + private String monthPeriod; + + /** Identifier of the scheduling report. **/ + private Long schedulingReportId; + + /** JAVA convention requires an empty constructor for each JAVA bean. **/ + public DbReport() { + // Nothing to see, move along... + } + + /** + * Override of the lombok setter. + * + * @param aTimestamp Set value + **/ + public void setEndGenerationDate(final Timestamp aTimestamp) { + + endGenerationDate = aTimestamp; + setMonthPeriod(DateHelper.getMonthPeriod()); + + /* Compute duration */ + if ((startGenerationDate != null) && (endGenerationDate != null)) { + generationDuration = endGenerationDate.getTime() - startGenerationDate.getTime(); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbReportOwner.java b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbReportOwner.java new file mode 100644 index 0000000..4f48a6d --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbReportOwner.java @@ -0,0 +1,50 @@ +package com.capgemini.reports.database.javabean; + +import java.io.Serializable; +import java.sql.Timestamp; + +import com.capgemini.framework.common.DateHelper; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** Persisted object in table REP_USER. **/ +@Getter +@Setter +@ToString +public class DbReportOwner implements Serializable, IPersistedObject { + + /** Required by serialization. **/ + private static final long serialVersionUID = 4697006911693586324L; + + /** Unique identifier recommended for using all features from Hibernate. **/ + private Long id; + + /** User ID: must be unique in database. **/ + private Long userId; + + /** Report Id: must be unique in database. **/ + private Long reportId; + + /** Date of the last connection of the user, matching with the last LDAP data synchronization. **/ + private Timestamp requestDate; + + /** Technical field only for filtering for statistics. **/ + private String monthPeriod; + + /** + * Override of the lombok setter. + * + * @param aTimestamp Set value + **/ + public void setRequestDate(final Timestamp aTimestamp) { + requestDate = aTimestamp; + setMonthPeriod(DateHelper.getMonthPeriod()); + } + + /** JAVA convention requires an empty constructor for each JAVA bean. **/ + public DbReportOwner() { + // Nothing to see, move along... + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbReportType.java b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbReportType.java new file mode 100644 index 0000000..ac11d6b --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbReportType.java @@ -0,0 +1,43 @@ +package com.capgemini.reports.database.javabean; + +import java.io.Serializable; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** Persisted object in table REPORT_TYPE. **/ +@Getter +@Setter +@ToString +public class DbReportType implements Serializable, IPersistedObject { + + /** Required by serialization. **/ + private static final long serialVersionUID = 1L; + + /** Unique identifier recommended for using all features from Hibernate. **/ + private Long id; + + /** Identification code for the report, ie: R01, R22... **/ + private String code; + + /** Priority in queue. **/ + private Long priority; + + /** Title of the report. **/ + private String title; + + /** Name of the revision rule. **/ + private String revisionRule; + + /** If 'TRUE' then the report can be launched interactively by the users. Defaults to 'TRUE' **/ + private String reportAuthorized; + + /** If 'TRUE' then the report can be launched scheduled. Defaults to 'FALSE'. **/ + private String isCandidateForScheduling; + + /** JAVA convention requires an empty constructor for each JAVA bean. **/ + public DbReportType() { + // Nothing to see, move along... + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbSchedulingCriteriaVal.java b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbSchedulingCriteriaVal.java new file mode 100644 index 0000000..bb92052 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbSchedulingCriteriaVal.java @@ -0,0 +1,35 @@ +package com.capgemini.reports.database.javabean; + +import java.io.Serializable; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + + +/** Persisted object in table CRITERIA. **/ +@Getter +@Setter +@ToString +public class DbSchedulingCriteriaVal implements Serializable, IPersistedObject { + + /** Required by serialization. **/ + private static final long serialVersionUID = -7663074318747139689L; + + /** Identifier of the linked report. **/ + private Long id; + + /** Linked dbSchedulignCriteria. **/ + private DbCriteria dbCriteria; + + /** Criteria value. **/ + private String criteriaValue; + + /** Identifier of the linked report. **/ + private Long schedulingReportId; + + /** JAVA convention requires an empty constructor for each JAVA bean. **/ + public DbSchedulingCriteriaVal() { + // Nothing to do + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbSchedulingReport.java b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbSchedulingReport.java new file mode 100644 index 0000000..fc88cb3 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbSchedulingReport.java @@ -0,0 +1,38 @@ +package com.capgemini.reports.database.javabean; + +import java.io.Serializable; +import java.sql.Timestamp; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** Persisted object in table SCHEDULING_REPORT. **/ +@Getter +@Setter +@ToString +public class DbSchedulingReport implements Serializable, IPersistedObject { + + /** Required by serialization. **/ + private static final long serialVersionUID = -451309740204083348L; + + /** Unique identifier recommended for using all features from Hibernate. **/ + private Long id; + + /** name of scheduling must be unique. **/ + private String schedulingName; + + /** Code of scheduling report. **/ + private String reportCode; + + /** Date when an admin last updated this. **/ + private Timestamp lastUpdate; + + /** ID of responsible admin. **/ + private Long adminResponsibleId; + + /** JAVA convention requires an empty constructor for each JAVA bean. **/ + public DbSchedulingReport() { + // Nothing to do, hihihi.... + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbUser.java b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbUser.java new file mode 100644 index 0000000..b73daf7 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/DbUser.java @@ -0,0 +1,89 @@ +package com.capgemini.reports.database.javabean; + +import com.capgemini.framework.common.activedirectory.ActiveDirectory; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.io.Serializable; +import java.sql.Date; + +/** Persisted object in table REP_USER. **/ +@Getter +@Setter +@ToString +public class DbUser implements Serializable, IPersistedObject { + + /** Required by serialization. **/ + private static final long serialVersionUID = 1L; + + /** Unique identifier recommended for using all features from Hibernate. **/ + private Long id; + + /** User login: must be unique in database. **/ + private String login; + + /** User email (synchronized with the LDAP). **/ + private String email; + + /** User surname (synchronized with the LDAP). **/ + private String surname; + + /** User first name (synchronized with the LDAP). **/ + private String firstname; + + /** Date of the last connection of the user, matching with the last LDAP data synchronization. **/ + private Date lastConnectionDate; + + /** user role, default to false. **/ + private String isAdmin = "FALSE"; + + /** JAVA convention requires an empty constructor for each JAVA bean. isAdmin **/ + public DbUser() { + // Nothing to see, move along... + } + + /** + * Returns true if both this DB entry and the provided user data match (all fields must be equal). + * + * @param user the {@link UserData} to be compared to this + * @return true if they are the same, false otherwise + */ + public boolean sameAs(final UserData user) { + if (user == null) { + return false; + } + boolean loginOk = login != null && login.equals(user.login); + boolean emailOk = email != null && email.equals(user.email); + boolean surnameOk = surname != null && surname.equals(user.surname); + boolean firstNameOk = firstname != null && firstname.equals(user.firstName); + return loginOk && emailOk && surnameOk && firstNameOk; + } + + /** POJO containing various information on a user. */ + @Getter + public static class UserData { + private final String login; + private final String email; + private final String firstName; + private final String surname; + private final boolean admin; + + public UserData(String login, String email, String firstName, String surname, boolean admin) { + this.login = login; + this.email = email; + this.firstName = firstName; + this.surname = surname; + this.admin = admin; + } + } + + /** + * Returns true if the user is Guest (identified by login='Invité(e)'). + * + * @return true if the user is a guest + */ + public boolean isGuest() { + return ActiveDirectory.GUEST_LOGIN.equals(login); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/IPersistedObject.java b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/IPersistedObject.java new file mode 100644 index 0000000..227a969 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/IPersistedObject.java @@ -0,0 +1,6 @@ +package com.capgemini.reports.database.javabean; + +/** Common interface for all JAVA beans persisted through Hibernate. **/ +public interface IPersistedObject { + // This interface is just to regroup all DB elements +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/enumeration/ReportCriteriaEnum.java b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/enumeration/ReportCriteriaEnum.java new file mode 100644 index 0000000..d398ed4 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/enumeration/ReportCriteriaEnum.java @@ -0,0 +1,136 @@ +package com.capgemini.reports.database.javabean.enumeration; + +import com.capgemini.reports.database.javabean.DbCriteria; +import com.capgemini.reports.database.javabean.DbSchedulingCriteriaVal; + +import java.util.HashMap; +import java.util.Map; + + +/** List of criteria values. Any change made to this class must be mirrored in the installation script of the database. **/ +public enum ReportCriteriaEnum { + + /** + * TcEffectivity date. + */ + EFFECTIVITY_DATE("Date d'effectivité"), + /** Generic ID. */ + GENERIC("Générique"), + /** Generic Assemb ID. */ + GENERIC_ASSEMB("Générique montage"), + /** Nomenclature explosion level (MONO/MULTI). */ + MONO_MULTI("Niveau"), + /** Part ID. */ + PART_ID("Numéro d'article"), + /** Revision of the item. */ + PART_REVISION("Révision"), + /** Document ID. */ + DOCUMENT_ID("Numéro document"), + /** Revision of the document. */ + DOCUMENT_REVISION("Document Révision"), + /** Product ID. */ + PRODUCT("Produit"), + /** Unit number. */ + UNIT("Unit"), + /** Unit before. */ + UNIT_BEFORE("Unit précédent"), + /** unit after. */ + UNIT_AFTER("Unit suivant"), + /** Product before. */ + PRODUCT_BEFORE("Produit précédent"), + /** Product after. */ + PRODUCT_AFTER("Produit suivant"), + /** Engine number. */ + MATRICULE("Matricule moteur"), + /** List of removed modifications. */ + LMR("LMR"), + /** Class. */ + CLASSE("Classe"), + /** Major/Minor. */ + MAJOR_MINOR("Majeur mineur"), + /** Conjoint/Unique. */ + CONJOINT_UNIQUE("Conjoint unique"), + /** Language. */ + LANGUAGE("Langue"), + /** Print type. */ + TYPE_IMPRESSION("Type d'impression"), + /** Start date. */ + DATE_DEBUT("Date de début"), + /** End date. */ + DATE_FIN("Date de fin"), + /** Object type. */ + TYPE_OBJET("Type d'objet"), + /** Unit number in configuration 1. */ + UNIT_CONFIGURATION_1("Unit configuration 1"), + /** Unit number in configuration 2. */ + UNIT_CONFIGURATION_2("Unit configuration 2"), + /** Règle de révision. */ + REVISION_RULE("Règle de révision"), + /** Item */ + ITEM("Item"), + /** Supermodel */ + SUPERMODEL("SuperModel"), + /** Avec le(s) unit(s) gelé(s) */ + WITH_FROZEN_UNIT("Avec le(s) unit(s) gelé(s)"), + /** A partir de Unit */ + FROM_UNIT("A partir de Unit"), + /** Units gelés il y a moins de */ + UNITS_FROZEN_SINCE_LESS_THAN("Units gelés il y a moins de"); + + /** Human readable value for the enumeration. **/ + private final String criteriaValue; + + /** Enumeration cache for conversions. **/ + private static Map enumMap; + + /** Enumeration constructor. **/ + ReportCriteriaEnum(final String aCriteriaValue) { + criteriaValue = aCriteriaValue; + } + + /** + * Getter for object string value. + * + * @return String value with readable format + **/ + @Override + public String toString() { + return criteriaValue; + } + + /** + * Conversion from String to SnecmaObjectTypeEnum. + * + * @param aCriteriaValue String value of the criteria + * @return Enumeration instance for the requested value + **/ + public static synchronized ReportCriteriaEnum getEnum(final String aCriteriaValue) { + if (enumMap == null) { + enumMap = new HashMap<>(); + for (ReportCriteriaEnum currentEnum : ReportCriteriaEnum.values()) { + enumMap.put(currentEnum.toString(), currentEnum); + } + } + return enumMap.get(aCriteriaValue); + } + + /** + * Conversion from {@link DbSchedulingCriteriaVal} to {@link ReportCriteriaEnum}. Uses the enum's criteriaValue property for string matching. + * + * @param criteria String value of the criteria + * @return Enumeration instance for the requested value + **/ + public static synchronized ReportCriteriaEnum valueOf(final DbSchedulingCriteriaVal criteria) { + return getEnum(criteria.getDbCriteria().getCriteriaName()); + } + + /** + * Conversion from {@link DbCriteria} to {@link ReportCriteriaEnum}. Uses the enum's criteriaValue property for string matching. + * + * @param criteria a {@link DbCriteria} + * @return Enumeration instance for the requested value + **/ + public static synchronized ReportCriteriaEnum valueOf(final DbCriteria criteria) { + return getEnum(criteria.getCriteriaName()); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/enumeration/ReportErrorTypeEnum.java b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/enumeration/ReportErrorTypeEnum.java new file mode 100644 index 0000000..d5199eb --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/enumeration/ReportErrorTypeEnum.java @@ -0,0 +1,9 @@ +package com.capgemini.reports.database.javabean.enumeration; + +/** The type of report errors: Technical errors (bug in the code) or Functional (user doesn't know what he/she's doing. */ +public enum ReportErrorTypeEnum { + /** The user doesn't know what he's doing. */ + FUNCTIONAL, + /** Bug in the code / environment. */ + TECHNICAL +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/enumeration/ReportStateEnum.java b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/enumeration/ReportStateEnum.java new file mode 100644 index 0000000..0b4d746 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/enumeration/ReportStateEnum.java @@ -0,0 +1,31 @@ +package com.capgemini.reports.database.javabean.enumeration; + +/** + * Represents the state of a report execution. + */ +public enum ReportStateEnum { + /** + * The report has been submitted and its parameters have been checked. The report is delayed or scheduled and is still waiting for being putting in the Queue. + */ + WAIT, + /** + * The report has been submitted and its parameters have been checked. It is waiting in a Queue. + */ + READY, + /** + * The report is being executed, it just got out of its queue. + */ + EXECUTING, + /** + * During the execution, the report generated an error. + */ + FAILED, + /** + * The report has successfully completed. It generated a file, which is awaiting for download. + */ + FINISHED, + /** + * The report State is unknown. + */ + UNKNOWN +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/enumeration/SchedulingEnum.java b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/enumeration/SchedulingEnum.java new file mode 100644 index 0000000..adb6e1c --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/javabean/enumeration/SchedulingEnum.java @@ -0,0 +1,59 @@ +package com.capgemini.reports.database.javabean.enumeration; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.HashMap; +import java.util.Map; + +/** KEYS of CriteriaValue in DB. Please use {@link SchedulingEnum#getEnum(String)} to obtain an instance from its DB value. */ +@AllArgsConstructor +@Getter +public enum SchedulingEnum { + + /** Key to the declared periodicity. Values are 'daily', 'weekly', 'weekend', 'date'. */ + PERIOD("period"), + /** Key to schedule every days (Monday to Sunday). No value required. */ + DAILY("daily"), + /** Key to schedule once every week (Monday to Friday only). Values available: 1, 2, 3, 4, 5. */ + WEEKLY("weekly"), + /** Key to schedule a specific day of every month. Values availble: 1, 2, 3... 31, 'we_1', 'we_2', 'we_3', 'we_4', 'we_5', 'we_6' <-- for end of month. */ + WEEKEND("weekend"), + /** scheduling by date. */ + DATE("date"), + /** value of month. */ + DAY_IN_MONTH_VALUE("day_in_month_value"); + + /** Human readable name for the enumeration. **/ + private final String criteriaName; + + /** Enumeration cache for conversions. **/ + private static final Map enumMap; + + static { + enumMap = new HashMap<>(); + for (SchedulingEnum currentEnum : SchedulingEnum.values()) { + enumMap.put(currentEnum.toString(), currentEnum); + } + } + + /** + * Getter for object string value. + * + * @return String value with readable format + **/ + @Override + public String toString() { + return criteriaName; + } + + /** + * Conversion from String to SchedulingEnum. + * + * @param aSchedulingCriteriaValue String value of the criteria + * @return Enumeration instance for the requested value + **/ + public static synchronized SchedulingEnum getEnum(final String aSchedulingCriteriaValue) { + return enumMap.get(aSchedulingCriteriaValue); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/manager/AbstractHibernateManager.java b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/AbstractHibernateManager.java new file mode 100644 index 0000000..b2178bf --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/AbstractHibernateManager.java @@ -0,0 +1,106 @@ +package com.capgemini.reports.database.manager; + +import com.capgemini.reports.database.javabean.IPersistedObject; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.Transaction; + +import java.util.ArrayList; +import java.util.List; + +/** + * Common methods for all Hibernate managers. + * + * @param The type of {@link IPersistedObject} which is meing managed + **/ +public abstract class AbstractHibernateManager { + + private static final String KEY_COLUMN_VALUE = "colValue1"; + private static final String FROM = "FROM "; + + /** + * Common method for searching object by its ID. + */ + public T searchById(Session session, final Long aTechnicalId) { + @SuppressWarnings("unchecked") + T entry = (T) session.load(getManagedClass(), aTechnicalId); + return entry; + } + + /** + * Parent method for coding easily a search query on a specific column. + */ + T searchBy(Session session, final String aColumn, final String aColumnValue) { + Query query = session.createQuery(FROM + getManagedClass().getName() + " r where r." + aColumn + "= :" + KEY_COLUMN_VALUE); + query.setString(KEY_COLUMN_VALUE, aColumnValue); + + List list = query.list(); + T theResult = null; + if (!list.isEmpty()) { + theResult = getManagedClass().cast(list.get(0)); + } + return theResult; + } + + /** + * Parent method for coding easily a search query on a specific column. + */ + List searchAndReturnAllValues(Session session, final String aColumn, final Long aColumnValue) { + Query query = session.createQuery(FROM + getClassName() + " r where r." + aColumn + " = :" + KEY_COLUMN_VALUE); + query.setLong(KEY_COLUMN_VALUE, aColumnValue); + List list = query.list(); + if (!list.isEmpty()) { + @SuppressWarnings("unchecked") + List typedList = (List) list; + return typedList; + } + else { + return new ArrayList<>(); + } + } + + /** + * List all objects of the managed type. + */ + public List getList(Session session) { + return castAll(session.createQuery(FROM + getClassName()).list()); + } + + List castAll(final List rawList) { + List typedList = new ArrayList<>(); + for (Object obj : rawList) { + typedList.add(getManagedClass().cast(obj)); + } + return typedList; + } + + /** + * Update the referenced object. + */ + public void update(Session session, final T aPersistedObj) { + session.update(aPersistedObj); + } + + /** + * Delete the referenced object. + */ + public void delete(Session session, final T aPersistedObj) { + session.delete(aPersistedObj); + } + + /** + * Getter for the class name of the current object. + * + * @return The class name value (without package) + */ + private String getClassName() { + return getManagedClass().getSimpleName(); + } + + /** + * Getter for the JAVA bean class managed by this Hibernate manager instance. + * + * @return The class value (without package) + */ + protected abstract Class getManagedClass(); +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngCriteria.java b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngCriteria.java new file mode 100644 index 0000000..15597d6 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngCriteria.java @@ -0,0 +1,35 @@ +package com.capgemini.reports.database.manager; + +import com.capgemini.reports.database.javabean.DbCriteria; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import org.hibernate.Session; + +/** Hibernate manager for DBCriteria JAVA bean. **/ +public class MngCriteria extends AbstractHibernateManager { + + @Override + public Class getManagedClass() { + return DbCriteria.class; + } + + /** + * Create a new persistent object for criteria. + */ + public DbCriteria insert(Session session, final ReportCriteriaEnum aCriteriaName, final String aType) { + DbCriteria theCriteria = new DbCriteria(); + // Set specific attribute values + theCriteria.setCriteriaName(aCriteriaName.toString()); + theCriteria.setCriteriaType(aType); + + // Persist object + session.save(theCriteria); + return theCriteria; + } + + /** + * Search query for retrieving Criteria using its name. + */ + DbCriteria searchByName(Session session, final String aName) { + return searchBy(session, "criteriaName", aName); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngCriteriaVal.java b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngCriteriaVal.java new file mode 100644 index 0000000..b147e09 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngCriteriaVal.java @@ -0,0 +1,145 @@ +package com.capgemini.reports.database.manager; + +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbCriteria; +import com.capgemini.reports.database.javabean.DbCriteriaVal; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * Hibernate manager for DbCriteriaVal JAVA bean. + **/ +@Slf4j +public class MngCriteriaVal extends AbstractHibernateManager { + + // Keys + private static final String KEY_REPORT_UID = "reportUID"; + private static final String KEY_REPORT_ID = "reportId"; + + // Queries + private static final String QUERY_CRITERIA_BY_REPORT_UID; + private static final String QUERY_CRITERIA_BY_REPORT_ID; + + static { + String select = "select T2.criteriaName, T1.criteriaValue "; + String from = "from DbReport T0, DbCriteriaVal T1, DbCriteria T2 "; + String whereCoherence = "where T0.id = T1.reportId and T1.criteria = T2.id "; + String whereReportUID = "and T0.reportUid = :" + KEY_REPORT_UID + " "; + String whereReportID = "and T0.id = :" + KEY_REPORT_ID + " "; + String orderBy = "order by T2.id"; + QUERY_CRITERIA_BY_REPORT_UID = select + from + whereCoherence + whereReportUID + orderBy; + QUERY_CRITERIA_BY_REPORT_ID = select + from + whereCoherence + whereReportID + orderBy; + } + + @Override + public Class getManagedClass() { + return DbCriteriaVal.class; + } + + /** + * Create a new criteria value. + */ + private DbCriteriaVal insert(Session session, final DbCriteria aCriteria, final String aCriteriaValue, final Long aReportId) { + log.trace("Inserting DbCriteria entry {}({}) = {} for report {}", aCriteria.getId(), aCriteria.getCriteriaName(), aCriteriaValue, aReportId); + DbCriteriaVal theCriteriaVal = new DbCriteriaVal(); + + theCriteriaVal.setCriteria(aCriteria); + theCriteriaVal.setCriteriaValue(aCriteriaValue); + theCriteriaVal.setReportId(aReportId); + + // Persist object + session.save(theCriteriaVal); + + return theCriteriaVal; + } + + /** + * Create a new criteria value using the criteria name as key. + */ + DbCriteriaVal insertByCriteriaName(Session session, final String aCriteriaName, final String aCriteriaValue, final Long aReportId) { + // Search the corresponding criteria using its name + DbCriteria theCriteria = new MngCriteria().searchByName(session, aCriteriaName); + + return insert(session, theCriteria, aCriteriaValue, aReportId); + } + + /** + * Search in database the list of criteria for a specific report using its UID. + */ + public List searchCriteriasByReportUID(final String aReportUid) { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + Query theQuery = session.createQuery(QUERY_CRITERIA_BY_REPORT_UID); + theQuery.setString(KEY_REPORT_UID, aReportUid); + + List result = new ArrayList<>(); + for (Object[] reportData : (List) theQuery.list()) { + result.add(new CriteriaValue((String) reportData[0], (String) reportData[1])); + } + return result; + } + finally { + session.close(); + } + } + + /** + * Search in database the list of criteria for a specific report using its identifier. + */ + List searchCriteriasByReportID(Session session, final long aReportID) { + Query theQuery = session.createQuery(QUERY_CRITERIA_BY_REPORT_ID); + theQuery.setLong(KEY_REPORT_ID, aReportID); + + List result = new ArrayList<>(); + for (Object[] reportData : (List) theQuery.list()) { + result.add(new CriteriaValue((String) reportData[0], (String) reportData[1])); + } + return result; + } + + /** + * Bean object carrying a report criteria's name and value. + */ + @Getter + public static class CriteriaValue { + + private static final String NULL_STRING = "null"; + private final String name; + private final String value; + + /** + * Builds a Criteria Name-Value object. + * + * @param name if null, will be 'null' + * @param value if null, will be 'null' + */ + protected CriteriaValue(final String name, final String value) { + this.name = name == null ? NULL_STRING : name; + this.value = (value == null || value.isEmpty() || "null".equals(value)) ? NULL_STRING : value; + } + + /** + * Builds a Criteria Name-Value object. + * + * @param criteria if null, will be 'null' + * @param value if null, will be 'null' + */ + public CriteriaValue(final ReportCriteriaEnum criteria, final String value) { + this.name = criteria == null ? NULL_STRING : criteria.toString(); + this.value = value == null ? NULL_STRING : value; + } + + @Override + public String toString() { + return name + " = " + value; + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngMemMonitor.java b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngMemMonitor.java new file mode 100644 index 0000000..8990983 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngMemMonitor.java @@ -0,0 +1,97 @@ +package com.capgemini.reports.database.manager; + +import com.capgemini.framework.common.DateHelper; +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbMemMonitor; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; + +import java.sql.Timestamp; +import java.util.Date; +import java.util.List; + +/** + * Hibernate manager for DBReport JAVA bean. + **/ +public class MngMemMonitor extends AbstractHibernateManager { + + private static final int THOUSAND = 1000; + private static final int FIVE = 5; + /** + * Quantity of trace displayed. + **/ + private static final int MAX_MONITOR_TRACE_COUNT = SettingsHelper.getMemoryMaxCount(); + /** + * Elapsed seconds between each trace. + **/ + private static final int MONITOR_FREQUENCY = SettingsHelper.getMemoryFrequency(); + + @Override + public Class getManagedClass() { + return DbMemMonitor.class; + } + + /** + * Create a memory monitoring trace. + * + * @param aFreeMemory free memory + * @param anUsedMemory used memory + * @param aMaxMemory max memory in session + * @param aMaxPercent max memory percent + * @param aTotalMemory total memory + * @return Monitoring trace object + */ + public DbMemMonitor insert(final Double aFreeMemory, final Double anUsedMemory, final Double aMaxMemory, final Double aMaxPercent, + final Double aTotalMemory) { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + Transaction transaction = session.beginTransaction(); + DbMemMonitor theMemMonitor = new DbMemMonitor(); + + // Assign default attribute values + theMemMonitor.setMonitorDate(DateHelper.getCurrentSqlTimestamp()); + + // Assign specific attribute values + theMemMonitor.setFreeMemory(aFreeMemory); + theMemMonitor.setMaxMemory(aMaxMemory); + theMemMonitor.setMaxPercent(aMaxPercent); + theMemMonitor.setTotalMemory(aTotalMemory); + theMemMonitor.setUsedMemory(anUsedMemory); + + // Persist object + session.save(theMemMonitor); + transaction.commit(); + + return theMemMonitor; + } + finally { + session.close(); + } + } + + /** + * Search last memory monitor traces. + */ + public List searchMemMonitor() { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + String theHqlQuery = "select T0 from DbMemMonitor T0 where monitorDate > :paramMonitorDate order by T0.id desc"; + Query theQuery = session.createQuery(theHqlQuery); + + long theSecDelta = MAX_MONITOR_TRACE_COUNT * MONITOR_FREQUENCY + FIVE; + long theMsDelta = theSecDelta * THOUSAND; + theQuery.setTimestamp("paramMonitorDate", new Timestamp(new Date().getTime() - theMsDelta)); + theQuery.setMaxResults(MAX_MONITOR_TRACE_COUNT); + + return castAll(theQuery.list()); + } + finally { + session.close(); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngReport.java b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngReport.java new file mode 100644 index 0000000..8bd9dc9 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngReport.java @@ -0,0 +1,659 @@ +package com.capgemini.reports.database.manager; + +import com.capgemini.framework.common.DateHelper; +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbCriteriaVal; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.javabean.DbReportOwner; +import com.capgemini.reports.database.javabean.DbReportType; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.database.javabean.enumeration.ReportStateEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NotFoundException; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; + +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * Hibernate manager for DBReport JAVA bean. + **/ +@Getter +@Slf4j +public class MngReport extends AbstractHibernateManager { + + private static final int QUERY_DBREPORT_POS = 0; + private static final int QUERY_LOGIN_POS = 1; + private static final int QUERY_SURNAME_POS = 2; + private static final int QUERY_FIRST_NAME_POS = 3; + private static final int QUERY_PRIORITY_POS = 4; + private static final int QUERY_REQUEST_DATE_POS = 5; + + // Constants + private static final String DATEFORMAT_DD_MM_YYYY_HH_MM_SS = "dd/MM/yyyy HH:mm:ss"; + + // Settings + private static final int MAX_JSP_PAGE_SIZE = SettingsHelper.getJspPaging(); + + // Queries + private static final String QUERY_USER_REPORTS_COUNT; + private static final String QUERY_RUNNING_REPORTS_DATA; + private static final String QUERY_WAITING_REPORTS_DATA; + private static final String QUERY_USER_REPORTS_DATA; + private static final String QUERY_ALL_USERS_AND_REPORTS; + private static final String QUERY_WAITING_REPORTS_DATA_WITH_TYPE; + private static final String QUERY_ALL_REPORTS_SCHEDULING; + + // Query keys (internal use only) + private static final String COLUMN_SCHEDULING_ID = "schedulingReportId"; + private static final String KEY_REPORT_UID = "reportUid"; + private static final String KEY_DB_USER_LOGIN = "DbUserLogin"; + private static final String KEY_DEADLINE = "deadline"; + private static final String KEY_REPORT_CODE = "reportCode"; + private static final String KEY_START_PERIOD = "startPeriod"; + private static final String KEY_END_PERIOD = "endPeriod"; + + static { + String selectData = "select DISTINCT T0, T2.login, T2.surname, T2.firstname, T3.priority, T1.requestDate "; + String from0123 = "from " + DbReport.class.getName() + " T0, " + DbReportOwner.class.getName() + " T1, " + DbUser.class.getName() + " T2, " + DbReportType.class.getName() + " T3 "; + String whereCoherence0123 = "where T0.id = T1.reportId AND T1.userId = T2.id AND T0.reportCode = T3.code "; + String readyOrWait = "and (T0.state = '" + ReportStateEnum.READY + "' OR T0.state = '" + ReportStateEnum.WAIT + "') "; + String readyOrExecuting = "and (T0.state = '" + ReportStateEnum.READY + "' OR T0.state = '" + ReportStateEnum.EXECUTING + "') "; + String andUserLogin = "and T2.login = :" + KEY_DB_USER_LOGIN + " "; + String andReportCode = "and T0.reportCode = :" + KEY_REPORT_CODE + " "; + String orderBy = "order by T0.startGenerationDate desc, T1.requestDate desc"; + QUERY_RUNNING_REPORTS_DATA = StringHelper.concatToString(selectData, from0123, whereCoherence0123, readyOrExecuting, orderBy); + QUERY_WAITING_REPORTS_DATA = StringHelper.concatToString(selectData, from0123, whereCoherence0123, readyOrWait, orderBy); + QUERY_WAITING_REPORTS_DATA_WITH_TYPE = + StringHelper.concatToString(selectData, from0123, whereCoherence0123, readyOrWait, andReportCode, orderBy); + QUERY_USER_REPORTS_DATA = StringHelper.concatToString(selectData, from0123, whereCoherence0123, andUserLogin, orderBy); + } + + static { + String select = "select T2.surname, T2.firstname, T0.reportCode, count(DISTINCT T1.reportId) "; + String from = "from DbReport T0, DbReportOwner T1, DbUser T2 "; + String whereCoherence = "where T0.id = T1.reportId and T1.userId = T2.id "; + String andWhereCriteria = "and T1.requestDate between TO_DATE(:" + KEY_START_PERIOD + ") and TO_DATE(:" + KEY_END_PERIOD + ") + 1 "; + String andIsNotReportScheduling = "and T0.schedulingReportId IS NULL "; + String groupBy = "group by T0.reportCode, T2.surname, T2.firstname "; + String orderBy = "order by T2.surname, T2.firstname, T0.reportCode "; + QUERY_ALL_USERS_AND_REPORTS = select + from + whereCoherence + andWhereCriteria + andIsNotReportScheduling + groupBy + orderBy; + } + + static { + String selectCount = "select count(*) "; + String selectStats = "select 'Administrateur', 'planification', T0.reportCode, count(DISTINCT T1.reportId) "; + String from012 = "from DbReport T0, DbReportOwner T1, DbUser T2 "; + String whereCoherence012 = "where T0.id = T1.reportId and T1.userId = T2.id "; + String andLogin = "and T2.login = :" + KEY_DB_USER_LOGIN + " "; + String andPeriod = "and T1.requestDate between TO_DATE(:" + KEY_START_PERIOD + ") and TO_DATE(:" + KEY_END_PERIOD + ") + 1 "; + String andIsReportScheduling = "and T0.schedulingReportId IS NOT NULL "; + String groupBy = "group by T0.reportCode "; + String orderBy = "order by T0.reportCode "; + QUERY_ALL_REPORTS_SCHEDULING = + StringHelper.concatToString(selectStats, from012, whereCoherence012, andPeriod, andIsReportScheduling, groupBy, orderBy); + QUERY_USER_REPORTS_COUNT = StringHelper.concatToString(selectCount, from012, whereCoherence012, andLogin); + } + + /** + * Create a new report in database setting its mandatory attributes. + * + * @param session + * @param aReportCode String - Code of the report (ie: "R01", "R21"...) + * @param uuid String - the Universal Unique Identifier of the Report Execution + * @param aState {@link ReportStateEnum} - State of the report + * @param schedulingReportId String - the id of the scheduling if it exists (mandatory for a scheduling).
+ * Else, this is not a scheduling and the value should be null or empty string. + * @return The created report instance + */ + private DbReport insert(Session session, final String aReportCode, final String uuid, final ReportStateEnum aState, final Long schedulingReportId) { + log.debug("Inserting DbReport entry UID={} {}", uuid, schedulingReportId == null ? "" : ("for Scheduling " + schedulingReportId)); + DbReport theReport = new DbReport(); + + // Assign default attribute values + theReport.setReportUid(uuid); + theReport.setState(aState.toString()); + if (schedulingReportId != null) { + theReport.setSchedulingReportId(schedulingReportId); + } + + // Set specific attribute values + theReport.setReportCode(aReportCode); + + // Persist object + session.save(theReport); + + return theReport; + } + + /** + * Create a new report in database setting its mandatory attributes and inject its associated criteria list and list of users data. + * + * @param session + * @param aReportCode String - Code of the report (ie: "R01", "R21"...) + * @param uuid String - the Universal Unique Identifier of the Report Execution + * @param aState {@link ReportStateEnum} - State of the report + * @param criteriaList List<{@link CriteriaValue}> - list containing all {@link CriteriaValue}s + * @param theUsers List<{@link DbUser}> - all the users asking for the report generation + * @param schedulingReportId Long - the id of the scheduling if it exists (mandatory for a scheduling).
+ * Else, this is not a scheduling and the value should be null or empty string. + * @return The created report instance + * @throws InvalidUserInputException Occurs only when the login of the request sender is unknown in database + */ + public DbReport insertWithCriteriaAndOwners(Session session, final String aReportCode, final String uuid, final ReportStateEnum aState, + final List criteriaList, final List theUsers, final Long schedulingReportId) throws InvalidUserInputException { + // Create the report + DbReport theNewReport = insert(session, aReportCode, uuid, aState, schedulingReportId); + + MngReportOwner mngReportOwner = new MngReportOwner(); + for (DbUser user : theUsers) { + // Assign the execution request entry to all the users + mngReportOwner.insert(session, theNewReport, user); + } + + // Create all criteria + Long theReportId = theNewReport.getId(); + MngCriteriaVal theCriteriaValManager = new MngCriteriaVal(); + for (CriteriaValue criterion : criteriaList) { + theCriteriaValManager.insertByCriteriaName(session, criterion.getName(), criterion.getValue(), theReportId); + } + + return theNewReport; + } + + /** + * Create a new report in database setting its mandatory attributes and inject its associated criteria list and user data. + * + * @param aReportCode String - Code of the report (ie: "R01", "R21"...) + * @param uuid String - the Universal Unique Identifier of the Report Execution + * @param aState {@link ReportStateEnum} - State of the report + * @param criteriaList List<{@link CriteriaValue}> - list containing all {@link CriteriaValue}s + * @param theUser {@link DbUser} - the user asking for the report generation + * @return The created report instance + * @throws InvalidUserInputException Occurs only when the login of the request sender is unknown in database + */ + public DbReport insertWithCriteriaAndOwner(final String aReportCode, final String uuid, final ReportStateEnum aState, + final List criteriaList, final DbUser theUser) throws InvalidUserInputException { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + Transaction transaction = session.beginTransaction(); + + // Create the report + // This report is not scheduled + DbReport theNewReport = insert(session, aReportCode, uuid, aState, null); + + // Assign the execution request entry + MngReportOwner mngReportOwner = new MngReportOwner(); + mngReportOwner.insert(session, theNewReport, theUser); + + // Create all criteria + Long theReportId = theNewReport.getId(); + MngCriteriaVal theCriteriaValManager = new MngCriteriaVal(); + for (CriteriaValue criterion : criteriaList) { + theCriteriaValManager.insertByCriteriaName(session, criterion.getName(), criterion.getValue(), theReportId); + } + transaction.commit(); + return theNewReport; + } + finally { + session.close(); + } + } + + /** + * Search query for retrieving Report using its UUID. + */ + public DbReport searchByUid(final String aReportUid, Session session) throws NotFoundException { + DbReport report = searchBy(session, KEY_REPORT_UID, aReportUid); + if (report == null) { + throw new NotFoundException("Unable to find a matching entry in the DB for this report:" + aReportUid); + } + return report; + } + + /** + * Search query for retrieving all the reports using this scheduling name. + */ + public List searchBySchedulingId(final Long aSchedulingId, Session session) { + return searchAndReturnAllValues(session, COLUMN_SCHEDULING_ID, aSchedulingId); + } + + /** + * Search in database the list of reports that belong to a provided user (using its login as search criteria). + */ + public List searchUserReports(Session session, final String aUserLogin, final int aPageNumber) { + Query theQuery = session.createQuery(QUERY_USER_REPORTS_DATA); + theQuery.setMaxResults(MAX_JSP_PAGE_SIZE); + theQuery.setFirstResult(MAX_JSP_PAGE_SIZE * (aPageNumber - 1)); + theQuery.setString(KEY_DB_USER_LOGIN, aUserLogin); + List result = new ArrayList<>(); + List rawResults = theQuery.list(); + for (Object[] reportData : rawResults) { + final DbReport dbReport = (DbReport) reportData[QUERY_DBREPORT_POS]; + final String login = (String) reportData[QUERY_LOGIN_POS]; + final String surname = (String) reportData[QUERY_SURNAME_POS]; + final String firstName = (String) reportData[QUERY_FIRST_NAME_POS]; + final Long priority = (Long) reportData[QUERY_PRIORITY_POS]; + final Timestamp requestDate = (Timestamp) reportData[QUERY_REQUEST_DATE_POS]; + final String requestDateStr = new SimpleDateFormat(DATEFORMAT_DD_MM_YYYY_HH_MM_SS).format(requestDate); + result.add(new RunningReportEntry(dbReport, login, surname, firstName, priority, requestDateStr)); + } + return result; + } + + /** + * Count in database the report list of a specific user using its login as search criteria. + * + * @param session + * @param aUserLogin String - Login of the searched user + * @return DbReport list + */ + public Long countUserReports(Session session, final String aUserLogin) { + Query theQuery = session.createQuery(QUERY_USER_REPORTS_COUNT); + theQuery.setString(KEY_DB_USER_LOGIN, aUserLogin); + return (Long) theQuery.uniqueResult(); + } + + /** + * Search in database the executing reports. + * + * @param session + * @return List of report entries, each of them being containing:
+ *
    + *
  • DbReport list
  • + *
  • Surname
  • + *
  • First name
  • + *
  • Report priority
  • + *
+ */ + public List searchRunningReports(Session session) { + Query theQuery = session.createQuery(QUERY_RUNNING_REPORTS_DATA); + List result = new ArrayList<>(); + for (Object[] reportData : (List) theQuery.list()) { + DbReport report = (DbReport) reportData[QUERY_DBREPORT_POS]; + String login = (String) reportData[QUERY_LOGIN_POS]; + String surname = (String) reportData[QUERY_SURNAME_POS]; + String firstName = (String) reportData[QUERY_FIRST_NAME_POS]; + Long priority = (Long) reportData[QUERY_PRIORITY_POS]; + Timestamp requestDate = (Timestamp) reportData[QUERY_REQUEST_DATE_POS]; + String requestDateStr = new SimpleDateFormat(DATEFORMAT_DD_MM_YYYY_HH_MM_SS).format(requestDate); + RunningReportEntry rep = new RunningReportEntry(report, login, surname, firstName, priority, requestDateStr); + result.add(rep); + } + return result; + } + + /** + * Search in database the reports which are on the READY (ready to run in queue) or WAITING (scheduled) state. + */ + public List searchWaitingReports(Session session) { + Query theQuery = session.createQuery(QUERY_WAITING_REPORTS_DATA); + List result = new ArrayList<>(); + for (Object[] reportData : (List) theQuery.list()) { + final DbReport dbReport = (DbReport) reportData[QUERY_DBREPORT_POS]; + final String login = (String) reportData[QUERY_LOGIN_POS]; + final String surname = (String) reportData[QUERY_SURNAME_POS]; + final String firstName = (String) reportData[QUERY_FIRST_NAME_POS]; + final Long priority = (Long) reportData[QUERY_PRIORITY_POS]; + final Timestamp requestDate = (Timestamp) reportData[QUERY_REQUEST_DATE_POS]; + final String requestDateStr = new SimpleDateFormat(DATEFORMAT_DD_MM_YYYY_HH_MM_SS).format(requestDate); + final RunningReportEntry fullReportEntry = new RunningReportEntry(dbReport, login, surname, firstName, priority, requestDateStr); + result.add(fullReportEntry); + } + return result; + } + + /** + * Get reports by report code and user login in a specific period. + * + * @param session + * @param aStartPeriod Starting period + * @param aEndPeriod End period + * @return List of {@link ReportLaunchByUser} + */ + public List searchUsersReports(Session session, final Date aStartPeriod, final Date aEndPeriod) { + Query theQuery = session.createQuery(QUERY_ALL_USERS_AND_REPORTS); + theQuery.setDate(KEY_START_PERIOD, aStartPeriod); + theQuery.setDate(KEY_END_PERIOD, aEndPeriod); + return parseStatisticsData(theQuery); + } + + /** + * Get report scheduling count by report code and admin in a specific period. + * + * @param session + * @param aStartPeriod Starting period + * @param aEndPeriod End period + * @return List of report entries, each of them being an array containing:
+ *
    + *
  • Index 0: Surname

  • + *
  • Index 1: First name

  • + *
  • Index 2: Report code

  • + *
  • Index 3: Report count
  • + *
  • Index 4[0]: year
  • + *
  • Index 4[1]: month
  • + *
+ */ + public List searchAdminSchedulingReports(Session session, final Date aStartPeriod, final Date aEndPeriod) { + Query theQuery = session.createQuery(QUERY_ALL_REPORTS_SCHEDULING); + theQuery.setDate(KEY_START_PERIOD, aStartPeriod); + theQuery.setDate(KEY_END_PERIOD, aEndPeriod); + return parseStatisticsData(theQuery); + } + + /** + * Executes the query and browses the results.
+ * Expecting an array containing: + *
    + *
  • Index 0: Surname

  • + *
  • Index 1: First name

  • + *
  • Index 2: Report code

  • + *
  • Index 3: Report count
  • + *
  • Index 4[0]: year
  • + *
  • Index 4[1]: month
  • + *
+ * + * @param theQuery the query to execute + * @return the browsed {@link List} + */ + private List parseStatisticsData(final Query theQuery) { + List result = new ArrayList<>(); + for (Object[] reportData : (List) theQuery.list()) { + final String surname = (String) reportData[QUERY_DBREPORT_POS]; + final String firstName = (String) reportData[QUERY_LOGIN_POS]; + final String reportCode = (String) reportData[QUERY_SURNAME_POS]; + final Long reportCount = (Long) reportData[QUERY_FIRST_NAME_POS]; + final ReportLaunchByUser launch = new ReportLaunchByUser(reportCode, surname, firstName, reportCount); + result.add(launch); + } + return result; + } + + /** + * Searches the DB to find all report of the specified type that match the provided list of criteria. + */ + public List searchQueuedReportsWithCriteria(Session session, final ReportEnum reportEnum, final List requestedCriteriaList) { + // First search all Waiting report executions + List recentReports = searchWaitingReportsInstances(session, reportEnum); + + // Prepare requested Criteria: put them in a map for fast retrieval + Map requestedCriteriaMap = new HashMap<>(); + for (CriteriaValue requestedCriteria : requestedCriteriaList) { + requestedCriteriaMap.put(requestedCriteria.getName(), requestedCriteria.getValue()); + } + + // Then for each recent executions check if the criteria were the same + List duplicates = new ArrayList<>(); + for (RunningReportEntry report : recentReports) { + List criteriaValues = new MngCriteriaVal().searchCriteriasByReportID(session, report.getReport().getId()); + if (hasSameCriteria(requestedCriteriaMap, criteriaValues)) { + duplicates.add(report); + } + } + return duplicates; + } + + private List searchWaitingReportsInstances(Session session, final ReportEnum reportEnum) { + Query theQuery = session.createQuery(QUERY_WAITING_REPORTS_DATA_WITH_TYPE); + theQuery.setString(KEY_REPORT_CODE, reportEnum.getReportCode()); + List result = new ArrayList<>(); + for (Object[] reportData : (List) theQuery.list()) { + DbReport dbreport = (DbReport) reportData[QUERY_DBREPORT_POS]; + String login = (String) reportData[QUERY_LOGIN_POS]; + String surname = (String) reportData[QUERY_SURNAME_POS]; + String firstname = (String) reportData[QUERY_FIRST_NAME_POS]; + Long priority = (Long) reportData[QUERY_PRIORITY_POS]; + Timestamp requestDate = (Timestamp) reportData[QUERY_REQUEST_DATE_POS]; + String requestDateStr = new SimpleDateFormat(DATEFORMAT_DD_MM_YYYY_HH_MM_SS).format(requestDate); + RunningReportEntry rep = new RunningReportEntry(dbreport, login, surname, firstname, priority, requestDateStr); + result.add(rep); + } + return result; + } + + private boolean hasSameCriteria(final Map requestedCriteriaMap, final List criteriaValues) { + // Check both list have at least same size + if (criteriaValues.size() != requestedCriteriaMap.size()) { + return false; + } + // Search if DB entries all exist in requested Criteria + for (CriteriaValue criteriaValue : criteriaValues) { + if (!isCriteriaInList(criteriaValue, requestedCriteriaMap)) { + return false; + } + } + // One set is inside the other set, and both are same size: so both sets are equal! + return true; + } + + private boolean isCriteriaInList(final CriteriaValue criteria, final Map requestedCriteriaMap) { + boolean noValue = criteria.getValue() == null || criteria.getValue().isEmpty() || "null".equals(criteria.getValue()); + boolean keyISInMap = requestedCriteriaMap.containsKey(criteria.getName()); + if (keyISInMap) { + String value = requestedCriteriaMap.get(criteria.getName()); + if (value == null || value.isEmpty() || "null".equals(value)) { + // If no value requested and no value obtained, it's ok. + return noValue; + } + else { + return value.equals(criteria.getValue()); + } + } + else { + // Key is not in the map, if value is absent then it's normal + return noValue; + } + } + + /** + * Search for all reports which were executed before a provided deadline. + */ + private List searchReportsBeforeDate(Session session, final Timestamp deadline) { + Query theQuery = session.createQuery( + "SELECT T0 " + + "FROM DbReport T0 " + + "WHERE T0.schedulingReportId IS NULL " + + "AND (T0.startGenerationDate IS NULL AND T0.endGenerationDate IS NULL) " + + "OR (T0.startGenerationDate IS NOT NULL AND T0.startGenerationDate < :deadline) " + + "OR (T0.endGenerationDate IS NOT NULL AND T0.endGenerationDate < :deadline) " + + "ORDER BY T0.reportUid"); + theQuery.setTimestamp(KEY_DEADLINE, deadline); + return castAll(theQuery.list()); + } + + /** + * Search for all reports which were executed before a provided deadline. + */ + private List searchScheduledReportsBeforeDate(Session session, final Timestamp deadline) { + Query theQuery = session.createQuery( + "SELECT T0 " + + "FROM DbReport T0 " + + "WHERE T0.schedulingReportId IS NOT NULL " + + "AND (T0.startGenerationDate IS NULL AND T0.endGenerationDate IS NULL) " + + "OR (T0.startGenerationDate IS NOT NULL AND T0.startGenerationDate < :deadline) " + + "OR (T0.endGenerationDate IS NOT NULL AND T0.endGenerationDate < :deadline) " + + "ORDER BY T0.reportUid"); + theQuery.setTimestamp(KEY_DEADLINE, deadline); + return castAll(theQuery.list()); + } + + /** + * Deletes all reports in the DB that were started before the deadline. + * + * @param deadline the deadline (literally!) + * @return the {@link List} of removed Entries + */ + public List deleteReportsBeforeDate(final Calendar deadline) { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + Transaction transaction = session.beginTransaction(); + List reports = new MngReport().searchReportsBeforeDate(session, DateHelper.toTimestamp(deadline)); + List removed = deleteCascade(session, reports); + transaction.commit(); + return removed; + } + finally { + session.close(); + } + } + + /** + * Deletes all scheduling reports in the DB that were started before the deadline. + * + * @param deadline the deadline (literally!) + * @return the {@link List} of removed Entries + */ + public List deleteScheduledReportsBeforeDate(final Calendar deadline) { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + Transaction transaction = session.beginTransaction(); + // HQL cannot delete from multiple tables, so let's SELECT first... + List reports = new MngReport().searchScheduledReportsBeforeDate(session, DateHelper.toTimestamp(deadline)); + List removed = deleteCascade(session, reports); + transaction.commit(); + return removed; + } + finally { + session.close(); + } + } + + // HQL cannot delete from multiple tables, so we need to browse and delete the entries one by one + private List deleteCascade(Session session, List reports) { + List removed = new ArrayList<>(); + log.trace("Deleting {} DbReport entries and all their associated owners and criteria values", reports.size()); + MngReportOwner mngReportOwner = new MngReportOwner(); + MngCriteriaVal mngCriteriaVal = new MngCriteriaVal(); + for (DbReport dbReport : reports) { + log.trace(" + Deleting DbRport with Id {} (generated on {})", dbReport.getId(), dbReport.getStartGenerationDate()); + + // Search all owners + List owners = mngReportOwner.searchAndReturnAllValues(session, "reportId", dbReport.getId()); + log.trace(" ->Deleting {} DbReportOwner entries", owners.size()); + for (DbReportOwner dbReportOwner : owners) { + log.trace(" + Deleting DbRportOwner {} of Report {} user ID = {} ", dbReportOwner.getId(), dbReportOwner.getReportId(), + dbReportOwner.getUserId()); + session.delete(dbReportOwner); // Delete each owner + } + + // Search all criteria + List criteria = mngCriteriaVal.searchAndReturnAllValues(session, "reportId", dbReport.getId()); + log.trace(" ->Deleting {} DbCriteriaVal entries", criteria.size()); + for (DbCriteriaVal criteriaValue : criteria) { + log.trace(" + Deleting DbCriteriaVal {} of Report {} for value {}", criteriaValue.getId(), criteriaValue.getReportId(), + criteriaValue.getCriteriaValue()); + session.delete(criteriaValue); // Delete each criteria value + } + + // Delete the report now + log.trace(" ->Deleting the DbReport {} itself", dbReport.getId()); + session.delete(dbReport); // Delete the report + removed.add(new RemovedReportEntry(dbReport, owners, criteria)); + } + return removed; + } + + @Override + public Class getManagedClass() { + return DbReport.class; + } + + /** + * Updates the file name of a report. Usually overwriting classical filename with scheduling filename. + * + * @param reportTechnicalUid the report UID + * @param scheduledReportFileName the filename + * @throws NotFoundException if the report entry wasn't found + */ + public void updateFileName(String reportTechnicalUid, String scheduledReportFileName) throws NotFoundException { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + Transaction transaction = session.beginTransaction(); + DbReport dbReport = searchByUid(reportTechnicalUid, session); + dbReport.setFileName(scheduledReportFileName); + update(session, dbReport); + transaction.commit(); + } + finally { + session.close(); + } + } + + /** + * Simple data class. + */ + @Getter + @ToString + @AllArgsConstructor(access = AccessLevel.PRIVATE) + public static class RemovedReportEntry { + private final DbReport report; + private final List owner; + private final List criteria; + } + + /** + * Represents a report entry in the DB, specifically from the logged-in user's point of view.
+ * Contains reference to a {@link DbReport}, the login/surname/firstname of its owner, the priority, and theoriginal request date + */ + @AllArgsConstructor + @Getter + public class RunningReportEntry { + private final DbReport report; + private final String login; + private final String surname; + private final String firstName; + private final Long reportPriority; + private final String requestDate; + + /** + * Returns a 'safe' username: 'Name Surname' or, if any is unavailable, then returns the login. + * + * @return a safe name, which always contains relevant information even with missing naming data + */ + public String getSafeName() { + boolean fistNameIsNull = isNull(firstName); + boolean surNameIsNull = isNull(surname); + return (fistNameIsNull || surNameIsNull) ? login : firstName + " " + surname; + } + + private boolean isNull(final String string) { + return string == null || string.isEmpty() || "null".equals(string); + } + } + + /** + * Represents a report entry in the DB. + */ + @AllArgsConstructor + @Getter + public class ReportLaunchByUser { + private final String reportCode; + private final String surname; + private final String firstName; + private final Long reportCount; + + @Override + public String toString() { + return "ReportLaunchByUser [reportCode=" + reportCode + ", surname=" + surname + ", firstName=" + firstName + ", reportCount=" + + reportCount + "]"; + } + + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngReportOwner.java b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngReportOwner.java new file mode 100644 index 0000000..ef9cd66 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngReportOwner.java @@ -0,0 +1,63 @@ +package com.capgemini.reports.database.manager; + +import com.capgemini.framework.common.DateHelper; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.javabean.DbReportOwner; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.database.manager.MngReport.RunningReportEntry; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Query; +import org.hibernate.Session; + +import java.util.List; + +/** + * Hibernate manager for DBReport JAVA bean. + **/ +@Slf4j +public class MngReportOwner extends AbstractHibernateManager { + + private static final String SELECT_REPORT_OWNERS; + + static { + SELECT_REPORT_OWNERS = "from DbReportOwner where reportId = :DbReportId order by id desc"; + } + + @Override + public Class getManagedClass() { + return DbReportOwner.class; + } + + /** + * Create a new affectation of a report execution to a user in database. + */ + protected DbReportOwner insert(Session session, final DbReport aReport, final DbUser aUser) { + log.debug("Inserting DbReportOwner entry report={}({}) - owner={}({})", aReport.getId(), aReport.getReportCode(), aUser.getId(), aUser.getLogin()); + DbReportOwner theReportOwner = new DbReportOwner(); + + // Assign default attribute values + theReportOwner.setReportId(aReport.getId()); + theReportOwner.setUserId(aUser.getId()); + theReportOwner.setRequestDate(DateHelper.getCurrentSqlTimestamp()); + + // Persist object + session.save(theReportOwner); + return theReportOwner; + } + + /** + * Search for all the {@link DbReportOwner}s that subscribed to the report whose ID is provided. A result page number above 0 can be provided to browse further results. + */ + public List searchReportOwners(Session session, final Long aReportId) { + Query theQuery = session.createQuery(SELECT_REPORT_OWNERS); + theQuery.setLong("DbReportId", aReportId); + return castAll(theQuery.list()); + } + + /** + * Creates and persists a {@link DbReportOwner} instance linking the provided {@link DbUser} to the provided report. + */ + public void subscribe(Session session, final DbUser dbUser, final RunningReportEntry report) { + insert(session, report.getReport(), dbUser); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngReportType.java b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngReportType.java new file mode 100644 index 0000000..5d7ba36 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngReportType.java @@ -0,0 +1,110 @@ +package com.capgemini.reports.database.manager; + +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbReportType; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; + +import java.util.List; + +/** + * Hibernate manager for DBReportType JAVA bean. + **/ +public class MngReportType extends AbstractHibernateManager { + + private static final String QUERY_ALL_SCHEDULABLE_REPORT_TYPES; + + static { + String select = "select T0.code "; + String from = "from " + DbReportType.class.getName() + " T0 "; + String whereSchedulable = "where T0.isCandidateForScheduling = 'TRUE' "; + String orderBy = "order by T0.code asc "; + QUERY_ALL_SCHEDULABLE_REPORT_TYPES = select + from + whereSchedulable + orderBy; + } + + @Override + public Class getManagedClass() { + return DbReportType.class; + } + + /** + * Create a new report type in database setting its mandatory attributes. + */ + public DbReportType insert(Session session, final String aReportCode, final String aTitle, final Long aPriority, final String aRevisionRule) { + DbReportType theReport = new DbReportType(); + + // Assign default attribute values + theReport.setCode(aReportCode); + theReport.setTitle(aTitle); + theReport.setPriority(aPriority); + theReport.setRevisionRule(aRevisionRule); + + // Persist object + session.save(theReport); + return theReport; + } + + /** + * Search query for retrieving Report type using {@link ReportEnum}. + */ + public DbReportType search(Session session, final ReportEnum report) { + return searchBy(session, "code", report.getReportCode()); + } + + /** + * Search query for retrieving Report type using its code. + */ + private DbReportType searchByUid(Session session, final String aCode) { + return searchBy(session, "code", aCode); + } + + /** + * Return true or false if current report is authorized. + */ + public boolean isAuthorized(Session session, final String aCode) { + return Boolean.valueOf(searchByUid(session, aCode).getReportAuthorized().toLowerCase()); + } + + /** + * Return true or false if current report is authorized. + */ + public boolean isAuthorized(final ReportEnum aReport) { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + return Boolean.valueOf(searchByUid(session, aReport.getReportCode()).getReportAuthorized().toLowerCase()); + } + finally { + session.close(); + } + } + + /** + * Obtain all the report types which are marked as Schedulable in the DB. + */ + public List getAllSchedulableReportTypes(Session session) { + return session.createQuery(QUERY_ALL_SCHEDULABLE_REPORT_TYPES).list(); + } + + + /** + * Changes the 'authorization' status of a Report Type. + */ + public DbReportType setReportActivation(final String reportCode, final String reportAuthorized) { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + Transaction transaction = session.beginTransaction(); + DbReportType dbReportType = searchBy(session, "code", reportCode); + dbReportType.setReportAuthorized(reportAuthorized); + update(session, dbReportType); + transaction.commit(); + return dbReportType; + } + finally { + session.close(); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngSchedulingCriteriaVal.java b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngSchedulingCriteriaVal.java new file mode 100644 index 0000000..59214b9 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngSchedulingCriteriaVal.java @@ -0,0 +1,300 @@ +package com.capgemini.reports.database.manager; + +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbCriteria; +import com.capgemini.reports.database.javabean.DbSchedulingCriteriaVal; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.javabean.enumeration.SchedulingEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.periodicity.PeriodFactory; +import com.capgemini.reports.periodicity.SchedulingPeriod; +import com.google.common.base.Joiner; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +/** + * Hibernate manager for {@link DbSchedulingCriteriaVal} JAVA bean. + **/ +@Slf4j +public class MngSchedulingCriteriaVal extends AbstractHibernateManager { + + private static final String COLUMN_SCHEDULING_REPORT_ID = "schedulingReportId"; + private static final String KEY_REPORT_ID = "schedulingReportId"; + + private static final String QUERY_SELECT_CRITERIAS_VALUES; + private static final String QUERY_SELECT_FUNCTIONAL_CRITERIAS_VALUES; + private static final String QUERY_SELECT_FUNCTIONAL_CRITERIAS_DATA; + private static final String QUERY_SELECT_TEMPORAL_CRITERIAS_VALUES; + private static final String QUERY_SELECT_TEMPORAL_CRITERIAS_DATA; + private static final String QUERY_DELETE_CRITERIAS_VALUES_OF_SCHEDULING; + private static final String QUERY_SELECT_PERIOD; + private static final String QUERY_DELETE_TEMPORAL_CRITERIAS_VALUES_OF_SCHEDULING; + private static final String QUERY_DELETE_FUNCTIONAL_CRITERIAS_VALUES_OF_SCHEDULING; + + static { + String select = "SELECT DISTINCT T0.criteriaName, T1.criteriaValue "; + String from = "FROM DbSchedulingCriteriaVal T1, DbCriteria T0 "; + String whereCoherence = "WHERE T1.dbCriteria = T0.id "; + String andReportId = "AND T1.schedulingReportId = :" + KEY_REPORT_ID + " "; + String andIsFunctional = "AND T0.isTemporel = 'FALSE' "; + String andIsTemporal = "AND T0.isTemporel = 'TRUE' "; + String orderBy = "ORDER BY T0.criteriaName ASC"; + QUERY_SELECT_FUNCTIONAL_CRITERIAS_DATA = select + from + whereCoherence + andReportId + andIsFunctional + orderBy; + QUERY_SELECT_TEMPORAL_CRITERIAS_DATA = select + from + whereCoherence + andReportId + andIsTemporal + orderBy; + } + + static { + String select = "SELECT T0 "; + String selectID = "SELECT T0.id "; + String from = "FROM DbSchedulingCriteriaVal T0, DbCriteria T1 "; + String whereCoherence = "WHERE T0.dbCriteria = T1.id "; + String andReportId = "AND T0.schedulingReportId = :" + KEY_REPORT_ID + " "; + String andIsPeriodicity = "AND T1.criteriaName ='period' "; + String andIsFunctional = "AND T1.isTemporel = 'FALSE' "; + String andIsTemporal = "AND T1.isTemporel = 'TRUE' "; + QUERY_SELECT_CRITERIAS_VALUES = select + from + whereCoherence + andReportId; + QUERY_SELECT_PERIOD = select + from + whereCoherence + andReportId + andIsPeriodicity; + QUERY_SELECT_FUNCTIONAL_CRITERIAS_VALUES = select + from + whereCoherence + andReportId + andIsFunctional; + QUERY_SELECT_TEMPORAL_CRITERIAS_VALUES = select + from + whereCoherence + andReportId + andIsTemporal; + + String delete = "DELETE DbSchedulingCriteriaVal "; + String whereIn = "WHERE id in ("; + String endWhere = ")"; + final String selectValueID = selectID + from + whereCoherence + andReportId; + QUERY_DELETE_CRITERIAS_VALUES_OF_SCHEDULING = delete + whereIn + selectValueID + endWhere; + QUERY_DELETE_FUNCTIONAL_CRITERIAS_VALUES_OF_SCHEDULING = delete + whereIn + selectValueID + andIsFunctional + endWhere; + QUERY_DELETE_TEMPORAL_CRITERIAS_VALUES_OF_SCHEDULING = delete + whereIn + selectValueID + andIsTemporal + endWhere; + } + + @Override + protected Class getManagedClass() { + return DbSchedulingCriteriaVal.class; + } + + /** + * Create a new scheduling criteria value. + */ + private DbSchedulingCriteriaVal insert(Session session, final DbCriteria dbCriteria, final String criteriaValue, final Long schedulingReportId) { + log.debug("Insert SchedulingCriteriaVal: {}({}) = {} for {}", dbCriteria.getId(), dbCriteria.getCriteriaName(), criteriaValue, + schedulingReportId); + + DbSchedulingCriteriaVal theSchedulingCriteriaVal = new DbSchedulingCriteriaVal(); + + theSchedulingCriteriaVal.setCriteriaValue(criteriaValue); + theSchedulingCriteriaVal.setDbCriteria(dbCriteria); + theSchedulingCriteriaVal.setSchedulingReportId(schedulingReportId); + + // Persist object + session.save(theSchedulingCriteriaVal); + + return theSchedulingCriteriaVal; + } + + /** + * Create a new scheduling criteria value using the criteria name as key. + */ + DbSchedulingCriteriaVal insertByCriteriaName(Session session, final String criteriaName, final String criteriaValue, final Long schedulingReportId) { + // Search the corresponding criteria using its name + DbCriteria theCriteria = new MngCriteria().searchByName(session, criteriaName); + + return insert(session, theCriteria, criteriaValue, schedulingReportId); + } + + /** + * Returns a {@link Map} of all {@link ReportCriteriaEnum} to their values, for a given report (whose ID is provided). + */ + public Map getFunctionalMap(final Long schedulingReportId) { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + List result = searchFunctionalCriteria(session, schedulingReportId); + Map theFunctionalValues = new EnumMap<>(ReportCriteriaEnum.class); + for (DbSchedulingCriteriaVal criteria : result) { + theFunctionalValues.put(ReportCriteriaEnum.valueOf(criteria), criteria.getCriteriaValue()); + } + return theFunctionalValues; + } + finally { + session.close(); + } + } + + /** + * Search functional criteria values or scheduling report. + */ + public List searchFunctional(final Long schedulingReportId) { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + Query theQuery = session.createQuery(QUERY_SELECT_FUNCTIONAL_CRITERIAS_DATA); + theQuery.setLong(KEY_REPORT_ID, schedulingReportId); + + List result = new ArrayList<>(); + for (Object[] reportData : (List) theQuery.list()) { + result.add(new SchedulingCriteriaValue((String) reportData[0], (String) reportData[1])); + } + return result; + } + finally { + session.close(); + } + } + + /** + * Search functional {@link DbSchedulingCriteriaVal} of scheduling report. + */ + private List searchFunctionalCriteria(Session session, final Long schedulingReportId) { + Query theQuery = session.createQuery(QUERY_SELECT_FUNCTIONAL_CRITERIAS_VALUES); + theQuery.setLong(KEY_REPORT_ID, schedulingReportId); + return castAll(theQuery.list()); + } + + /** + * Search Temporal {@link DbSchedulingCriteriaVal} of scheduling report. + */ + private List searchTemporalCriteria(Session session, final Long schedulingReportId) { + Query theQuery = session.createQuery(QUERY_SELECT_TEMPORAL_CRITERIAS_VALUES); + theQuery.setLong(KEY_REPORT_ID, schedulingReportId); + return castAll(theQuery.list()); + } + + /** + * Search All {@link DbSchedulingCriteriaVal} of scheduling report. + */ + public List searchCriteria(Session session, final Long schedulingReportId) { + Query theQuery = session.createQuery(QUERY_SELECT_CRITERIAS_VALUES); + theQuery.setLong(KEY_REPORT_ID, schedulingReportId); + return castAll(theQuery.list()); + } + + /** + * Builds a SchedulingPeriod representing the scheduling parameters of the ReportSchedulig whose ID is passed as parameters. + */ + public SchedulingPeriod getPeriod(Session session, final Long schedulingReportId) throws InvalidInputException { + List result = searchTemporalCriteria(session, schedulingReportId); + return PeriodFactory.fromDbSchedulingCriteria(result); + } + + /** + * Obtain the criteria which describe the period of a report. + */ + public SchedulingCriteriaValue getPeriodOfSchedulingReportById(Session session, final Long schedulingReportId) { + Query theQuery = session.createQuery(QUERY_SELECT_PERIOD); + theQuery.setLong(KEY_REPORT_ID, schedulingReportId); + + // Construct query result + List result = new ArrayList<>(); + for (DbSchedulingCriteriaVal reportData : (List) theQuery.list()) { + String periodicityStr = reportData.getDbCriteria().getCriteriaName(); + SchedulingEnum periodicity = SchedulingEnum.getEnum(periodicityStr); + String criteriaValue = reportData.getCriteriaValue(); + result.add(new SchedulingCriteriaValue(periodicity, criteriaValue)); + } + + if (!result.isEmpty()) { + return result.get(0); + } + else { + return new SchedulingCriteriaValue("", ""); + } + } + + /** + * Updates the period of a scheduled report. + */ + public void updatePeriod(Session session, final Long aSchedulingTemplateId, final SchedulingPeriod period) { + log.trace("Updating scheduling temporal params: {} to {}", aSchedulingTemplateId, period.toString()); + deleteTemporalCriteriaValueBySchedulingReportId(session, aSchedulingTemplateId); + for (SchedulingCriteriaValue cts : period.asCriteriaValues()) { + insertByCriteriaName(session, cts.getName(), cts.getValue(), aSchedulingTemplateId); + } + } + + /** + * Update the functional criteria of a scheduled report.
+ * Deletes the old ones, replaces by the provided list of values. + */ + public void updateFunctionalParameters(Session session, final Long aSchedulingTemplateId, final List launchData) { + if (log.isTraceEnabled()) { + log.trace("Updating scheduling functional params: schedulingID={} to {}", aSchedulingTemplateId, Joiner.on(", ").join(launchData)); + } + deleteFunctionalCriteriaValueBySchedulingReportId(session, aSchedulingTemplateId); + for (CriteriaValue criteriaValue : launchData) { + insertByCriteriaName(session, criteriaValue.getName(), criteriaValue.getValue(), aSchedulingTemplateId); + } + } + + /** + * Delete all scheduling criteria value by scheduling report id (both functional and temporal). + */ + private int deleteFunctionalCriteriaValueBySchedulingReportId(Session session, final Long schedulingReportId) { + Query theQuery = session.createQuery(QUERY_DELETE_FUNCTIONAL_CRITERIAS_VALUES_OF_SCHEDULING); + theQuery.setLong(KEY_REPORT_ID, schedulingReportId); + return theQuery.executeUpdate(); + } + + /** + * Delete all scheduling criteria value by scheduling report id (both functional and temporal). + */ + private int deleteTemporalCriteriaValueBySchedulingReportId(Session session, final Long schedulingReportId) { + Query theQuery = session.createQuery(QUERY_DELETE_TEMPORAL_CRITERIAS_VALUES_OF_SCHEDULING); + theQuery.setLong(KEY_REPORT_ID, schedulingReportId); + return theQuery.executeUpdate(); + } + + /** + * Delete all scheduling criteria value by scheduling report id (both functional and temporal). + */ + int deleteAllSchedulingCriteriaValueBySchedulingReportId(Session session, final Long schedulingReportId) { + Query theQuery = session.createQuery(QUERY_DELETE_CRITERIAS_VALUES_OF_SCHEDULING); + theQuery.setLong(KEY_REPORT_ID, schedulingReportId); + return theQuery.executeUpdate(); + } + + /** + * A Simple POJO class to bundle scheduling periodicity name - value pair. + */ + @Getter + public static class SchedulingCriteriaValue { + + private static final String NULL_STRING = "null"; + private final String name; + private final String value; + + /** + * Builds a SchedulingCriteria Name-Value object. + * + * @param name if null, will be 'null' + * @param value if null, will be 'null' + */ + public SchedulingCriteriaValue(final String name, final String value) { + this.name = name == null ? NULL_STRING : name; + this.value = (value == null || value.isEmpty() || "null".equals(value)) ? NULL_STRING : value; + } + + /** + * Builds a SchedulingCriteria Name-Value object. + * + * @param criteria if null, will be 'null' + * @param value if null, will be 'null' + */ + public SchedulingCriteriaValue(final SchedulingEnum criteria, final String value) { + this.name = criteria == null ? NULL_STRING : criteria.toString(); + this.value = value == null ? NULL_STRING : value; + } + + @Override + public String toString() { + return name + " = " + value; + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngSchedulingReport.java b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngSchedulingReport.java new file mode 100644 index 0000000..f484833 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngSchedulingReport.java @@ -0,0 +1,239 @@ +package com.capgemini.reports.database.manager; + +import com.capgemini.framework.common.DateHelper; +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbCriteriaVal; +import com.capgemini.reports.database.javabean.DbSchedulingCriteriaVal; +import com.capgemini.reports.database.javabean.DbSchedulingReport; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.database.manager.MngSchedulingCriteriaVal.SchedulingCriteriaValue; +import com.capgemini.reports.exceptions.NotFoundException; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.HibernateException; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * Hibernate manager for {@link DbSchedulingReport} JAVA bean. + **/ +@Getter +@Slf4j +public class MngSchedulingReport extends AbstractHibernateManager { + + private static final int REPORT_CODE_POS = 0; + private static final int END_GENERATION_DATE_POS = 1; + private static final int FILE_NAME_POS = 2; + + // Column name in Db + private static final String COLUMN_SCHEDULING_NAME = "schedulingName"; + + // Key values + private static final String KEY_REPORT_CODE = "reportCode"; + private static final String KEY_UPPER_DATE = "upperDate"; + + private static final int MAX_JSP_PAGE_SIZE = SettingsHelper.getJspPaging(); + + // Reports and their owners + private static final String QUERY_ALL_SCHEDULING_REPORTS_AND_OWNERS; + private static final String QUERY_SCHEDULING_REPORTS_BY_TYPE; + + // Reports by their periodicity + private static final String QUERY_SCHEDULING_REPORTS_COUNT; + private static final String QUERY_SCHEDULING_REPORTS_COUNT_BY_REPORT_CODE; + private static final String QUERY_DELETE_SCHEDULING_REPORT_AND_CRITERIA_VAL; + private static final String QUERY_SELECT_SCHEDULING_REPORT_AND_CRITERIA_VAL; + + static { + String select = "SELECT count(*) "; + String from = "FROM DbSchedulingReport T0 "; + String whereReportCode = "WHERE T0.reportCode = :" + KEY_REPORT_CODE; + QUERY_SCHEDULING_REPORTS_COUNT = select + from; + QUERY_SCHEDULING_REPORTS_COUNT_BY_REPORT_CODE = QUERY_SCHEDULING_REPORTS_COUNT + whereReportCode; + } + + static { + String delete = "DELETE T0, T3"; + String select = "SELECT DISTINCT T0.reportCode ,T0.endGenerationDate, T0.fileName "; + String from = "FROM DbReport T0, DbReportOwner T1,DbCriteriaVal T3 "; + String whereCoherence = "WHERE T0.id = T1.reportId AND T0.id = T3.reportId "; + String andBefore = "AND T0.endGenerationDate < :" + KEY_UPPER_DATE; + String andIsaReportScheduling = "AND T0.schedulingReportId IS NOT NULL "; + + final String allSchedulingReports = from + whereCoherence + andBefore + andIsaReportScheduling; + QUERY_DELETE_SCHEDULING_REPORT_AND_CRITERIA_VAL = delete + allSchedulingReports; + QUERY_SELECT_SCHEDULING_REPORT_AND_CRITERIA_VAL = select + allSchedulingReports; + } + + static { + String select = "SELECT DISTINCT T0, concat(T1.firstname, ', ', T1.surname) "; + String from = "FROM DbSchedulingReport T0, DbUser T1 "; + String whereCoherence = "WHERE T0.adminResponsibleId = T1.id "; + String andReportCode = "AND T0.reportCode = :reportCode "; + String orderBy = "ORDER BY T0.lastUpdate DESC "; + + QUERY_SCHEDULING_REPORTS_BY_TYPE = select + from + whereCoherence + andReportCode + orderBy; + QUERY_ALL_SCHEDULING_REPORTS_AND_OWNERS = select + from + whereCoherence + orderBy; + } + + /** + * Count in database the scheduling report list by report code . + */ + public Long countSchedulingReportsByReportCode(Session session, final ReportEnum report) { + Query theQuery = session.createQuery(QUERY_SCHEDULING_REPORTS_COUNT_BY_REPORT_CODE); + theQuery.setString(KEY_REPORT_CODE, report.getReportCode()); + return (Long) theQuery.uniqueResult(); + } + + /** + * Count in database all scheduling report list . + */ + public Long countAllSchedulingReport(Session session) { + Query theQuery = session.createQuery(QUERY_SCHEDULING_REPORTS_COUNT); + return (Long) theQuery.uniqueResult(); + } + + /* Create a scheduling report */ + private DbSchedulingReport insert(Session session, final String schedulingName, final DbUser theAdminResponsible, final ReportEnum reportCode) { + DbSchedulingReport schedulingReport = new DbSchedulingReport(); + + schedulingReport.setSchedulingName(schedulingName); + schedulingReport.setLastUpdate(DateHelper.getCurrentSqlTimestamp()); + schedulingReport.setAdminResponsibleId(theAdminResponsible.getId()); + schedulingReport.setReportCode(reportCode.getReportCode()); + // Persist object + session.save(schedulingReport); + return schedulingReport; + } + + /** + * Insert a SchedulingReport in the DB.
+ * The related {@link DbSchedulingReport}, {@link DbSchedulingCriteriaVal}s, {@link DbCriteriaVal}s will be created accordingly. + * + * @param schedulingName the name of the scheduling, as asked by the user + * @param schedulingCriteriaValues the temporal criterias of the scheduling + * @param criteriaValues the functional criteria of the report's execution + * @param requestor the user making the request + * @param reportCode the required report's type + * @return the entry in the DB + */ + public DbSchedulingReport insertSchedulingReportWithCriteriaAndOwner(final String schedulingName, + final List schedulingCriteriaValues, final List criteriaValues, final DbUser requestor, + final ReportEnum reportCode) { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + Transaction transaction = session.beginTransaction(); + DbSchedulingReport dbSchedulingReport = this.insert(session, schedulingName, requestor, reportCode); + Long schedulingReportId = dbSchedulingReport.getId(); + + // save temporal criteria values + MngSchedulingCriteriaVal theSchedulingCriteriaValManager = new MngSchedulingCriteriaVal(); + for (SchedulingCriteriaValue schedulingCriterion : schedulingCriteriaValues) { + theSchedulingCriteriaValManager.insertByCriteriaName(session, schedulingCriterion.getName(), schedulingCriterion.getValue(), schedulingReportId); + } + + // save functional criteria values + MngSchedulingCriteriaVal theCriteriaValManager = new MngSchedulingCriteriaVal(); + for (CriteriaValue criterion : criteriaValues) { + theCriteriaValManager.insertByCriteriaName(session, criterion.getName(), criterion.getValue(), schedulingReportId); + } + transaction.commit(); + return dbSchedulingReport; + } + finally { + session.close(); + } + } + + /** + * Returns all data on all the scheduling report entries..
+ * Returns a {@link Map} whose keys are all the {@link DbSchedulingReport} of the DB, and each value is the associated owner's full name. + */ + public Map searchAllSchedulingReports(Session session, final int aPageNumber) { + + Query theQuery = session.createQuery(QUERY_ALL_SCHEDULING_REPORTS_AND_OWNERS); + theQuery.setMaxResults(MAX_JSP_PAGE_SIZE); + theQuery.setFirstResult(MAX_JSP_PAGE_SIZE * (aPageNumber - 1)); + + Map results = new HashMap<>(); + for (Object[] reportData : (List) theQuery.list()) { + DbSchedulingReport dbReport = (DbSchedulingReport) reportData[0]; + String owner = (String) reportData[1]; + results.put(dbReport, owner); + } + return results; + } + + /** + * Returns all data on the scheduling report entries refering to the provided {@link ReportEnum} code.
+ * Returns a {@link Map} whose keys are all the {@link DbSchedulingReport} of the DB, and each value is the associated owner's full name. + */ + public Map searchSchedulingReportByReportCode(Session session, final ReportEnum reportCode, final int aPageNumber) { + Query theQuery = session.createQuery(QUERY_SCHEDULING_REPORTS_BY_TYPE); + theQuery.setMaxResults(MAX_JSP_PAGE_SIZE); + theQuery.setFirstResult(MAX_JSP_PAGE_SIZE * (aPageNumber - 1)); + theQuery.setString(KEY_REPORT_CODE, reportCode.getReportCode()); + + Map results = new HashMap<>(); + for (Object[] reportData : (List) theQuery.list()) { + DbSchedulingReport dbReport = (DbSchedulingReport) reportData[0]; + String owner = (String) reportData[1]; + results.put(dbReport, owner); + } + return results; + } + + /** + * Delete a scheduling report, and all its scheduling values (functional and temporal). + * + * @param schedulingReportId the ID f the scheduled report + * @return the number of lines affected (all criteria values, plus the scheduling itself) + * @throws NotFoundException if Hibernate is unable to perform the operation + */ + public int deleteSchedulingReport(final Long schedulingReportId) throws NotFoundException { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + Transaction transaction = session.beginTransaction(); + DbSchedulingReport persistedObj = searchById(session, schedulingReportId); + + log.debug("Find DbSchedulingReport by id " + schedulingReportId); + MngSchedulingCriteriaVal mngSchedulingCriteriaVal = new MngSchedulingCriteriaVal(); + int valuesDeleted = mngSchedulingCriteriaVal.deleteAllSchedulingCriteriaValueBySchedulingReportId(session, schedulingReportId); + delete(session, persistedObj); + transaction.commit(); + return valuesDeleted + 1; + } + catch (HibernateException e) { + throw new NotFoundException("SchedulingReport with id " + schedulingReportId + " not found in DB.", e); + } + finally { + session.close(); + } + } + + @Override + public Class getManagedClass() { + return DbSchedulingReport.class; + } + + /** + * Returns the entry with the provided scheduling_name (if any).
+ * If non exist, returns null + */ + public DbSchedulingReport searchByName(Session session, String planifName) { + return searchBy(session, COLUMN_SCHEDULING_NAME, planifName); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngUser.java b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngUser.java new file mode 100644 index 0000000..30a1b83 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/manager/MngUser.java @@ -0,0 +1,134 @@ +package com.capgemini.reports.database.manager; + +import com.capgemini.framework.common.DateHelper; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.database.javabean.DbUser.UserData; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.Transaction; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Hibernate manager for DBUser JAVA bean. + **/ +@Slf4j +public class MngUser extends AbstractHibernateManager { + + private static final String KEY_REPORT = "DbReportObject"; + private static final String QUERY_REPORT_OWNERS = + "select T2 from DbReport T0, DbReportOwner T1, DbUser T2 where T0.id = T1.reportId and T1.userId = T2.id and T0.id = :" + KEY_REPORT + + " order by T2.id desc"; + + @Override + public Class getManagedClass() { + return DbUser.class; + } + + /** + * Create new user instance settings its mandatory attributes. + */ + public DbUser insert(Session session, final String aLogin, final String aFirstName, final String aSurname, final String anEmail) { + log.debug("Encountered new user : " + aLogin); + Transaction transaction = session.beginTransaction(); + DbUser theCreatedUser = new DbUser(); + + // Assign default attribute values + theCreatedUser.setLogin(aLogin); + theCreatedUser.setFirstname(aFirstName); + theCreatedUser.setSurname(aSurname); + theCreatedUser.setEmail(anEmail); + theCreatedUser.setLastConnectionDate(DateHelper.getCurrentSqlDate()); + + // Persist object + session.save(theCreatedUser); + transaction.commit(); + return theCreatedUser; + } + + /** + * Search query for retrieving User using its login. + * + * + * @param session + * @param aLogin Searched login value + * @return Found user (or null of not founr) + */ + private DbUser searchByLogin(Session session, final String aLogin) { + return searchBy(session, "login", aLogin); + } + + /** + * Updates a DbUser's data to match the provided UserData (assumed to be up-to-date, freshly provided by the ActiveDirectory). + */ + private void updateUser(Session session, final DbUser dbUser, final UserData user) { + log.debug("Updating user data for " + dbUser.getLogin()); + Transaction transaction = session.beginTransaction(); + dbUser.setEmail(user.getEmail()); + dbUser.setFirstname(user.getFirstName()); + dbUser.setSurname(user.getSurname()); + session.update(dbUser); + transaction.commit(); + } + + /** + * Returns the DbUser from the database.
+ * If the user did not exist, creates the user, then returns it.
+ * If the dbUser did exist, but did not have the same data as the adUser, updates the DbUser to match the adUser, then returns the dbUSer. + */ + public DbUser fetchOrUpdateOrCreateUser(Session session, final UserData adUser) { + // Fetch or Register the requesting user in the DB + MngUser mngUser = new MngUser(); + DbUser dbUser = mngUser.searchByLogin(session, adUser.getLogin()); + if (dbUser == null) { + // User does not already exist, we must create a new one + dbUser = mngUser.insert(session, adUser.getLogin(), adUser.getFirstName(), adUser.getSurname(), adUser.getEmail()); + } + else { + // User has been found, now we need to make sure all its data are up to date + if (!dbUser.sameAs(adUser)) { + mngUser.updateUser(session, dbUser, adUser); + } + } + return dbUser; + } + + /** + * Returns the DbUser(s) from the database.
+ * If any dbUser did not exist, creates that user.
+ * If any dbUser did exist, but did not have the same data as the adUser, updates the DbUser to match the adUser. + */ + public List fetchOrUpdateOrCreateUsers(Session session, final Collection adUsers) { + // Fetch or Register the requesting user in the DB + MngUser mngUser = new MngUser(); + List dbUSers = new ArrayList<>(); + for (UserData adUser : adUsers) { + DbUser dbUser = mngUser.searchByLogin(session, adUser.getLogin()); + if (dbUser == null) { + // User does not already exist, we must create a new one + dbUser = mngUser.insert(session, adUser.getLogin(), adUser.getFirstName(), adUser.getSurname(), adUser.getEmail()); + } + else { + // User has been found, now we need to make sure all its data are up to date + if (!dbUser.sameAs(adUser)) { + mngUser.updateUser(session, dbUser, adUser); + } + } + dbUSers.add(dbUser); + } + return dbUSers; + } + + /** + * Search in database the list of users that requested a specific report to be executed (using its login as search criteria). + */ + public List searchReportOwners(Session session, final DbReport dbReport) { + Query theQuery = session.createQuery(QUERY_REPORT_OWNERS); + theQuery.setEntity(KEY_REPORT, dbReport); + return castAll(theQuery.list()); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/stats/GenJspStats.java b/kurt-utility/src/main/java/com/capgemini/reports/database/stats/GenJspStats.java new file mode 100644 index 0000000..6181386 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/stats/GenJspStats.java @@ -0,0 +1,291 @@ +package com.capgemini.reports.database.stats; + +import com.capgemini.framework.common.DateHelper; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.manager.MngReport; +import com.capgemini.reports.database.manager.MngReport.ReportLaunchByUser; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +import java.text.ParseException; +import java.util.*; +import java.util.Map.Entry; + +/** + * Class for dynamic content of JSP statistics page. + **/ +public final class GenJspStats { + + private static final String PLACEHOLDER_NUM = "0"; + private static final long MILLIS_IN_S = 1000L; + private static final String START_PERIOD = "startPeriod"; + private static final String END_PERIOD = "endPeriod"; + private static final String TOTAL = "total"; + + /** + * Count exectutions. + */ + private static final String HQL_COUNT_EXECUTIONS_QUERY; + /** + * Count TECHNICAL errors. + */ + private static final String HQL_COUNT_TECHNICAL_ERRORS_QUERY; + /** + * Count FUNCTIONAL errors. + */ + private static final String HQL_COUNT_FUNCTIONAL_ERRORS_QUERY; + /** + * Calc min, avg, and max duration of each report types. + */ + private static final String HQL_MIN_MAX_AVG_DURATION_QUERY; + + static { + String selectCount = "select T0.reportCode, count(DISTINCT T1.reportId) "; + String selectStats = + "select T0.reportCode, min(T0.generationDuration), avg(T0.generationDuration), max(T0.generationDuration) "; + String from = "from DbReport T0, DbReportOwner T1 "; + String whereCoherence = "where T0.id = T1.reportId "; + String andPeriod = "and T1.requestDate between TO_DATE(:" + START_PERIOD + ") and TO_DATE(:" + END_PERIOD + ") + 1 "; + String andSuccess = "and T0.endGenerationDate is not null and T0.state != 'FAILED' "; + String andErrorTypeTech = "and T0.errorType = 'TECHNICAL' "; + String andErrorTypeFunc = "and T0.errorType = 'FUNCTIONAL' "; + String groupBy = "group by T0.reportCode"; + HQL_COUNT_EXECUTIONS_QUERY = selectCount + from + whereCoherence + andPeriod + groupBy; + HQL_COUNT_TECHNICAL_ERRORS_QUERY = selectCount + from + whereCoherence + andPeriod + andErrorTypeTech + groupBy; + HQL_COUNT_FUNCTIONAL_ERRORS_QUERY = selectCount + from + whereCoherence + andPeriod + andErrorTypeFunc + groupBy; + HQL_MIN_MAX_AVG_DURATION_QUERY = selectStats + from + whereCoherence + andPeriod + andSuccess + groupBy; + } + + private GenJspStats() { + // Nothing to do... + } + + /** + * Generate the content of the Javascript array for all statistics. + */ + public static String generateTimingsTableAsJS(final String aStartPeriod, final String aEndPeriod) throws ParseException { + StringBuilder theJsCode = new StringBuilder(); + Collection theReportStatList = getReportStatList(aStartPeriod, aEndPeriod); + + int theLineCount = 0; + for (ReportStatBean currentStat : theReportStatList) { + theJsCode.append(currentStat.toJs("reportStatArray[" + theLineCount + "]")); + theLineCount++; + } + + return theJsCode.toString(); + } + + /** + * Compute statistics from database. + */ + public static Collection getReportStatList(final String startPeriod, final String endPeriod) throws ParseException { + // Compute the limit date in the past for the analyzed interval + Map statMap = initMap(); + Date parsedStartPeriod = DateHelper.parseDate(startPeriod); + Date parsedEndPeriod = DateHelper.parseDate(endPeriod); + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + countExecutions(parsedStartPeriod, parsedEndPeriod, session, statMap); + countFunctionalErrors(parsedStartPeriod, parsedEndPeriod, session, statMap); + countTechnicalErrors(parsedStartPeriod, parsedEndPeriod, session, statMap); + calcMinMaxAvgDuration(parsedStartPeriod, parsedEndPeriod, session, statMap); + return statMap.values(); + } + finally { + session.close(); + } + } + + private static Map initMap() { + Map statMap = new TreeMap<>(); + for (String reportCode : ReportEnum.getListReportCode()) { + statMap.put(reportCode, new ReportStatBean(reportCode)); + } + return statMap; + } + + private static void countExecutions(final Date startPeriod, final Date endPeriod, final Session hibernateSession, + final Map theStatMap) { + // Fill execution count + Query query = hibernateSession.createQuery(HQL_COUNT_EXECUTIONS_QUERY); + query.setDate(START_PERIOD, startPeriod); + query.setDate(END_PERIOD, endPeriod); + List theResultSet = query.list(); + for (Object[] currentRecord : theResultSet) { + String reportCode = (String) currentRecord[0]; + Long reportCount = (Long) currentRecord[1]; + + ReportStatBean theReportStatBean = theStatMap.get(reportCode); + theReportStatBean.setExecutionCount(reportCount); + } + } + + private static void countFunctionalErrors(final Date aStartPeriod, final Date aEndPeriod, final Session hibernateSession, + final Map theStatMap) { + // Fill functional error count + Query theQuery = hibernateSession.createQuery(HQL_COUNT_FUNCTIONAL_ERRORS_QUERY); + theQuery.setDate(START_PERIOD, aStartPeriod); + theQuery.setDate(END_PERIOD, aEndPeriod); + List theResultSet = theQuery.list(); + for (Object[] currentRecord : theResultSet) { + String theReportCode = (String) currentRecord[0]; + Long theReportCount = (Long) currentRecord[1]; + + ReportStatBean theReportStatBean = theStatMap.get(theReportCode); + theReportStatBean.setFailedFuncCount(theReportCount); + } + } + + private static void countTechnicalErrors(final Date aStartPeriod, final Date aEndPeriod, final Session hibernateSession, + final Map theStatMap) { + // Fill technical error count + Query theQuery = hibernateSession.createQuery(HQL_COUNT_TECHNICAL_ERRORS_QUERY); + theQuery.setDate(START_PERIOD, aStartPeriod); + theQuery.setDate(END_PERIOD, aEndPeriod); + List theResultSet = theQuery.list(); + for (Object[] currentRecord : theResultSet) { + String theReportCode = (String) currentRecord[0]; + Long theReportCount = (Long) currentRecord[1]; + + ReportStatBean theReportStatBean = theStatMap.get(theReportCode); + theReportStatBean.setFailedTechCount(theReportCount); + } + } + + private static void calcMinMaxAvgDuration(final Date startPeriod, final Date endPeriod, final Session hibernateSession, + final Map statMap) { + // Fill min, max and average durations + Query theQuery = hibernateSession.createQuery(HQL_MIN_MAX_AVG_DURATION_QUERY); + theQuery.setDate(START_PERIOD, startPeriod); + theQuery.setDate(END_PERIOD, endPeriod); + List theResultSet = theQuery.list(); + for (Object[] currentRecord : theResultSet) { + String theReportCode = (String) currentRecord[0]; + ReportStatBean theReportStatBean = statMap.get(theReportCode); + + Long theReportMin = (Long) currentRecord[1]; + if (theReportMin != null) { + theReportStatBean.setMinDuration(theReportMin / MILLIS_IN_S); + } + + Double theReportAvg = (Double) currentRecord[2]; + if (theReportAvg != null) { + Long theAvgRepDuration = theReportAvg.longValue(); + theReportStatBean.setAvgDuration(theAvgRepDuration / MILLIS_IN_S); + } + + Long theReportMax = (Long) currentRecord[3]; + if (theReportMax != null) { + theReportStatBean.setMaxDuration(theReportMax / MILLIS_IN_S); + } + } + } + + + private static List generateUserStatBean(Session session, final String startPeriod, final String endPeriod) throws ParseException { + // ref list contains all report + List refListContainsAllReportCode = ReportEnum.getListReportCode(); + + // Get all record + Date parsedStartPeriod = DateHelper.parseDate(startPeriod); + Date parsedEndPeriod = DateHelper.parseDate(endPeriod); + List userReportList = new MngReport().searchUsersReports(session, parsedStartPeriod, parsedEndPeriod); + userReportList.addAll(userReportList.size(), new MngReport().searchAdminSchedulingReports(session, parsedStartPeriod, parsedEndPeriod)); + + Map> mapObjects = new TreeMap<>(); + // objects of period + for (ReportLaunchByUser curReportLaunchByUser : userReportList) { + // current user name + String currentUserName = curReportLaunchByUser.getSurname().concat(" ").concat(curReportLaunchByUser.getFirstName()); + + // if username most exist + if (mapObjects.containsKey(currentUserName)) { + // if you don't have this current reportCode then put it + if (!mapObjects.get(currentUserName).containsKey(curReportLaunchByUser.getReportCode())) { + mapObjects.get(currentUserName).put(curReportLaunchByUser.getReportCode(), curReportLaunchByUser.getReportCount()); + + // Then if total key exist so re-compute + if (mapObjects.get(currentUserName).containsKey(TOTAL)) { + Long curTotal = mapObjects.get(currentUserName).get(TOTAL); + curTotal += curReportLaunchByUser.getReportCount(); + mapObjects.get(currentUserName).put(TOTAL, curTotal); + } + } + } + else { // then create the currentName and put reportCode and reportCount + Map mapDatas = new TreeMap<>(); + mapDatas.put(curReportLaunchByUser.getReportCode(), curReportLaunchByUser.getReportCount()); + mapDatas.put(TOTAL, curReportLaunchByUser.getReportCount()); + mapObjects.put(currentUserName, mapDatas); + } + } + + // Generate object UserStaBean + List usersListStatBean = new ArrayList<>(); + for (Entry> userEntry : mapObjects.entrySet()) { + // temp list for diff + List curListReportCode = new ArrayList<>(); + // create userStatBean + String userName = userEntry.getKey(); + Map datas = userEntry.getValue(); + UserStatBean userStatBean = new UserStatBean(userName); + for (Entry userEntryValues : datas.entrySet()) { + userStatBean.getDatas().put(userEntryValues.getKey(), userEntryValues.getValue().toString()); + curListReportCode.add(userEntryValues.getKey()); + } + // diff + // findAll ref list report + List tempListContainsAllReport = new ArrayList<>(refListContainsAllReportCode); + // diff findAll missing report code + tempListContainsAllReport.removeAll(curListReportCode); + + for (String reportCodeMissing : tempListContainsAllReport) { + userStatBean.getDatas().put(reportCodeMissing, PLACEHOLDER_NUM); + } + // add to list + usersListStatBean.add(userStatBean); + } + + return usersListStatBean; + } + + /** + * Second table implementation for report count per code & user login. + **/ + + public static String generateLaunchCountTableAsJS(final String aStartPeriod, final String aEndPeriod) throws ParseException { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + StringBuilder theJsCode = new StringBuilder(); + List users = generateUserStatBean(session, aStartPeriod, aEndPeriod); + int theLineCount = 0; + for (UserStatBean userStatBean : users) { + theJsCode.append(userStatBean.toJs("userStatArray[" + theLineCount + "]")); + theLineCount++; + } + return theJsCode.toString(); + } + finally { + session.close(); + } + } + + /** + * Generate a list of all users stats for csv + */ + public static List generateLaunchCountTableForCsv(final String aStartPeriod, final String aEndPeriod) throws ParseException { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + return generateUserStatBean(session, aStartPeriod, aEndPeriod); + } + finally { + session.close(); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/stats/ReportStatBean.java b/kurt-utility/src/main/java/com/capgemini/reports/database/stats/ReportStatBean.java new file mode 100644 index 0000000..adc198f --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/stats/ReportStatBean.java @@ -0,0 +1,85 @@ +package com.capgemini.reports.database.stats; + +import com.capgemini.framework.common.TimeHelper; +import lombok.Setter; + +/** + * Bean object carrying Statistical information about a report. + */ +@Setter +public class ReportStatBean { + + /** + * HTML entity for blank character. + **/ + private static final String BLANK_CHAR = " "; + private static final String DELIM = "-"; + private static final String ZERO_STRING = "0"; + private final String reportCode; + private Long executionCount; + private Long failedFuncCount; + private Long failedTechCount; + private Long minDuration; + private Long avgDuration; + private Long maxDuration; + + /** + * Makes an ReportStatBean, using its code as a reference. + * @param aReportCode a report code (R' etc.) + * + */ + public ReportStatBean(final String aReportCode) { + this.reportCode = aReportCode; + } + + /** + * Convert the current bean by Javascript code. + * + * @param aJsArray Name of the JAVA script array + * @return The Javascript code + */ + public String toJs(final String aJsArray) { + return aJsArray + " = new Array();\n" + + aJsArray + "['reportCode'] = '" + nullAsBlank(reportCode) + "';\n" + + aJsArray + "['executionCount'] = '" + nullAsBlank(executionCount) + "';\n" + + aJsArray + "['failedFuncCount'] = '" + nullAsBlank(failedFuncCount) + "';\n" + + aJsArray + "['failedTechCount'] = '" + nullAsBlank(failedTechCount) + "';\n" + + aJsArray + "['minDuration'] = '" + TimeHelper.formatDuration(minDuration) + "';\n" + + aJsArray + "['avgDuration'] = '" + TimeHelper.formatDuration(avgDuration) + "';\n" + + aJsArray + "['maxDuration'] = '" + TimeHelper.formatDuration(maxDuration) + "';\n"; + } + + public String toCsv() { + return reportCode + "," + + contentOrZero(executionCount) + "," + + contentOrZero(failedFuncCount) + "," + + contentOrZero(failedTechCount) + "," + + contentOrZero(minDuration) + "," + + contentOrZero(avgDuration) + "," + + contentOrZero(maxDuration); + } + + private String contentOrZero(final Long exec) { + return exec == null ? ZERO_STRING : exec.toString(); + } + + /** + * Display null values with a blank character. + * + * @param value Value which should be converted. + * @return The string value. + */ + private String nullAsBlank(final Object value) { + return value == null ? BLANK_CHAR : value.toString(); + } + + + @Override + public String toString() { + return "ReportStatBean [reportCode=" + reportCode + ", executionCount=" + executionCount + ", failedFuncCount=" + failedFuncCount + + ", failedTechCount=" + failedTechCount + ", minDuration=" + minDuration + ", avgDuration=" + avgDuration + ", maxDuration=" + + maxDuration + "]"; + } + + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/database/stats/UserStatBean.java b/kurt-utility/src/main/java/com/capgemini/reports/database/stats/UserStatBean.java new file mode 100644 index 0000000..b0e91dd --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/database/stats/UserStatBean.java @@ -0,0 +1,69 @@ +package com.capgemini.reports.database.stats; + +import lombok.Getter; +import lombok.Setter; + +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +/** + * Bean object carrying Statistical information about a report. + */ +@Getter +@Setter +public class UserStatBean { + + private static final String TOTAL = "total"; + + /** + * HTML entity for blank character. + **/ + private static final String BLANK_CHAR = " "; + + private String name; + private Map datas = new TreeMap<>(); + + /** + * Make a simple bean containing stats about a user. + * + * @param name the user name + */ + public UserStatBean(final String name) { + this.name = name; + } + + /** + * Convert the current bean by Javascript code. + * + * @param aJsArrayName Name of the JAVA script array + * @return The Javascript code + */ + public String toJs(final String aJsArrayName) { + StringBuilder theJsCodeBuilder = new StringBuilder(aJsArrayName).append(" = new Array();\n"); + theJsCodeBuilder.append(aJsArrayName).append("['name'] = \"").append(nullAsBlank(name)).append("\";\n"); + for (Entry entry : datas.entrySet()) { + if (entry.getKey().equals(TOTAL)) { + theJsCodeBuilder.append(aJsArrayName).append("['Global'] = '").append(nullAsBlank(entry.getValue())).append("';\n"); + } else { + theJsCodeBuilder.append(aJsArrayName).append("['").append(entry.getKey()).append("'] = '").append(nullAsBlank(entry.getValue())).append("';\n"); + } + } + return theJsCodeBuilder.toString(); + } + + /** + * Display null values with a blank character. + * + * @param aValue Value which should be converted. + * @return The string value. + */ + private String nullAsBlank(final Object aValue) { + return aValue == null ? BLANK_CHAR : aValue.toString(); + } + + @Override + public String toString() { + return "UserStatBean [name=" + name + ", datas=" + datas + "]"; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/DataReportPreparatorR01.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/DataReportPreparatorR01.java new file mode 100644 index 0000000..f15dbae --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/DataReportPreparatorR01.java @@ -0,0 +1,110 @@ +package com.capgemini.reports.definition.r01report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObjectFactory; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRule; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRuleProperties; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.product.TcProduct; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.product.TcProductRevision; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindow; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindowConfiguration; +import com.capgemini.framework.teamcenter.object.runtime.TcRevisionRulesConfiguration; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderFactory; +import com.capgemini.reports.bomlineholder.processor.DefaultAltOrDetBehaviour; +import com.capgemini.reports.definition.r01report.visitors.R01Visitor; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.filter.AllIsGoodFilter; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.reports.parameters.MonoMulti; +import com.capgemini.reports.teamcenter.resolution.structureservice.IStructureServiceCaller; +import com.capgemini.reports.teamcenter.resolution.structureservice.MultiStructureServiceCaller; +import com.capgemini.reports.teamcenter.resolution.structureservice.TripleStructureServiceCaller; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Form; +import com.teamcenter.soa.client.model.strong.PSBOMView; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * This class will allow to prepare data and findAll back data for making report R01. + */ +class DataReportPreparatorR01 implements IDataReportPreparator { + private static final long serialVersionUID = -1029419855928264125L; + private static final Logger LOGGER = LoggerFactory.getLogger(DataReportPreparatorR01.class); + + private static final AllIsGoodFilter ACCEPT_ALL = new AllIsGoodFilter(); + + @Override + public String print(TcSession session, ExecutionR01 execution, IExecutionStrategy executionStrategy) throws KurtException { + PrintParameters printParameters = prepareData(session, execution); + executionStrategy.print(printParameters, execution); + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + } + + private PrintParameters prepareData(final TcSession session, final ExecutionR01 report) throws KurtException { + LOGGER.debug("PrepareData started on: {}", report.getReportIdentifier().getReportTitle()); + + TcBomObject topLineObject= new TcBomObjectFactory(session, report.getGeneric().getItem(session)).create(); + TcProduct productObject = new TcProduct(session, report.getProductUnit().getProduct(session)); + TcProductRevision productObjectRevision = productObject.revisions().get(0); + int unit = report.getProductUnit().getUnit(); + EffectivityDate effectivityDate = report.getEffectivityDate(); + + TcRevisionRuleProperties revisionRuleProperties = new TcRevisionRuleProperties(productObject, unit, effectivityDate.isNow() ? null : effectivityDate.getDateTime()); + TcRevisionRule revisionRule = session.findRevRule(report.getRevisionRule()); + TcRevisionRulesConfiguration revRulesConfiguration = new TcRevisionRulesConfiguration(revisionRule, revisionRuleProperties); + + IStructureServiceCaller service; + if (MonoMulti.MONO.equals(report.getMonoMulti())) { + service = new TripleStructureServiceCaller(session); + } else { + service = new MultiStructureServiceCaller(session); + } + + TcBomWindowConfiguration tcBomWindowConfiguration ; + if (report.isSuperModelBOM()) { + PSBOMView modelBom = productObjectRevision.bomViewRev(); + tcBomWindowConfiguration = new TcBomWindowConfiguration (topLineObject,modelBom,revRulesConfiguration); + } else { + tcBomWindowConfiguration = new TcBomWindowConfiguration(topLineObject, revRulesConfiguration); + } + + try (TcBomWindow bomWindow = session.createBomWindow(tcBomWindowConfiguration)) { + session.setObjectPropPolicy(report.getFullPolicy()); + BOMLineHolder unbuiltTopLine = service.resolve(bomWindow.topLine(), ACCEPT_ALL); + List
itemRevMaster = unbuiltTopLine.getAllItemRevMasters(); + session.loadProperties(itemRevMaster.toArray(new ModelObject[itemRevMaster.size()])); + + BOMLineHolderFactory.buildTopBom(session, unbuiltTopLine, ACCEPT_ALL); + DefaultAltOrDetBehaviour aBOMLineHolderProcessor = new DefaultAltOrDetBehaviour<>(session, effectivityDate.isNow() ? null : effectivityDate.getDateTime()); + unbuiltTopLine.process(aBOMLineHolderProcessor); + unbuiltTopLine.freeze(); + + R01Visitor visitor = new R01Visitor(); + PrintParameters printParameters = visitor.makeMasterTemplate(report, unbuiltTopLine); + visitor.constructDataMaps(session, printParameters, unbuiltTopLine); + + LOGGER.debug("PrepareData ended on: {}", report.getReportIdentifier().getReportTitle()); + return printParameters; + } catch (EmptyNomenclatureException e) { + switch (report.getGeneric().getType()) { + case GENERIC: + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_PRODUCT_AND_UNIT, e); + case GENERIC_ASSEMB: + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_ASSEMB_PRODUCT_AND_UNIT, e); + default: + throw new KurtException("The TC Nomenclature Resolution returned null", e); + } + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/ExecutionR01.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/ExecutionR01.java new file mode 100644 index 0000000..2619ba8 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/ExecutionR01.java @@ -0,0 +1,170 @@ +package com.capgemini.reports.definition.r01report; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.builder.R01Builder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.reports.parameters.*; +import com.capgemini.reports.reports.parameters.Generics.GenericType; +import com.capgemini.reports.reports.parameters.checker.*; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.List; + +/** + * Obtain data for report R01.
+ * Contain {@link IChecker} for a report's construction + */ +@Getter +@EqualsAndHashCode(callSuper = true) +public class ExecutionR01 extends AbstractExecutionReport { + private static final long serialVersionUID = -2173366731814318218L; + + private static final DataReportPreparatorR01 DATA_REPORT_PREPARATOR_R01 = new DataReportPreparatorR01(); + + // Policies parameters + private static final PolicyLocation R01_POLICY_XML_LIGHT = + PolicyLocation.make("R01_policy_light", "/xml/policies/r01report/R01_policy_light.xml"); + private static final PolicyLocation R01_POLICY_XML_FULL = PolicyLocation.make("R01_policy_full", "/xml/policies/r01report/R01_policy_full.xml"); + /** + * Policy for inspecting Alternates and DETs more closely (i.e. looking into their pseudo-folders for alternative parts). + */ + public static final PolicyLocation R01_POLICY_XML_ALT = PolicyLocation.make("R01_policy_alt", "/xml/policies/r01report/R01_policy_alt.xml"); + + + // Launch type parameter + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R01"); + + // Revision rule parameter + private static final String REPORT_REVISION_RULE = + SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R01", DEFAULT_REVISION_RULE); + + // Priority parameter + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R01); + + // Internal working data + private final Generics generic; + private final MonoMulti monoMulti; + private final ProductUnit productUnit; + private final EffectivityDate effectivityDate; + private final boolean isSuperModelBOM; + + @Setter + private BOMLineHolder topLine; + + /** + * Constructor + * + * @param aProductUnit {@link ProductUnit} - the product and unit + * @param aGeneric le generic {@link Generics} - represent the generic. Can be null if the wanted configuration is only with the Product and the Unit. + * @param aMonoMulti {@link MonoMulti} - represent the type of resolution structure + * @param effectivityDate {@link EffectivityDate} - represent the effectivity date + */ + public ExecutionR01(final ProductUnit aProductUnit, final Generics aGeneric, final MonoMulti aMonoMulti, final EffectivityDate effectivityDate, final boolean isSuperModelBOM) { + super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE); + this.productUnit = aProductUnit; + this.generic = aGeneric; + this.monoMulti = aMonoMulti; + this.effectivityDate = effectivityDate; + this.isSuperModelBOM = isSuperModelBOM; + } + + @Override + public List getLaunchData() { + List theCriteria = new ArrayList<>(); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PRODUCT, productUnit.getProductID())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.UNIT, productUnit.getUnitStr())); + if (generic.getType() == GenericType.GENERIC) { + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC, generic.getID())); + } + if (generic.getType() == GenericType.GENERIC_ASSEMB) { + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC_ASSEMB, generic.getID())); + } + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.MONO_MULTI, monoMulti.toString())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.SUPERMODEL, Boolean.toString(isSuperModelBOM))); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.EFFECTIVITY_DATE, effectivityDate.formatAsInputCriteria())); + return theCriteria; + } + + @Override + public String getSpecifiedFileName() { + String separator = "-"; + StringBuilder builder = new StringBuilder("R01-"); + if (generic.getType() != GenericType.ONLY_PRODUCT) { + builder.append(generic.getID()).append(separator); + } + builder.append(productUnit.getProductID()).append(separator); + builder.append(productUnit.getUnit()).append(separator); + builder.append(monoMulti.toString()); + return builder.toString(); + } + + @Override + public PrintFormat getPrintingFormat() { + return PrintFormat.XLSX; + } + + @Override + public ReportEnum getReportIdentifier() { + return ReportEnum.REPORT_R01; + } + + @Override + public List getQuickChecks() { + List quickChecks = new ArrayList<>(); + quickChecks.add(new GenericExistenceChecker(generic)); + quickChecks.add(new ProductChecker(productUnit.getProductID())); + quickChecks.add(new ProductUnitChecker(productUnit)); + quickChecks.add(new EffectivityChecker(effectivityDate)); + return quickChecks; + } + + @Override + public List getLongChecks() { + List longChecks = new ArrayList<>(); + longChecks.add(new GenericUnderProductUnitChecker(generic)); + return longChecks; + } + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R01_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R01_POLICY_XML_FULL; + } + + @Override + public String getTemplateLocation() { + return JasperTemplate.TEMPLATE_R01.getFilepath(); + } + + @Override + public IDataReportPreparator getDataPreparator() { + return DATA_REPORT_PREPARATOR_R01; + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return new ExecutionR01(productUnit, generic, monoMulti, effectivityDate, isSuperModelBOM); + } + + @Override + public Class getReportBuilderClass() { + return R01Builder.class; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/visitors/R01Visitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/visitors/R01Visitor.java new file mode 100644 index 0000000..6279fd5 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/visitors/R01Visitor.java @@ -0,0 +1,103 @@ +package com.capgemini.reports.definition.r01report.visitors; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.definition.r01report.ExecutionR01; +import com.capgemini.reports.definition.r01report.visitors.bomlineholder.R01BOMLineHolderVisitor; +import com.capgemini.reports.execution.mapconstructor.AbstractStaticTemplateMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.reports.IReportVisitor; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +/** + * Visit a R01 report. + */ +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class R01Visitor extends AbstractStaticTemplateMapConstructor implements IReportVisitor { + + private static final long serialVersionUID = -943826236018829172L; + private static final String NULL = ""; + private static final String EMPTY = ""; + + protected final R01BOMLineHolderVisitor r01BOMLineHolderVisitor = new R01BOMLineHolderVisitor(); + + /** + * Constructor. + */ + public R01Visitor() { + super(); + } + + private static String check(final Object anInput) { + return anInput == null ? NULL : anInput.toString(); + } + + /** + * Translate the specific result of the visitor into something the printer can understand. + */ + private List> translate(final List> visitorMaps) { + // Add empty fields in the first line + Map firstLine = visitorMaps.get(0); + // Empty receptor + firstLine.put(R01VisitorKeys.IDENTIFIANT_RECEPTEUR, EMPTY); + firstLine.put(R01VisitorKeys.REVISION_RECEPTEUR, EMPTY); + firstLine.put(R01VisitorKeys.NOM_RECEPTEUR, EMPTY); + // Empty RF + firstLine.put(R01VisitorKeys.REPERE_FONCTIONNEL, EMPTY); + firstLine.put(R01VisitorKeys.REVISION_REPERE_FONCTIONNEL, EMPTY); + firstLine.put(R01VisitorKeys.IDENTIFIANT_REPERE_FONCTIONNEL, EMPTY); + firstLine.put(R01VisitorKeys.MAQUETTE, EMPTY); + firstLine.put(R01VisitorKeys.TRANSFERT_LIEN_LOGISTIQUE, EMPTY); + firstLine.put(R01VisitorKeys.TRANSFERT_LIEN_MONTAGE, EMPTY); + firstLine.put(R01VisitorKeys.UIN, EMPTY); + firstLine.put(R01VisitorKeys.EQUIVALENT_SNSSIN, EMPTY); + firstLine.put(R01VisitorKeys.RESPONSABLE_REPERE, EMPTY); + firstLine.put(R01VisitorKeys.SUIVI_MONTAGE, EMPTY); + // Empty BOM + firstLine.put(R01VisitorKeys.ALT, EMPTY); + firstLine.put(R01VisitorKeys.SB, EMPTY); + firstLine.put(R01VisitorKeys.QUANTITE_CUMULEE, EMPTY); + firstLine.put(R01VisitorKeys.PANACHE, EMPTY); + firstLine.put(R01VisitorKeys.QUANTITE, EMPTY); + + // Construct the map list expected by the printer + List> printerMaps = new ArrayList<>(); + for (Map visitorMap : visitorMaps) { + Map printerMap = new HashMap<>(); + for (R01VisitorKeys key : R01VisitorKeys.values()) { + printerMap.put(key.toString(), check(visitorMap.get(key))); + } + printerMaps.add(printerMap); + } + + return printerMaps; + } + + @Override + public List> visitReport(final BOMLineHolder holder) { + List> visitorMaps = r01BOMLineHolderVisitor.visitTopReceptorBom(holder); + return translate(visitorMaps); + } + + @Override + public void constructDataMaps(TcSession session, final PrintParameters printParameters, final BOMLineHolder data) throws KurtException { + long start = System.currentTimeMillis(); + if (data == null) { + throw new NoSuchElementException("No Product structure found"); + } + + // Parse all the snecma objects... + List> printerMaps = this.visitReport(data); + printParameters.addReportData(printerMaps); + log.info("Filtering time : {} ms", System.currentTimeMillis() - start); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/visitors/R01VisitorKeys.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/visitors/R01VisitorKeys.java new file mode 100644 index 0000000..50b845a --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/visitors/R01VisitorKeys.java @@ -0,0 +1,49 @@ +package com.capgemini.reports.definition.r01report.visitors; + +/** + * Enumeration of all the columns of the R01 report. + */ +public enum R01VisitorKeys { + IDENTIFIANT_RECEPTEUR, + REVISION_RECEPTEUR, + NOM_RECEPTEUR, + REPERE_FONCTIONNEL, + REVISION_REPERE_FONCTIONNEL, + UIN, + EQUIVALENT_SNSSIN, + RESPONSABLE_REPERE, + SUIVI_MONTAGE, + ALT, + SB, + QUANTITE_CUMULEE, + PANACHE, + QUANTITE, + REF_FABRICANT_REF_SNECMA, + REVISION_REFERENCE, + REFERENCE_CONCEPTEUR, + TYPE_REFERENCE, + NOM_REFERENCE, + DESIGNATION_EN, + REFERENCE_TRANSPOSEE, + RESPONSABLE_CONCEPTION, + ALTERNATIVE, + CLASSEMENT, + SUIVI_UTILISATION, + SUIVI_DUREE_VIE, + MASSE_INDICATIVE, + UNITE_DE_MASSE, + IDENTIFIANT_REPERE_FONCTIONNEL, + MAQUETTE, + TRANSFERT_LIEN_LOGISTIQUE, + TRANSFERT_LIEN_MONTAGE, + STATUT_REFERENCE_ARTICLE, + SUIVI_DEVELOPPEMENT, + TYPE_PRODUIT, + DOCUMENT_CONTROLE, + OBTURATION, + MOT_CLE_EN, + MOT_CLE_FR, + DATE_PEREMPTION, + CR, + CN +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/visitors/bomlineholder/R01AltOrDetBehaviour.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/visitors/bomlineholder/R01AltOrDetBehaviour.java new file mode 100644 index 0000000..9fdae43 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/visitors/bomlineholder/R01AltOrDetBehaviour.java @@ -0,0 +1,61 @@ +package com.capgemini.reports.definition.r01report.visitors.bomlineholder; + +import com.capgemini.reports.bomlineholder.processor.AltOrDetBehaviour; +import com.capgemini.reports.definition.r01report.visitors.R01VisitorKeys; +import com.capgemini.reports.snecmaobjects.part.AlternateRevision; +import com.capgemini.reports.snecmaobjects.part.DETRevision; + +import java.util.Map; + +/** + * This class visits Parts that are below an {@link AlternateRevision} or a {@link DETRevision}.
+ * It puts "Oui" in the ALTERNATIVE field of a map. + */ +public class R01AltOrDetBehaviour implements AltOrDetBehaviour { + private static final long serialVersionUID = -1337127910440186192L; + + private static final String OUI = "Oui"; + private static final String EMPTY_STRING = ""; + + @Override + public boolean shouldVisitPartsInPseudoFolder() { + return true; + } + + @Override + public boolean shouldVisitPartsBelowAlt() { + return true; + } + + @Override + public void treatPartsInPseudoFolder(final Map map) { + treatAnyPartBelowThisAltOrDet(map); + } + + @Override + public void treatAlternateOrDETAsReceptor(final Map map) { + treatAnyPartBelowThisAltOrDet(map); + } + + private void treatAnyPartBelowThisAltOrDet(final Map map) { + // Empty fields + map.put(R01VisitorKeys.REPERE_FONCTIONNEL, EMPTY_STRING); + map.put(R01VisitorKeys.IDENTIFIANT_REPERE_FONCTIONNEL, EMPTY_STRING); + map.put(R01VisitorKeys.REVISION_REPERE_FONCTIONNEL, EMPTY_STRING); + map.put(R01VisitorKeys.MAQUETTE, EMPTY_STRING); + map.put(R01VisitorKeys.UIN, EMPTY_STRING); + map.put(R01VisitorKeys.EQUIVALENT_SNSSIN, EMPTY_STRING); + map.put(R01VisitorKeys.RESPONSABLE_REPERE, EMPTY_STRING); + map.put(R01VisitorKeys.TRANSFERT_LIEN_LOGISTIQUE, EMPTY_STRING); + map.put(R01VisitorKeys.TRANSFERT_LIEN_MONTAGE, EMPTY_STRING); + map.put(R01VisitorKeys.SUIVI_MONTAGE, EMPTY_STRING); + map.put(R01VisitorKeys.ALT, EMPTY_STRING); + map.put(R01VisitorKeys.SB, EMPTY_STRING); + map.put(R01VisitorKeys.QUANTITE_CUMULEE, EMPTY_STRING); + map.put(R01VisitorKeys.PANACHE, EMPTY_STRING); + map.put(R01VisitorKeys.QUANTITE, EMPTY_STRING); + + // Mention that these parts are alternatives to each other + map.put(R01VisitorKeys.ALTERNATIVE, OUI); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/visitors/bomlineholder/R01BOMLineHolderVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/visitors/bomlineholder/R01BOMLineHolderVisitor.java new file mode 100644 index 0000000..6e830d1 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/visitors/bomlineholder/R01BOMLineHolderVisitor.java @@ -0,0 +1,83 @@ +package com.capgemini.reports.definition.r01report.visitors.bomlineholder; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.visitor.AbstractBOMLineHolderVisitor; +import com.capgemini.reports.definition.r01report.visitors.R01VisitorKeys; +import com.capgemini.reports.definition.r01report.visitors.snecmaobject.R01ComponentVisitor; +import com.capgemini.reports.definition.r01report.visitors.snecmaobject.R01ReceptorVisitor; +import com.capgemini.reports.releasestatus.EffectivityBehaviourHelper; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.Map; + +/** + * Visitor of an expansion of BOMLineHolder for the R01 report. + */ +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class R01BOMLineHolderVisitor extends AbstractBOMLineHolderVisitor { + private static final long serialVersionUID = -2136631482354508026L; + + public R01BOMLineHolderVisitor() { + super(new R01ReceptorVisitor(), new R01ComponentVisitor(), EffectivityBehaviourHelper.visitAnyPart(), + new R01AltOrDetBehaviour(), true, true, true); + } + + @Override + protected Map visitThisReceptor(final BOMLineHolder aBomLine) { + return aBomLine.getSnecmaObject().accept(receptorVisitor); + } + + @Override + protected Map visitThisComponent(final BOMLineHolder aBomLine) { + Map aMap = aBomLine.getSnecmaObject().accept(componentVisitor); + + // Put the BOMLine properties into the map + if ((aBomLine.getSnecmaObject().isGeneric()) || (aBomLine.getSnecmaObject().isPart()) || aBomLine.getSnecmaObject().isSuperModel()) { + aMap.put(R01VisitorKeys.ALT, aBomLine.getBomAlt()); + aMap.put(R01VisitorKeys.SB, aBomLine.getBomSb()); + aMap.put(R01VisitorKeys.QUANTITE_CUMULEE, aBomLine.getBomQtyCumul()); + aMap.put(R01VisitorKeys.PANACHE, aBomLine.getBomPanache()); + aMap.put(R01VisitorKeys.QUANTITE, aBomLine.getBomQty()); + aMap.put(R01VisitorKeys.UIN, aBomLine.getUin()); + } + return aMap; + } + + @Override + protected void visitSpecificFirstLine(final BOMLineHolder aTopBomLine) { + Map theFirstLine = aTopBomLine.getSnecmaObject().accept(getComponentVisitor()); + theReportTable.add(theFirstLine); + } + + @Override + protected void mergeReceptorAndRepereReceptor(final Map aReceptor, final Map aRepereReceptor) { + aReceptor.putAll(aRepereReceptor); + } + + @Override + protected void mergeComponentAndRepereComponent(final Map aComponent, final Map aRepereComponent) { + aComponent.putAll(aRepereComponent); + } + + @Override + protected void mergeRepereReceptorandAdmin(final Map aRepereReceptor, final Map anAdmin) { + aRepereReceptor.putAll(anAdmin); + } + + @Override + protected void mergeRepereComponentandAdmin(final Map aRepereComponent, final Map anAdmin) { + aRepereComponent.putAll(anAdmin); + } + + @Override + protected void addToReport(final Map aReceptor, final Map aComponent) { + // Put the Receptor and Repere Receptor in the Component and modify the Component + // Do not modify the receptor + aComponent.putAll(aReceptor); + + // Add to the R21 report + theReportTable.add(aComponent); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/visitors/snecmaobject/R01ComponentVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/visitors/snecmaobject/R01ComponentVisitor.java new file mode 100644 index 0000000..48a7f24 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/visitors/snecmaobject/R01ComponentVisitor.java @@ -0,0 +1,393 @@ +package com.capgemini.reports.definition.r01report.visitors.snecmaobject; + +import com.capgemini.framework.common.DoubleFormatter; +import com.capgemini.framework.common.LanguageHelper; +import com.capgemini.framework.teamcenter.object.pom.status.TcReleaseStatus; +import com.capgemini.reports.definition.r01report.visitors.R01VisitorKeys; +import com.capgemini.reports.snecmaobjects.AbstractSnecmaObject; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAGRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision; +import com.capgemini.reports.snecmaobjects.generic.AbstractGenericRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericAssembRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.mockup.MockupRevision; +import com.capgemini.reports.snecmaobjects.part.*; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.snecmaobjects.rf.AbstractRF; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartAssembRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartRevision; +import com.capgemini.reports.snecmaobjects.supermodel.AbstractSuperModelRevision; +import com.capgemini.reports.snecmaobjects.supermodel.SuperModelRevision; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; + +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +/** + * Visit a Component SnecmaObject to make a R01 report. + */ +public class R01ComponentVisitor implements IComponentVisitor> { + private static final long serialVersionUID = -2446473004152109053L; + + private static final int MASS_SIGNIFICANT_DIGITS = 15; + private static final String EMPTY_STRING = ""; + private static final String PART_MAT = "PartMat"; + private static final String SEPARATOR = " / "; + private static final String VALUE_MATIERE = "matière"; + private static final String PRODUIT = "Produit"; + private static final String GENERIQUE_MONTAGE = "Générique Montage"; + private static final String GENERIQUE = "Générique"; + private static final String PARAM_NON = "Non"; + private static final String PARAM_OUI = "Oui"; + private static final String SOLO_SEPARATOR = "/"; + + private static String french(final String string) { + return LanguageHelper.french(string); + } + + @Override + public Map visitComponent(final ProductRevision aProductRev) { + Map theMap = getAbstractSnecmaObjectProperties(aProductRev); + theMap.put(R01VisitorKeys.DESIGNATION_EN, aProductRev.getDesignationEN()); + theMap.put(R01VisitorKeys.TYPE_PRODUIT, aProductRev.getTypeProduit()); + theMap.put(R01VisitorKeys.TYPE_REFERENCE, PRODUIT); + theMap.put(R01VisitorKeys.SUIVI_UTILISATION, PARAM_NON); + theMap.put(R01VisitorKeys.SUIVI_DUREE_VIE, PARAM_NON); + theMap.put(R01VisitorKeys.REFERENCE_CONCEPTEUR, EMPTY_STRING); + theMap.put(R01VisitorKeys.REFERENCE_TRANSPOSEE, EMPTY_STRING); + theMap.put(R01VisitorKeys.RESPONSABLE_CONCEPTION, EMPTY_STRING); + theMap.put(R01VisitorKeys.MASSE_INDICATIVE, EMPTY_STRING); + theMap.put(R01VisitorKeys.UNITE_DE_MASSE, EMPTY_STRING); + theMap.put(R01VisitorKeys.STATUT_REFERENCE_ARTICLE, statutReferenceArticle(aProductRev.getStatusList())); + theMap.put(R01VisitorKeys.CLASSEMENT, "-"); + theMap.put(R01VisitorKeys.ALTERNATIVE, EMPTY_STRING); + theMap.put(R01VisitorKeys.SUIVI_DEVELOPPEMENT, EMPTY_STRING); + theMap.put(R01VisitorKeys.DOCUMENT_CONTROLE, EMPTY_STRING); + theMap.put(R01VisitorKeys.OBTURATION, EMPTY_STRING); + theMap.put(R01VisitorKeys.DATE_PEREMPTION, EMPTY_STRING); + theMap.put(R01VisitorKeys.MOT_CLE_EN, EMPTY_STRING); + theMap.put(R01VisitorKeys.MOT_CLE_FR, EMPTY_STRING); + theMap.put(R01VisitorKeys.CR, EMPTY_STRING); + theMap.put(R01VisitorKeys.CN, EMPTY_STRING); + return theMap; + } + + private String statutReferenceArticle(final List statuses) { + StringBuilder builder = new StringBuilder(); + int size = statuses.size(); + for (int i = 0; i < size; i++) { + builder.append(statuses.get(i).getDisplayableName()); + if (i != size - 1) { + builder.append(", "); + } + } + return builder.toString(); + } + + @Override + public Map visitComponent(final GenericRevision aGenericRev) { + Map theMap = getAbstractSnecmaObjectProperties(aGenericRev); + theMap.put(R01VisitorKeys.TYPE_REFERENCE, GENERIQUE); + putGenericProperties(theMap, aGenericRev); + return theMap; + } + + @Override + public Map visitComponent(final GenericAssembRevision aGenericAssembRev) { + Map theMap = getAbstractSnecmaObjectProperties(aGenericAssembRev); + theMap.put(R01VisitorKeys.TYPE_REFERENCE, GENERIQUE_MONTAGE); + putGenericProperties(theMap, aGenericAssembRev); + return theMap; + } + + @Override + public Map visitComponent(final SuperModelRevision aSuperModelRev) { + Map theMap = getAbstractSnecmaObjectProperties(aSuperModelRev); + theMap.put(R01VisitorKeys.TYPE_REFERENCE, GENERIQUE); + putSuperModelProperties(theMap, aSuperModelRev); + return theMap; + } + + + @Override + public Map visitComponent(final AlternateRevision anAlternateRev) { + Map theMap = getAbstractSnecmaObjectProperties(anAlternateRev); + putPartProperties(theMap, anAlternateRev); + theMap.put(R01VisitorKeys.TYPE_REFERENCE, french(anAlternateRev.getTypeAlt1()) + SEPARATOR + french(anAlternateRev.getTypeAlt2())); + theMap.put(R01VisitorKeys.SUIVI_DEVELOPPEMENT, french(anAlternateRev.getSuiviDeveloppement())); + theMap.put(R01VisitorKeys.DOCUMENT_CONTROLE, french(anAlternateRev.getDocumentControle())); + theMap.put(R01VisitorKeys.OBTURATION, french(anAlternateRev.getObturation())); + theMap.put(R01VisitorKeys.DATE_PEREMPTION, EMPTY_STRING); + return theMap; + } + + @Override + public Map visitComponent(final DETRevision aDetRev) { + Map theMap = getAbstractSnecmaObjectProperties(aDetRev); + putPartProperties(theMap, aDetRev); + theMap.put(R01VisitorKeys.TYPE_REFERENCE, french(aDetRev.getTypeDet1()) + SEPARATOR + french(aDetRev.getTypeDet2())); + theMap.put(R01VisitorKeys.SUIVI_DEVELOPPEMENT, french(aDetRev.getSuiviDeveloppement())); + theMap.put(R01VisitorKeys.DOCUMENT_CONTROLE, french(aDetRev.getDocumentControle())); + theMap.put(R01VisitorKeys.OBTURATION, french(aDetRev.getObturation())); + return theMap; + } + + @Override + public Map visitComponent(final PartAeroRevision aPartAeroRev) { + Map theMap = getAbstractSnecmaObjectProperties(aPartAeroRev); + putPartProperties(theMap, aPartAeroRev); + theMap.put(R01VisitorKeys.TYPE_REFERENCE, french(aPartAeroRev.getTypeAero1()) + SEPARATOR + french(aPartAeroRev.getTypeAero2()) + SEPARATOR + french(aPartAeroRev.getTypeAero3())); + theMap.put(R01VisitorKeys.SUIVI_DEVELOPPEMENT, french(aPartAeroRev.getSuiviDeveloppement())); + theMap.put(R01VisitorKeys.DOCUMENT_CONTROLE, french(aPartAeroRev.getDocumentControle())); + theMap.put(R01VisitorKeys.OBTURATION, french(aPartAeroRev.getObturation())); + return theMap; + } + + @Override + public Map visitComponent(final PartNoAeroRevision aPartNoAeroRev) { + Map theMap = getAbstractSnecmaObjectProperties(aPartNoAeroRev); + putPartProperties(theMap, aPartNoAeroRev); + theMap.put(R01VisitorKeys.TYPE_REFERENCE, french(aPartNoAeroRev.getTypeNoAero())); + theMap.put(R01VisitorKeys.SUIVI_DEVELOPPEMENT, french(aPartNoAeroRev.getSuiviDeveloppement())); + theMap.put(R01VisitorKeys.DOCUMENT_CONTROLE, french(aPartNoAeroRev.getDocumentControle())); + theMap.put(R01VisitorKeys.OBTURATION, EMPTY_STRING); + theMap.put(R01VisitorKeys.DATE_PEREMPTION, EMPTY_STRING); + return theMap; + } + + @Override + public Map visitComponent(final PartAssembRevision aPartAssembRev) { + Map theMap = getAbstractSnecmaObjectProperties(aPartAssembRev); + putPartProperties(theMap, aPartAssembRev); + theMap.put(R01VisitorKeys.TYPE_REFERENCE, french(aPartAssembRev.getTypePartMontage1()) + SEPARATOR + french(aPartAssembRev.getTypePartMontage2())); + theMap.put(R01VisitorKeys.SUIVI_DEVELOPPEMENT, EMPTY_STRING); + theMap.put(R01VisitorKeys.DOCUMENT_CONTROLE, french(aPartAssembRev.getDocumentControle())); + theMap.put(R01VisitorKeys.OBTURATION, EMPTY_STRING); + theMap.put(R01VisitorKeys.DATE_PEREMPTION, EMPTY_STRING); + return theMap; + } + + @Override + public Map visitComponent(final PartMatRevision aPartMatRev) { + Map theMap = getAbstractSnecmaObjectProperties(aPartMatRev); + putPartProperties(theMap, aPartMatRev); + theMap.put(R01VisitorKeys.TYPE_REFERENCE, VALUE_MATIERE); + theMap.put(R01VisitorKeys.CLASSEMENT, aPartMatRev.getClassementMat()); + theMap.put(R01VisitorKeys.MASSE_INDICATIVE, EMPTY_STRING); + theMap.put(R01VisitorKeys.UNITE_DE_MASSE, EMPTY_STRING); + theMap.put(R01VisitorKeys.SUIVI_UTILISATION, PARAM_NON); + theMap.put(R01VisitorKeys.SUIVI_DUREE_VIE, PARAM_NON); + theMap.put(R01VisitorKeys.SUIVI_DEVELOPPEMENT, EMPTY_STRING); + theMap.put(R01VisitorKeys.DOCUMENT_CONTROLE, EMPTY_STRING); + theMap.put(R01VisitorKeys.OBTURATION, EMPTY_STRING); + theMap.put(R01VisitorKeys.DATE_PEREMPTION, EMPTY_STRING); + theMap.put(R01VisitorKeys.MOT_CLE_EN, EMPTY_STRING); + theMap.put(R01VisitorKeys.MOT_CLE_FR, EMPTY_STRING); + return theMap; + } + + @Override + public Map visitComponent(final StandardRevision aStandardRev) { + Map theMap = getAbstractSnecmaObjectProperties(aStandardRev); + putPartProperties(theMap, aStandardRev); + theMap.put(R01VisitorKeys.TYPE_REFERENCE, french(aStandardRev.getTypeStandard())); + theMap.put(R01VisitorKeys.SUIVI_DEVELOPPEMENT, french(aStandardRev.getSuiviDeveloppement())); + theMap.put(R01VisitorKeys.DOCUMENT_CONTROLE, french(aStandardRev.getDocumentControle())); + theMap.put(R01VisitorKeys.OBTURATION, EMPTY_STRING); + return theMap; + } + + /** + * Get Component properties to make a R01 report. + * + * @param anAbstractSnecmaObject AbstractSnecmaObject + * @return theMap Map + */ + private Map getAbstractSnecmaObjectProperties(final AbstractSnecmaObject anAbstractSnecmaObject) { + Map theMap = new EnumMap<>(R01VisitorKeys.class); + theMap.put(R01VisitorKeys.REF_FABRICANT_REF_SNECMA, anAbstractSnecmaObject.getItemId()); + theMap.put(R01VisitorKeys.NOM_REFERENCE, anAbstractSnecmaObject.getName()); + theMap.put(R01VisitorKeys.REVISION_REFERENCE, anAbstractSnecmaObject.getRevisionId()); + theMap.put(R01VisitorKeys.ALTERNATIVE, EMPTY_STRING); + return theMap; + } + + /** + * Put the Generic properties into aMap. + * + * @param aMap Map + * @param anAbstractGenericRevision AbstractGenericRevision + */ + private void putGenericProperties(final Map aMap, final AbstractGenericRevision anAbstractGenericRevision) { + aMap.put(R01VisitorKeys.DESIGNATION_EN, anAbstractGenericRevision.getDesignationEN()); + aMap.put(R01VisitorKeys.RESPONSABLE_CONCEPTION, anAbstractGenericRevision.getResponsableConception()); + aMap.put(R01VisitorKeys.SUIVI_UTILISATION, PARAM_OUI); + aMap.put(R01VisitorKeys.SUIVI_DUREE_VIE, PARAM_NON); + aMap.put(R01VisitorKeys.REFERENCE_CONCEPTEUR, EMPTY_STRING); + aMap.put(R01VisitorKeys.REFERENCE_TRANSPOSEE, EMPTY_STRING); + aMap.put(R01VisitorKeys.MASSE_INDICATIVE, EMPTY_STRING); + aMap.put(R01VisitorKeys.UNITE_DE_MASSE, EMPTY_STRING); + aMap.put(R01VisitorKeys.STATUT_REFERENCE_ARTICLE, statutReferenceArticle(anAbstractGenericRevision.getStatusList())); + aMap.put(R01VisitorKeys.ALTERNATIVE, EMPTY_STRING); + aMap.put(R01VisitorKeys.CLASSEMENT, "-"); + aMap.put(R01VisitorKeys.TYPE_PRODUIT, EMPTY_STRING); + aMap.put(R01VisitorKeys.SUIVI_DEVELOPPEMENT, EMPTY_STRING); + aMap.put(R01VisitorKeys.DOCUMENT_CONTROLE, EMPTY_STRING); + aMap.put(R01VisitorKeys.OBTURATION, EMPTY_STRING); + aMap.put(R01VisitorKeys.DATE_PEREMPTION, EMPTY_STRING); + aMap.put(R01VisitorKeys.MOT_CLE_EN, EMPTY_STRING); + aMap.put(R01VisitorKeys.MOT_CLE_FR, EMPTY_STRING); + aMap.put(R01VisitorKeys.CR, EMPTY_STRING); + aMap.put(R01VisitorKeys.CN, EMPTY_STRING); + } + + + /** + * Put the Super Model properties into aMap. + * + * @param aMap Map + * @param anAbstractSuperModelRevision AbstractSuperModelRevision + */ + private void putSuperModelProperties(final Map aMap, final AbstractSuperModelRevision anAbstractSuperModelRevision) { + aMap.put(R01VisitorKeys.SUIVI_UTILISATION, EMPTY_STRING); + aMap.put(R01VisitorKeys.SUIVI_DUREE_VIE, EMPTY_STRING); + aMap.put(R01VisitorKeys.REFERENCE_CONCEPTEUR, EMPTY_STRING); + aMap.put(R01VisitorKeys.REFERENCE_TRANSPOSEE, EMPTY_STRING); + aMap.put(R01VisitorKeys.MASSE_INDICATIVE, EMPTY_STRING); + aMap.put(R01VisitorKeys.UNITE_DE_MASSE, EMPTY_STRING); + aMap.put(R01VisitorKeys.TYPE_REFERENCE, french(anAbstractSuperModelRevision.getType())); + aMap.put(R01VisitorKeys.STATUT_REFERENCE_ARTICLE, statutReferenceArticle(anAbstractSuperModelRevision.getStatusList())); + aMap.put(R01VisitorKeys.ALTERNATIVE, EMPTY_STRING); + aMap.put(R01VisitorKeys.CLASSEMENT, "-"); + aMap.put(R01VisitorKeys.TYPE_PRODUIT, EMPTY_STRING); + aMap.put(R01VisitorKeys.SUIVI_DEVELOPPEMENT, EMPTY_STRING); + aMap.put(R01VisitorKeys.DOCUMENT_CONTROLE, EMPTY_STRING); + aMap.put(R01VisitorKeys.OBTURATION, EMPTY_STRING); + aMap.put(R01VisitorKeys.DESIGNATION_EN, EMPTY_STRING); + aMap.put(R01VisitorKeys.RESPONSABLE_CONCEPTION, EMPTY_STRING); + aMap.put(R01VisitorKeys.DATE_PEREMPTION, EMPTY_STRING); + aMap.put(R01VisitorKeys.MOT_CLE_EN, EMPTY_STRING); + aMap.put(R01VisitorKeys.MOT_CLE_FR, EMPTY_STRING); + aMap.put(R01VisitorKeys.CR, EMPTY_STRING); + aMap.put(R01VisitorKeys.CN, EMPTY_STRING); + + } + + + /** + * Put the Part properties into aMap. + * + * @param aMap Map + * @param anAbstractPart AbstractPart + */ + private void putPartProperties(final Map aMap, final AbstractPart anAbstractPart) { + aMap.put(R01VisitorKeys.DESIGNATION_EN, anAbstractPart.getDesignationEN()); + aMap.put(R01VisitorKeys.REFERENCE_CONCEPTEUR, anAbstractPart.getRefCompleteConcepteur()); + aMap.put(R01VisitorKeys.REFERENCE_TRANSPOSEE, anAbstractPart.getRefTransposeeSnecma()); + aMap.put(R01VisitorKeys.RESPONSABLE_CONCEPTION, anAbstractPart.getResponsableConception()); + if (!PART_MAT.equals(anAbstractPart.getType())) { + aMap.put(R01VisitorKeys.CLASSEMENT, anAbstractPart.getClassement()); + aMap.put(R01VisitorKeys.SUIVI_UTILISATION, french(anAbstractPart.getSuiviUtilisation())); + aMap.put(R01VisitorKeys.SUIVI_DUREE_VIE, french(anAbstractPart.getSuiviDureeVie())); + aMap.put(R01VisitorKeys.MASSE_INDICATIVE, DoubleFormatter.toSignificantDigits(anAbstractPart.getMass(), MASS_SIGNIFICANT_DIGITS)); + aMap.put(R01VisitorKeys.UNITE_DE_MASSE, anAbstractPart.getMassUnit()); + } + aMap.put(R01VisitorKeys.STATUT_REFERENCE_ARTICLE, statutReferenceArticle(anAbstractPart.getStatusList())); + aMap.put(R01VisitorKeys.TYPE_PRODUIT, anAbstractPart.getTypeProduit()); + aMap.put(R01VisitorKeys.DATE_PEREMPTION, anAbstractPart.getExpirationDate()); + aMap.put(R01VisitorKeys.MOT_CLE_EN, anAbstractPart.getMotClefEN()); + aMap.put(R01VisitorKeys.MOT_CLE_FR, anAbstractPart.getMotClefFR()); + aMap.put(R01VisitorKeys.CR, anAbstractPart.getCRPseudoFolderContentAsString()); + aMap.put(R01VisitorKeys.CN, anAbstractPart.getCNPseudoFolderContentAsString()); + } + + @Override + public Map visitComponent(final RFGenericRevision aRfGenericRev) { + Map theMap = getRfProperties(aRfGenericRev); + theMap.put(R01VisitorKeys.SUIVI_MONTAGE, PARAM_NON); + return theMap; + } + + @Override + public Map visitComponent(final RFPartAssembRevision aRfPartAssembRev) { + Map theMap = new EnumMap<>(R01VisitorKeys.class); + theMap.put(R01VisitorKeys.REPERE_FONCTIONNEL, aRfPartAssembRev.getName()); + theMap.put(R01VisitorKeys.REVISION_REPERE_FONCTIONNEL, aRfPartAssembRev.getRevisionId()); + theMap.put(R01VisitorKeys.IDENTIFIANT_REPERE_FONCTIONNEL, aRfPartAssembRev.getItemId()); + theMap.put(R01VisitorKeys.EQUIVALENT_SNSSIN, EMPTY_STRING); + return theMap; + } + + @Override + public Map visitComponent(final RFPartRevision aRfPartRev) { + return getRfProperties(aRfPartRev); + } + + @Override + public Map visitComponent(final RFAdminRevision aRfAdminRev) { + Map theMap = new EnumMap<>(R01VisitorKeys.class); + theMap.put(R01VisitorKeys.RESPONSABLE_REPERE, aRfAdminRev.getResponsableRepere()); + theMap.put(R01VisitorKeys.MAQUETTE, french(aRfAdminRev.getMaqIntExt())); + return theMap; + } + + @Override + public Map visitComponent(final RFAdminARevision aRfAdminARev) { + Map theMap = new EnumMap<>(R01VisitorKeys.class); + theMap.put(R01VisitorKeys.SUIVI_MONTAGE, french(aRfAdminARev.getSuiviMontage())); + theMap.put(R01VisitorKeys.RESPONSABLE_REPERE, aRfAdminARev.getResponsableRepere()); + theMap.put(R01VisitorKeys.MAQUETTE, french(aRfAdminARev.getMaqIntExt())); + theMap.put(R01VisitorKeys.TRANSFERT_LIEN_LOGISTIQUE, french(aRfAdminARev.getTransfertLienLogisti())); + theMap.put(R01VisitorKeys.TRANSFERT_LIEN_MONTAGE, french(aRfAdminARev.getTransfertLienMontage())); + return theMap; + } + + @Override + public Map visitComponent(final RFAdminAPRevision aRfAdminAPRev) { + Map theMap = new EnumMap<>(R01VisitorKeys.class); + theMap.put(R01VisitorKeys.SUIVI_MONTAGE, french(aRfAdminAPRev.getSuiviMontage())); + theMap.put(R01VisitorKeys.TRANSFERT_LIEN_LOGISTIQUE, french(aRfAdminAPRev.getTransfertLienLogisti())); + theMap.put(R01VisitorKeys.TRANSFERT_LIEN_MONTAGE, french(aRfAdminAPRev.getTransfertLienMontage())); + return theMap; + } + + @Override + public Map visitComponent(final RFAdminAGRevision aRfAdminAGRev) { + Map theMap = new EnumMap<>(R01VisitorKeys.class); + theMap.put(R01VisitorKeys.TRANSFERT_LIEN_LOGISTIQUE, french(aRfAdminAGRev.getTransfertLienLogisti())); + theMap.put(R01VisitorKeys.TRANSFERT_LIEN_MONTAGE, french(aRfAdminAGRev.getTransfertLienMontage())); + return theMap; + } + + /** + * Get the Repere Component properties to make a R01 report. + * + * @param anAbstractRF AbstractRF + * @return theMap Map + */ + private Map getRfProperties(final AbstractRF anAbstractRF) { + Map theMap = new EnumMap<>(R01VisitorKeys.class); + theMap.put(R01VisitorKeys.REPERE_FONCTIONNEL, anAbstractRF.getName()); + theMap.put(R01VisitorKeys.IDENTIFIANT_REPERE_FONCTIONNEL, anAbstractRF.getItemId()); + theMap.put(R01VisitorKeys.REVISION_REPERE_FONCTIONNEL, anAbstractRF.getRevisionId()); + theMap.put(R01VisitorKeys.EQUIVALENT_SNSSIN, anAbstractRF.getEquivalentSnsSin()); + return theMap; + } + + @Override + public Map visitComponent(final MockupRevision aMockupRev) { + // This object is not use in this report + return null; + } + + @Override + public Map visitComponent(final DescriptifRevision aDescriptifRev) { + // This object is not use in this report + return null; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/visitors/snecmaobject/R01ReceptorVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/visitors/snecmaobject/R01ReceptorVisitor.java new file mode 100644 index 0000000..1800bcd --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r01report/visitors/snecmaobject/R01ReceptorVisitor.java @@ -0,0 +1,164 @@ +package com.capgemini.reports.definition.r01report.visitors.snecmaobject; + +import com.capgemini.reports.definition.r01report.visitors.R01VisitorKeys; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAGRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericAssembRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.mockup.MockupRevision; +import com.capgemini.reports.snecmaobjects.part.*; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartAssembRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartRevision; +import com.capgemini.reports.snecmaobjects.supermodel.SuperModelRevision; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; + +import java.util.EnumMap; +import java.util.Map; + +/** + * Visit a Receptor SnecmaObject to make a R01 report. + */ +public class R01ReceptorVisitor implements IReceptorVisitor> { + private static final long serialVersionUID = -3978586236500021891L; + + @Override + public Map visitReceptor(final ProductRevision aProductRev) { + return getReceptorProperties(aProductRev); + } + + @Override + public Map visitReceptor(final GenericRevision aGenericRev) { + return getReceptorProperties(aGenericRev); + } + + @Override + public Map visitReceptor(final GenericAssembRevision aGenericAssembRev) { + return getReceptorProperties(aGenericAssembRev); + } + + @Override + public Map visitReceptor(final SuperModelRevision aSuperModelRev) { + return getReceptorProperties(aSuperModelRev); + } + + @Override + public Map visitReceptor(final AlternateRevision anAlternateRev) { + return getReceptorProperties(anAlternateRev); + } + + @Override + public Map visitReceptor(final DETRevision aDetRev) { + return getReceptorProperties(aDetRev); + } + + @Override + public Map visitReceptor(final PartAeroRevision aPartAeroRev) { + return getReceptorProperties(aPartAeroRev); + } + + @Override + public Map visitReceptor(final PartNoAeroRevision aPartNoAeroRev) { + return getReceptorProperties(aPartNoAeroRev); + } + + @Override + public Map visitReceptor(final PartAssembRevision aPartAssembRev) { + return getReceptorProperties(aPartAssembRev); + } + + @Override + public Map visitReceptor(final PartMatRevision aPartMatRev) { + return getReceptorProperties(aPartMatRev); + } + + @Override + public Map visitReceptor(final StandardRevision aStandardRev) { + return getReceptorProperties(aStandardRev); + } + + @Override + public Map visitReceptor(final RFGenericRevision aRfGenericRev) { + // No use in R01 report + return new EnumMap<>(R01VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFPartAssembRevision aRfPartAssembRev) { + // No use in R01 report + return new EnumMap<>(R01VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFPartRevision aRfPartRev) { + // No use in R01 report + return new EnumMap<>(R01VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFAdminRevision aRfAdminRev) { + // No use in R01 report + return new EnumMap<>(R01VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFAdminARevision aRfAdminARev) { + // No use in R01 report + return new EnumMap<>(R01VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFAdminAPRevision aRfAdminAPRev) { + // No use in R01 report + return new EnumMap<>(R01VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFAdminAGRevision aRfAdminAGRev) { + // No use in R01 report + return new EnumMap<>(R01VisitorKeys.class); + } + + /** + * Get the Receptor properties. + */ + private Map getReceptorProperties(final ISnecmaObject iSnecmaObject) { + Map theMap = new EnumMap<>(R01VisitorKeys.class); + theMap.put(R01VisitorKeys.IDENTIFIANT_RECEPTEUR, iSnecmaObject.getItemId()); + theMap.put(R01VisitorKeys.NOM_RECEPTEUR, iSnecmaObject.getName()); + theMap.put(R01VisitorKeys.REVISION_RECEPTEUR, iSnecmaObject.getRevisionId()); + return theMap; + } + + @Override + public Map visitReceptor(final MockupRevision aMockupRev) { + // This object is not use in this report + return null; + } + + @Override + public Map visitReceptor(final DescriptifRevision aDescriptifRev) { + // This object is not use in this report + return null; + } + + @Override + public Map emptyRf() { + Map theMap = new EnumMap<>(R01VisitorKeys.class); + theMap.put(R01VisitorKeys.REPERE_FONCTIONNEL, ""); + theMap.put(R01VisitorKeys.REVISION_REPERE_FONCTIONNEL, ""); + theMap.put(R01VisitorKeys.IDENTIFIANT_REPERE_FONCTIONNEL, ""); + theMap.put(R01VisitorKeys.MAQUETTE, ""); + theMap.put(R01VisitorKeys.TRANSFERT_LIEN_LOGISTIQUE, ""); + theMap.put(R01VisitorKeys.TRANSFERT_LIEN_MONTAGE, ""); + theMap.put(R01VisitorKeys.EQUIVALENT_SNSSIN, ""); + theMap.put(R01VisitorKeys.RESPONSABLE_REPERE, ""); + theMap.put(R01VisitorKeys.SUIVI_MONTAGE, ""); + return theMap; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/DataReportPreparatorR03.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/DataReportPreparatorR03.java new file mode 100644 index 0000000..591b230 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/DataReportPreparatorR03.java @@ -0,0 +1,96 @@ +package com.capgemini.reports.definition.r03report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObjectFactory; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRule; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindow; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindowConfiguration; +import com.capgemini.framework.teamcenter.object.runtime.TcRevisionRulesConfiguration; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderFactory; +import com.capgemini.reports.bomlineholder.processor.DefaultAltOrDetBehaviour; +import com.capgemini.reports.definition.r03report.visitors.R03Visitor; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.filter.AllIsGoodFilter; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.teamcenter.resolution.structureservice.MultiStructureServiceCaller; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Form; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * This class will allow to prepare data and findAll back data for making report R03. + */ +public class DataReportPreparatorR03 implements IDataReportPreparator { + private static final long serialVersionUID = 8862577856995249621L; + private static final Logger LOGGER = LoggerFactory.getLogger(DataReportPreparatorR03.class); + + private static final AllIsGoodFilter ACCEPT_ALL = new AllIsGoodFilter(); + + @Override + public String print(TcSession session, ExecutionR03 execution, IExecutionStrategy executionStrategy) throws KurtException { + PrintParameters printParameters = prepareData(session, execution); + executionStrategy.print(printParameters, execution); + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + } + + private PrintParameters prepareData(final TcSession session, final ExecutionR03 report) throws KurtException { + LOGGER.debug("PrepareData started on: {}", report.getReportIdentifier().getReportTitle()); + + List list = new ItemRevisionQuery(session).searchIDAndRevision(report.getPartID(), report.getPartRevisionID()).findAll(); + if (list.isEmpty()) { + throw new InvalidUserInputException(UserInputErrorEnum.OBJECT_DOES_NOT_EXIST); + } + + ItemRevision itemRevision = null; + + for(ItemRevision currentItemRev : list) { + if(SnecmaObjectTypes.isPartRevision(currentItemRev.getTypeObject().getName())){ + itemRevision = currentItemRev; + break; + } + } + + if(itemRevision == null){ + throw new InvalidUserInputException(UserInputErrorEnum.THE_SELECTED_OBJECT_IS_NOT_PERMITTED_ON_THIS_REPORT); + } + + TcRevisionRule revisionRule = session.findRevRule(report.getRevisionRule()); + TcRevisionRulesConfiguration revRulesConfiguration = new TcRevisionRulesConfiguration(revisionRule); + TcBomObject topLineObject = new TcBomObjectFactory(session, itemRevision).create(); + try (TcBomWindow bomWindow = session.createBomWindow(new TcBomWindowConfiguration(topLineObject, revRulesConfiguration))) { + session.setObjectPropPolicy(report.getFullPolicy()); + + BOMLineHolder unbuiltTopLine = new MultiStructureServiceCaller(session).resolve(bomWindow.topLine(), ACCEPT_ALL); + List itemRevMaster = unbuiltTopLine.getAllItemRevMasters(); + session.loadProperties(itemRevMaster.toArray(new ModelObject[itemRevMaster.size()])); + + BOMLineHolderFactory.buildTopBom(session, unbuiltTopLine, ACCEPT_ALL); + DefaultAltOrDetBehaviour altOrDetBehaviour = new DefaultAltOrDetBehaviour(session, new EffectivityDate().getDateTime()); + unbuiltTopLine.process(altOrDetBehaviour); + unbuiltTopLine.freeze(); + + R03Visitor visitor = new R03Visitor(); + PrintParameters printParameters = visitor.makeMasterTemplate(report, unbuiltTopLine); + visitor.constructDataMaps(session, printParameters, unbuiltTopLine); + + LOGGER.debug("PrepareData ended on: {}", report.getReportIdentifier().getReportTitle()); + return printParameters; + } catch (EmptyNomenclatureException e) { + throw new KurtException("The TC Nomenclature Resolution returned null", e); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/ExecutionR03.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/ExecutionR03.java new file mode 100644 index 0000000..139239a --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/ExecutionR03.java @@ -0,0 +1,137 @@ +package com.capgemini.reports.definition.r03report; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.builder.R03Builder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.reports.parameters.checker.ObjectTypeChecker; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +/** + * This class controls the execution of the R03 report. + */ +@Getter +@EqualsAndHashCode(callSuper = true) +public class ExecutionR03 extends AbstractExecutionReport { + private static final long serialVersionUID = -1050126556474290283L; + + // Policies parameter + private static final PolicyLocation R03_POLICY_XML_FULL = PolicyLocation.make("R03_policy_full", "/xml/policies/r03report/R03_policy_full.xml"); + private static final PolicyLocation R03_POLICY_XML_LIGHT = PolicyLocation.make("R03_policy_light", "/xml/policies/r03report/R03_policy_light.xml"); + + // Priority parameter + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R03); + + // Revision rule parameter + private static final String REPORT_REVISION_RULE = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R03", DEFAULT_REVISION_RULE); + + // Launch type parameter + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R03"); + + // Configuration + private static final String FILE_SEPARATOR = "_"; + private static final String PATTERN_DATE = "dd-MM-yyyy"; + + // Internal working data + private final String partID; + private final String partRevisionID; + + /** + * Executes the Report R03. + * + * @param partId {@link String} - the part Id + * @param partRevisionID {@link String} - the part revision Id + */ + public ExecutionR03(final String partId, final String partRevisionID) { + super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE); + this.partID = partId; + this.partRevisionID = partRevisionID; + } + + @Override + public List getLaunchData() { + List theCriteria = new ArrayList<>(); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PART_ID, partID)); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PART_REVISION, partRevisionID)); + return theCriteria; + } + + @Override + public String getTemplateLocation() { + return JasperTemplate.TEMPLATE_R03.getFilepath(); + } + + @Override + public List getQuickChecks() { + List quickChecks = new ArrayList<>(); + quickChecks.add(new ObjectTypeChecker(partID, SnecmaObjectTypes.ALTERNATE, SnecmaObjectTypes.DET, SnecmaObjectTypes.PART_AERO, + SnecmaObjectTypes.PART_ASSEMB, SnecmaObjectTypes.PART_MAT, SnecmaObjectTypes.PART_NO_AERO, + SnecmaObjectTypes.STANDARD)); + return quickChecks; + } + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R03_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R03_POLICY_XML_FULL; + } + + @Override + public List getLongChecks() { + // Empty lists - not used for this report + return new ArrayList<>(); + } + + @Override + public ReportEnum getReportIdentifier() { + return ReportEnum.REPORT_R03; + } + + @Override + public String getSpecifiedFileName() { + // Format file expected : BOMParDATE_ "RéférenceArticle"_"RévisionArticle"_"date_système".pdf + String dateSystem = TeamcenterDateFormatter.formatCalendarToPattern(Calendar.getInstance(), PATTERN_DATE); + return "R03-BOMParDATE_" + partID + FILE_SEPARATOR + partRevisionID + FILE_SEPARATOR + dateSystem; + } + + @Override + public PrintFormat getPrintingFormat() { + return PrintFormat.XLSX; + } + + @Override + public IDataReportPreparator getDataPreparator() { + return new DataReportPreparatorR03(); + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return new ExecutionR03(partID, partRevisionID); + } + + @Override + public Class getReportBuilderClass() { + return R03Builder.class; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/visitors/R03Visitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/visitors/R03Visitor.java new file mode 100644 index 0000000..83d6ff2 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/visitors/R03Visitor.java @@ -0,0 +1,99 @@ +package com.capgemini.reports.definition.r03report.visitors; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.definition.r03report.ExecutionR03; +import com.capgemini.reports.definition.r03report.visitors.bomlineholder.R03BOMLineHolderVisitor; +import com.capgemini.reports.execution.mapconstructor.AbstractStaticTemplateMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.reports.IReportVisitor; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +/** + * Visit a R03 report. + */ +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class R03Visitor extends AbstractStaticTemplateMapConstructor implements IReportVisitor { + private static final long serialVersionUID = -1999990931692459183L; + + private static final String EMPTY = ""; + + protected final R03BOMLineHolderVisitor r03BOMLineHolderVisitor; + + /** + * Constructor. + */ + public R03Visitor() { + super(); + this.r03BOMLineHolderVisitor = new R03BOMLineHolderVisitor(); + } + + private static String check(final Object anInput) { + return anInput == null ? EMPTY : anInput.toString(); + } + + private List> translate(final List> visitorMaps) { + // Add empty fields in the first line + Map firstLine = visitorMaps.get(0); + // Empty receptor + firstLine.put(R03VisitorKeys.IDENTIFIANT_RECEPTEUR, EMPTY); + firstLine.put(R03VisitorKeys.REVISION_RECEPTEUR, EMPTY); + firstLine.put(R03VisitorKeys.NOM_RECEPTEUR, EMPTY); + // Empty RF + firstLine.put(R03VisitorKeys.REPERE_FONCTIONNEL, EMPTY); + firstLine.put(R03VisitorKeys.REVISION_REPERE_FONCTIONNEL, EMPTY); + firstLine.put(R03VisitorKeys.UIN, EMPTY); + firstLine.put(R03VisitorKeys.EQUIVALENT_SNSSIN, EMPTY); + firstLine.put(R03VisitorKeys.RESPONSABLE_REPERE, EMPTY); + // Empty BOM + firstLine.put(R03VisitorKeys.SUIVI_MONTAGE, EMPTY); + firstLine.put(R03VisitorKeys.ALT, EMPTY); + firstLine.put(R03VisitorKeys.SB, EMPTY); + firstLine.put(R03VisitorKeys.QUANTITE_CUMULEE, EMPTY); + firstLine.put(R03VisitorKeys.PANACHE, EMPTY); + firstLine.put(R03VisitorKeys.QUANTITE, EMPTY); + + // Construct the map list expected by the printer + List> printerMaps = new ArrayList<>(); + for (Map visitorMap : visitorMaps) { + Map printerMap = new HashMap<>(); + for (R03VisitorKeys key : R03VisitorKeys.values()) { + printerMap.put(key.toString(), check(visitorMap.get(key))); + } + printerMaps.add(printerMap); + } + + return printerMaps; + } + + @Override + public List> visitReport(final BOMLineHolder holder) { + List> visitorMaps = r03BOMLineHolderVisitor.visitTopReceptorBom(holder); + return translate(visitorMaps); + } + + @Override + public void constructDataMaps(TcSession session, final PrintParameters printParameters, final BOMLineHolder topLine) throws KurtException { + long start = System.currentTimeMillis(); + if (topLine == null) { + + throw new NoSuchElementException("No object structure found"); + } + log.info("constructDataMaps "); + + // Parse all the snecma objects... + List> printerMaps = this.visitReport(topLine); + log.debug("printer map size " + printerMaps.size()); + printParameters.addReportData(printerMaps); + log.info("Filtering time : {} ms", System.currentTimeMillis() - start); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/visitors/R03VisitorKeys.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/visitors/R03VisitorKeys.java new file mode 100644 index 0000000..b6882f9 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/visitors/R03VisitorKeys.java @@ -0,0 +1,35 @@ +package com.capgemini.reports.definition.r03report.visitors; + +/** + * Enumeration of all the columns of the R03 report. + */ +public enum R03VisitorKeys { + IDENTIFIANT_RECEPTEUR, + REVISION_RECEPTEUR, + NOM_RECEPTEUR, + REPERE_FONCTIONNEL, + REVISION_REPERE_FONCTIONNEL, + UIN, + EQUIVALENT_SNSSIN, + RESPONSABLE_REPERE, + SUIVI_MONTAGE, + ALT, + SB, + QUANTITE_CUMULEE, + PANACHE, + QUANTITE, + REF_FABRICANT_REF_SNECMA, + REVISION_REFERENCE, + REFERENCE_CONCEPTEUR, + TYPE_REFERENCE, + NOM_REFERENCE, + DESIGNATION_EN, + REFERENCE_TRANSPOSEE, + RESPONSABLE_CONCEPTION, + ALTERNATIVE, + CLASSEMENT, + SUIVI_UTILISATION, + SUIVI_DUREE_VIE, + MASSE_INDICATIVE, + UNITE_DE_MASSE +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/visitors/bomlineholder/R03AltOrDetBehaviour.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/visitors/bomlineholder/R03AltOrDetBehaviour.java new file mode 100644 index 0000000..a44adc6 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/visitors/bomlineholder/R03AltOrDetBehaviour.java @@ -0,0 +1,57 @@ +package com.capgemini.reports.definition.r03report.visitors.bomlineholder; + +import com.capgemini.reports.bomlineholder.processor.AltOrDetBehaviour; +import com.capgemini.reports.definition.r03report.visitors.R03VisitorKeys; +import com.capgemini.reports.snecmaobjects.part.AlternateRevision; +import com.capgemini.reports.snecmaobjects.part.DETRevision; + +import java.util.Map; + +/** + * This class visits Parts that are below an {@link AlternateRevision} or a {@link DETRevision}.
+ * It puts "Oui" in the ALTERNATIVE field of a map. + */ +public class R03AltOrDetBehaviour implements AltOrDetBehaviour { + private static final long serialVersionUID = -3129556059907841821L; + + private static final String OUI = "Oui"; + private static final String EMPTY_STRING = ""; + + @Override + public boolean shouldVisitPartsInPseudoFolder() { + return true; + } + + @Override + public boolean shouldVisitPartsBelowAlt() { + return true; + } + + @Override + public void treatPartsInPseudoFolder(final Map map) { + treatAnyPartBelowThisAltOrDet(map); + } + + @Override + public void treatAlternateOrDETAsReceptor(final Map map) { + map.put(R03VisitorKeys.ALTERNATIVE, OUI); + } + + private void treatAnyPartBelowThisAltOrDet(final Map map) { + // Empty fields + map.put(R03VisitorKeys.REPERE_FONCTIONNEL, EMPTY_STRING); + map.put(R03VisitorKeys.REVISION_REPERE_FONCTIONNEL, EMPTY_STRING); + map.put(R03VisitorKeys.UIN, EMPTY_STRING); + map.put(R03VisitorKeys.EQUIVALENT_SNSSIN, EMPTY_STRING); + map.put(R03VisitorKeys.RESPONSABLE_REPERE, EMPTY_STRING); + map.put(R03VisitorKeys.SUIVI_MONTAGE, EMPTY_STRING); + map.put(R03VisitorKeys.ALT, EMPTY_STRING); + map.put(R03VisitorKeys.SB, EMPTY_STRING); + map.put(R03VisitorKeys.QUANTITE_CUMULEE, EMPTY_STRING); + map.put(R03VisitorKeys.PANACHE, EMPTY_STRING); + map.put(R03VisitorKeys.QUANTITE, EMPTY_STRING); + + // Mention that these parts are alternatives to each other + map.put(R03VisitorKeys.ALTERNATIVE, OUI); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/visitors/bomlineholder/R03BOMLineHolderVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/visitors/bomlineholder/R03BOMLineHolderVisitor.java new file mode 100644 index 0000000..7c8066c --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/visitors/bomlineholder/R03BOMLineHolderVisitor.java @@ -0,0 +1,96 @@ +package com.capgemini.reports.definition.r03report.visitors.bomlineholder; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.visitor.AbstractBOMLineHolderVisitor; +import com.capgemini.reports.definition.r03report.visitors.R03VisitorKeys; +import com.capgemini.reports.definition.r03report.visitors.snecmaobject.R03ComponentVisitor; +import com.capgemini.reports.definition.r03report.visitors.snecmaobject.R03ReceptorVisitor; +import com.capgemini.reports.releasestatus.EffectivityBehaviourHelper; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.Map; + +/** + * Visitor of an expansion of BOMLineHolder for the R03 report. + */ +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class R03BOMLineHolderVisitor extends AbstractBOMLineHolderVisitor { + private static final long serialVersionUID = -984208349993142537L; + + private static final String EMPTY_STRING = ""; + + /** + * Constructor. + */ + public R03BOMLineHolderVisitor() { + super(new R03ReceptorVisitor(), new R03ComponentVisitor(), EffectivityBehaviourHelper.visitAnyPart(), new R03AltOrDetBehaviour(), false, + false, true); + } + + @Override + protected Map visitThisReceptor(final BOMLineHolder aBomLine) { + return aBomLine.getSnecmaObject().accept(receptorVisitor); + } + + @Override + protected Map visitThisComponent(final BOMLineHolder aBomLine) { + ISnecmaObject snecmaObject = aBomLine.getSnecmaObject(); + Map aMap = snecmaObject.accept(componentVisitor); + // Put the BOMLine properties into the map + if ((snecmaObject.isGeneric()) || (snecmaObject.isPart())) { + aMap.put(R03VisitorKeys.ALT, aBomLine.getBomAlt()); + aMap.put(R03VisitorKeys.SB, aBomLine.getBomSb()); + aMap.put(R03VisitorKeys.QUANTITE_CUMULEE, aBomLine.getBomQtyCumul()); + aMap.put(R03VisitorKeys.PANACHE, aBomLine.getBomPanache()); + aMap.put(R03VisitorKeys.QUANTITE, aBomLine.getBomQty()); + aMap.put(R03VisitorKeys.UIN, aBomLine.getUin()); + } + if (aBomLine.getParentBomLine().getSnecmaObject().isPart() && snecmaObject.isPart()) { + aMap.put(R03VisitorKeys.REPERE_FONCTIONNEL, EMPTY_STRING); + aMap.put(R03VisitorKeys.REVISION_REPERE_FONCTIONNEL, EMPTY_STRING); + aMap.put(R03VisitorKeys.SUIVI_MONTAGE, EMPTY_STRING); + aMap.put(R03VisitorKeys.RESPONSABLE_REPERE, EMPTY_STRING); + aMap.put(R03VisitorKeys.EQUIVALENT_SNSSIN, EMPTY_STRING); + } + return aMap; + } + + @Override + protected void visitSpecificFirstLine(final BOMLineHolder aTopBomLine) { + Map theFirstLine = aTopBomLine.getSnecmaObject().accept(getComponentVisitor()); + theReportTable.add(theFirstLine); + } + + @Override + protected void mergeReceptorAndRepereReceptor(final Map aReceptor, final Map aRepereReceptor) { + // No used for R03 report + } + + @Override + protected void mergeComponentAndRepereComponent(final Map aComponent, final Map aRepereComponent) { + aComponent.putAll(aRepereComponent); + } + + @Override + protected void mergeRepereReceptorandAdmin(final Map aRepereReceptor, final Map anAdmin) { + // No used for R03 report + } + + @Override + protected void mergeRepereComponentandAdmin(final Map aRepereComponent, final Map anAdmin) { + aRepereComponent.putAll(anAdmin); + } + + @Override + protected void addToReport(final Map aReceptor, final Map aComponent) { + // Put the Receptor and Repere Receptor in the Component and modify the Component + // Do not modify the receptor + aComponent.putAll(aReceptor); + + // Add to the R22 report + theReportTable.add(aComponent); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/visitors/snecmaobject/R03ComponentVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/visitors/snecmaobject/R03ComponentVisitor.java new file mode 100644 index 0000000..abb8d30 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/visitors/snecmaobject/R03ComponentVisitor.java @@ -0,0 +1,217 @@ +package com.capgemini.reports.definition.r03report.visitors.snecmaobject; + +import com.capgemini.framework.common.DoubleFormatter; +import com.capgemini.framework.common.LanguageHelper; +import com.capgemini.reports.definition.r03report.visitors.R03VisitorKeys; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAGRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericAssembRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.mockup.MockupRevision; +import com.capgemini.reports.snecmaobjects.part.*; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartAssembRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartRevision; +import com.capgemini.reports.snecmaobjects.supermodel.SuperModelRevision; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; + +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; + +/** + * Visit a Component SnecmaObject to make a R03 report. + */ +public class R03ComponentVisitor implements IComponentVisitor> { + + private static final long serialVersionUID = -1358969880241440037L; + + private static final int MASS_SIGNIFICANT_DIGITS = 15; + private static final String EMPTY_STRING = ""; + private static final String PART_MAT = "PartMat"; + private static final String SEPARATOR = " / "; + private static final String VALUE_MATIERE = "matière"; + private static final String PARAM_NON = "Non"; + private static final String SOLO_SEPARATOR = "/"; + + /** + * Extracts left side of a string of the form "French text / English text".
+ * Separator slash may have *any* number (0+) of white spaces around them. + */ + private static String french(final String string) { + return LanguageHelper.french(string); + } + + @Override + public Map visitComponent(final ProductRevision aProductRev) { + // No used in R03 report + return new EnumMap<>(R03VisitorKeys.class); + } + + @Override + public Map visitComponent(final GenericRevision aGenericRev) { + // No used in R03 report + return new EnumMap<>(R03VisitorKeys.class); + } + + @Override + public Map visitComponent(SuperModelRevision aSuperModelRev) { + return null; + } + + @Override + public Map visitComponent(final GenericAssembRevision aGenericAssembRev) { + // No used in R03 report + return new EnumMap<>(R03VisitorKeys.class); + } + + @Override + public Map visitComponent(final AlternateRevision anAlternateRev) { + Map theMap = getPartProperties(anAlternateRev); + theMap.put(R03VisitorKeys.TYPE_REFERENCE, french(anAlternateRev.getTypeAlt1()) + SEPARATOR + french(anAlternateRev.getTypeAlt2())); + return theMap; + } + + @Override + public Map visitComponent(final DETRevision aDetRev) { + Map theMap = getPartProperties(aDetRev); + theMap.put(R03VisitorKeys.TYPE_REFERENCE, french(aDetRev.getTypeDet1()) + SEPARATOR + french(aDetRev.getTypeDet2())); + return theMap; + } + + @Override + public Map visitComponent(final PartAeroRevision aPartAeroRev) { + Map theMap = getPartProperties(aPartAeroRev); + theMap.put(R03VisitorKeys.TYPE_REFERENCE, french(aPartAeroRev.getTypeAero1()) + SEPARATOR + french(aPartAeroRev.getTypeAero2()) + SEPARATOR + french(aPartAeroRev.getTypeAero3())); + return theMap; + } + + @Override + public Map visitComponent(final PartNoAeroRevision aPartNoAeroRev) { + Map theMap = getPartProperties(aPartNoAeroRev); + theMap.put(R03VisitorKeys.TYPE_REFERENCE, french(aPartNoAeroRev.getTypeNoAero())); + return theMap; + } + + @Override + public Map visitComponent(final PartAssembRevision aPartAssembRev) { + Map theMap = getPartProperties(aPartAssembRev); + theMap.put(R03VisitorKeys.TYPE_REFERENCE, french(aPartAssembRev.getTypePartMontage1()) + SEPARATOR + french(aPartAssembRev.getTypePartMontage2())); + return theMap; + } + + @Override + public Map visitComponent(final PartMatRevision aPartMatRev) { + Map theMap = getPartProperties(aPartMatRev); + theMap.put(R03VisitorKeys.TYPE_REFERENCE, VALUE_MATIERE); + theMap.put(R03VisitorKeys.CLASSEMENT, aPartMatRev.getClassementMat()); + theMap.put(R03VisitorKeys.SUIVI_UTILISATION, PARAM_NON); + theMap.put(R03VisitorKeys.SUIVI_DUREE_VIE, PARAM_NON); + theMap.put(R03VisitorKeys.MASSE_INDICATIVE, EMPTY_STRING); + theMap.put(R03VisitorKeys.UNITE_DE_MASSE, EMPTY_STRING); + return theMap; + } + + @Override + public Map visitComponent(final StandardRevision aStandardRev) { + Map theMap = getPartProperties(aStandardRev); + theMap.put(R03VisitorKeys.TYPE_REFERENCE, french(aStandardRev.getTypeStandard())); + return theMap; + } + + /** + * Get Component Part properties to make a R03 report. + * + * @param anAbstractPart AbstractPart + * @return theMap Map + */ + private Map getPartProperties(final AbstractPart anAbstractPart) { + Map theMap = new EnumMap<>(R03VisitorKeys.class); + theMap.put(R03VisitorKeys.REF_FABRICANT_REF_SNECMA, anAbstractPart.getItemId()); + theMap.put(R03VisitorKeys.NOM_REFERENCE, anAbstractPart.getName()); + theMap.put(R03VisitorKeys.REVISION_REFERENCE, anAbstractPart.getRevisionId()); + theMap.put(R03VisitorKeys.ALTERNATIVE, EMPTY_STRING); + theMap.put(R03VisitorKeys.DESIGNATION_EN, anAbstractPart.getDesignationEN()); + theMap.put(R03VisitorKeys.REFERENCE_CONCEPTEUR, anAbstractPart.getRefCompleteConcepteur()); + theMap.put(R03VisitorKeys.REFERENCE_TRANSPOSEE, anAbstractPart.getRefTransposeeSnecma()); + theMap.put(R03VisitorKeys.RESPONSABLE_CONCEPTION, anAbstractPart.getResponsableConception()); + if (!PART_MAT.equals(anAbstractPart.getType())) { + theMap.put(R03VisitorKeys.CLASSEMENT, anAbstractPart.getClassement()); + theMap.put(R03VisitorKeys.SUIVI_UTILISATION, french(anAbstractPart.getSuiviUtilisation())); + theMap.put(R03VisitorKeys.SUIVI_DUREE_VIE, french(anAbstractPart.getSuiviDureeVie())); + theMap.put(R03VisitorKeys.MASSE_INDICATIVE, DoubleFormatter.toSignificantDigits(anAbstractPart.getMass(), MASS_SIGNIFICANT_DIGITS)); + theMap.put(R03VisitorKeys.UNITE_DE_MASSE, anAbstractPart.getMassUnit()); + } + return theMap; + } + + @Override + public Map visitComponent(final RFGenericRevision aRfGenericRev) { + return new EnumMap<>(R03VisitorKeys.class); + } + + @Override + public Map visitComponent(final RFPartAssembRevision aRfPartAssembRev) { + Map theMap = new EnumMap<>(R03VisitorKeys.class); + theMap.put(R03VisitorKeys.REPERE_FONCTIONNEL, aRfPartAssembRev.getName()); + theMap.put(R03VisitorKeys.REVISION_REPERE_FONCTIONNEL, aRfPartAssembRev.getRevisionId()); + theMap.put(R03VisitorKeys.EQUIVALENT_SNSSIN, EMPTY_STRING); + return theMap; + } + + @Override + public Map visitComponent(final RFPartRevision aRfPartRev) { + Map theMap = new EnumMap<>(R03VisitorKeys.class); + theMap.put(R03VisitorKeys.REPERE_FONCTIONNEL, aRfPartRev.getName()); + theMap.put(R03VisitorKeys.REVISION_REPERE_FONCTIONNEL, aRfPartRev.getRevisionId()); + theMap.put(R03VisitorKeys.EQUIVALENT_SNSSIN, aRfPartRev.getEquivalentSnsSin()); + return theMap; + } + + @Override + public Map visitComponent(final RFAdminRevision aRfAdminRev) { + Map theMap = new EnumMap<>(R03VisitorKeys.class); + theMap.put(R03VisitorKeys.RESPONSABLE_REPERE, aRfAdminRev.getResponsableRepere()); + return theMap; + } + + @Override + public Map visitComponent(final RFAdminARevision aRfAdminARev) { + Map theMap = new EnumMap<>(R03VisitorKeys.class); + String[] suiviMontage = aRfAdminARev.getSuiviMontage().split(SEPARATOR); + suiviMontage[0].split(SOLO_SEPARATOR); + theMap.put(R03VisitorKeys.SUIVI_MONTAGE, suiviMontage[0]); + theMap.put(R03VisitorKeys.RESPONSABLE_REPERE, aRfAdminARev.getResponsableRepere()); + return theMap; + } + + @Override + public Map visitComponent(final RFAdminAPRevision aRfAdminAPRev) { + Map theMap = new EnumMap<>(R03VisitorKeys.class); + String[] suiviMontage = aRfAdminAPRev.getSuiviMontage().split(SEPARATOR); + suiviMontage[0].split(SOLO_SEPARATOR); + theMap.put(R03VisitorKeys.SUIVI_MONTAGE, suiviMontage[0]); + return theMap; + } + + @Override + public Map visitComponent(final RFAdminAGRevision aRfAdminAGRev) { + return new HashMap<>(); + } + + @Override + public Map visitComponent(final MockupRevision aMockupRev) { + // This object is not use in this report + return null; + } + + @Override + public Map visitComponent(final DescriptifRevision aDescriptifRev) { + // This object is not use in this report + return null; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/visitors/snecmaobject/R03ReceptorVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/visitors/snecmaobject/R03ReceptorVisitor.java new file mode 100644 index 0000000..e92cf9b --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r03report/visitors/snecmaobject/R03ReceptorVisitor.java @@ -0,0 +1,148 @@ +package com.capgemini.reports.definition.r03report.visitors.snecmaobject; + +import com.capgemini.reports.definition.r03report.visitors.R03VisitorKeys; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAGRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericAssembRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.mockup.MockupRevision; +import com.capgemini.reports.snecmaobjects.part.*; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartAssembRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartRevision; +import com.capgemini.reports.snecmaobjects.supermodel.SuperModelRevision; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; + +import java.util.EnumMap; +import java.util.Map; + +/** + * Visit a Receptor SnecmaObject to make a R03 report. + */ +public class R03ReceptorVisitor implements IReceptorVisitor> { + + private static final long serialVersionUID = 8706801275271305065L; + + @Override + public Map visitReceptor(final ProductRevision aProductRev) { + return new EnumMap<>(R03VisitorKeys.class); + } + + @Override + public Map visitReceptor(final GenericRevision aGenericRev) { + return new EnumMap<>(R03VisitorKeys.class); + } + + @Override + public Map visitReceptor(final GenericAssembRevision aGenericAssembRev) { + return new EnumMap<>(R03VisitorKeys.class); + } + + @Override + public Map visitReceptor(SuperModelRevision aSuperModelRev) { + return null; + } + + @Override + public Map visitReceptor(final AlternateRevision anAlternateRev) { + return getReceptorProperties(anAlternateRev); + } + + @Override + public Map visitReceptor(final DETRevision aDetRev) { + return getReceptorProperties(aDetRev); + } + + @Override + public Map visitReceptor(final PartAeroRevision aPartAeroRev) { + return getReceptorProperties(aPartAeroRev); + } + + @Override + public Map visitReceptor(final PartNoAeroRevision aPartNoAeroRev) { + return getReceptorProperties(aPartNoAeroRev); + } + + @Override + public Map visitReceptor(final PartAssembRevision aPartAssembRev) { + return getReceptorProperties(aPartAssembRev); + } + + @Override + public Map visitReceptor(final PartMatRevision aPartMatRev) { + return getReceptorProperties(aPartMatRev); + } + + @Override + public Map visitReceptor(final StandardRevision aStandardRev) { + return getReceptorProperties(aStandardRev); + } + + @Override + public Map visitReceptor(final RFGenericRevision aRfGenericRev) { + return new EnumMap<>(R03VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFPartAssembRevision aRfPartAssembRev) { + return new EnumMap<>(R03VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFPartRevision aRfPartRev) { + return new EnumMap<>(R03VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFAdminRevision aRfAdminRev) { + return new EnumMap<>(R03VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFAdminARevision aRfAdminARev) { + return new EnumMap<>(R03VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFAdminAPRevision aRfAdminAPRev) { + return new EnumMap<>(R03VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFAdminAGRevision aRfAdminAGRev) { + return new EnumMap<>(R03VisitorKeys.class); + } + + /** + * Get the Receptor properties. + */ + private Map getReceptorProperties(final ISnecmaObject iSnecmaObject) { + Map theMap = new EnumMap<>(R03VisitorKeys.class); + theMap.put(R03VisitorKeys.IDENTIFIANT_RECEPTEUR, iSnecmaObject.getItemId()); + theMap.put(R03VisitorKeys.NOM_RECEPTEUR, iSnecmaObject.getName()); + theMap.put(R03VisitorKeys.REVISION_RECEPTEUR, iSnecmaObject.getRevisionId()); + return theMap; + } + + @Override + public Map visitReceptor(final MockupRevision aMockupRev) { + // This object is not use in this report + return null; + } + + @Override + public Map visitReceptor(final DescriptifRevision aDescriptifRev) { + // This object is not use in this report + return null; + } + + @Override + public Map emptyRf() { + return new EnumMap<>(R03VisitorKeys.class); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/CRExtractorHelper.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/CRExtractorHelper.java new file mode 100644 index 0000000..b3836ee --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/CRExtractorHelper.java @@ -0,0 +1,58 @@ +package com.capgemini.reports.definition.r07report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.changeobjects.change.TcChangeNoticeRevision; +import com.capgemini.reports.changeobjects.change.TcChangeRequestRevision; +import com.capgemini.reports.teamcenter.queries.saved.ChangeNoticeR07Query; +import com.capgemini.reports.teamcenter.queries.saved.ChangeRequestR07Query; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class is able to request the ChangeRequests or the ChangeNotices associated to a part or generic. + */ +public class CRExtractorHelper { + + private final TcSession session; + + /** + * Builds an instance of CR helper. + * + * @param session a teamcenter session + */ + public CRExtractorHelper(final TcSession session) { + this.session = session; + } + + /** + * Return map with changeRequest and the list of changeNotice for each changeRequest. + * + * @param itemID ID of a generic or a part. + * @param itemRevisionID Revision of a generic or a part. + * @return map. + */ + public List getCrOnPart(final String itemID, final String itemRevisionID) { + List changeRequestRevs = new ArrayList<>(); + for (ItemRevision changeRequestRev : new ChangeRequestR07Query(session).searchIDAndRevision(itemID, itemRevisionID).findAll()) { + changeRequestRevs.add(new TcChangeRequestRevision(session, changeRequestRev)); + } + return changeRequestRevs; + } + + /** + * Return list of changeNotice which is not associated to a changeRequest but directly to the part or generic. + * + * @param itemID ID of a generic or a part. + * @param itemRevisionID Revision of a generic or a part. + * @return list. + */ + public List getCnOnPart(final String itemID, final String itemRevisionID) { + List changeNoticeRevs = new ArrayList<>(); + for (ItemRevision changeNoticeRev : new ChangeNoticeR07Query(session).searchIDAndRevision(itemID, itemRevisionID).findAll()) { + changeNoticeRevs.add(new TcChangeNoticeRevision(session, changeNoticeRev)); + } + return changeNoticeRevs; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/ExecutionR07.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/ExecutionR07.java new file mode 100644 index 0000000..339e17a --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/ExecutionR07.java @@ -0,0 +1,171 @@ +package com.capgemini.reports.definition.r07report; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.builder.R07Builder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.definition.r07report.checker.R07ProductUnitChecker; +import com.capgemini.reports.definition.r07report.data.DataReportPreparatorR07; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.reports.parameters.Generics; +import com.capgemini.reports.reports.parameters.Generics.GenericType; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.reports.parameters.checker.GenericExistenceChecker; +import com.capgemini.reports.reports.parameters.checker.ProductChecker; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class controls the execution of a R07 report. + */ +@Setter(value = AccessLevel.PROTECTED) +public class ExecutionR07 extends AbstractExecutionReport { + private static final long serialVersionUID = 584625053050646351L; + + // Policies + private static final PolicyLocation R07_POLICY_XML_FULL = PolicyLocation.make("R07_policy_full", "/xml/policies/r07report/R07_policy_full.xml"); + private static final PolicyLocation R07_POLICY_XML_LIGHT = PolicyLocation.make("R07_policy_light", "/xml/policies/r07report/R07_policy_light.xml"); + // Launch type parameter + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R07"); + // Revision rule parameter + private static final String REPORT_REVISION_RULE = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R07", DEFAULT_REVISION_RULE); + // Priority parameter + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R07); + // Report parameters + @Getter + private final Generics genericParam1; + @Getter + private final Generics genericParam2; + + /** + * Constructor. Will compare nomenclature for two generics. + * + * @param genericParam1 the 1st Generic + * @param genericParam2 the 2nd Generic + */ + public ExecutionR07(final Generics genericParam1, final Generics genericParam2) { + super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE); + this.genericParam1 = genericParam1; + this.genericParam2 = genericParam2; + } + + @Override + public List getQuickChecks() { + // Sort the quick checks + ArrayList quickChecks = new ArrayList<>(); + quickChecks.add(new GenericExistenceChecker(genericParam1)); // Only 1 Generic because they are the same in the two configurations + quickChecks.add(new ProductChecker(genericParam1.getProductUnit().getProductID())); + quickChecks.add(new R07ProductUnitChecker(genericParam1.getProductUnit(), true)); + quickChecks.add(new R07ProductUnitChecker(genericParam2.getProductUnit(), false)); + return quickChecks; + } + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R07_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R07_POLICY_XML_FULL; + } + + @Override + public List getLongChecks() { + return new ArrayList<>(); + } + + @Override + public String getTemplateLocation() { + return "No Template needed for this report! it is automatically generated"; + } + + @Override + public ReportEnum getReportIdentifier() { + return ReportEnum.REPORT_R07; + } + + @Override + public String getSpecifiedFileName() { + return StringHelper.implode("_", "R07", getNameSheet()); + } + + /** + * Returns the spreadsheet's name. + * + * @return the name + */ + String getNameSheet() { + ProductUnit productUnit1 = genericParam1.getProductUnit(); + String productId = productUnit1.getProductID(); + String unit1 = productUnit1.getUnitStr(); + String unit2 = genericParam2.getProductUnit().getUnitStr(); + String name; + switch (genericParam1.getType()) { + case GENERIC: + name = StringHelper.implode("_", genericParam1.getGeneric(), productId, unit1, unit2); + break; + case GENERIC_ASSEMB: + name = StringHelper.implode("_", genericParam1.getGenericAssemb(), productId, unit1, unit2); + break; + case ONLY_PRODUCT: + name = StringHelper.implode("_", productId, unit1, unit2); + break; + default: + name = "R07_UnsupportedGenericType_" + genericParam1.toString() + "_" + genericParam2.toString(); + break; + } + return name; + } + + @Override + public PrintFormat getPrintingFormat() { + return PrintFormat.XLSX; + } + + @Override + public List getLaunchData() { + List theCriteria = new ArrayList<>(); + // The Product is the same for the 2 configurations + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PRODUCT, genericParam1.getProductUnit().getProductID())); + + // Configuration 1 + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.UNIT_CONFIGURATION_1, genericParam1.getProductUnit().getUnitStr())); + if (GenericType.GENERIC.equals(genericParam1.getType())) { + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC, genericParam1.getGeneric())); + } else if (GenericType.GENERIC_ASSEMB.equals(genericParam1.getType())) { + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC_ASSEMB, genericParam1.getGenericAssemb())); + } + + // Configuration 2 + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.UNIT_CONFIGURATION_2, genericParam2.getProductUnit().getUnitStr())); + return theCriteria; + } + + @Override + public IDataReportPreparator getDataPreparator() { + return new DataReportPreparatorR07(); + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return new ExecutionR07(genericParam1, genericParam2); + } + + @Override + public Class getReportBuilderClass() { + return R07Builder.class; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/R07Printer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/R07Printer.java new file mode 100644 index 0000000..fd314e8 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/R07Printer.java @@ -0,0 +1,327 @@ +package com.capgemini.reports.definition.r07report; + +import com.capgemini.framework.common.LanguageHelper; +import com.capgemini.framework.common.ReportFolderOutputHelper; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.bomlineholder.flattener.line.SnecmaLine; +import com.capgemini.reports.changeobjects.change.TcChangeNoticeRevision; +import com.capgemini.reports.changeobjects.change.TcChangeRequestRevision; +import com.capgemini.reports.definition.r07report.data.DataReportPreparatorR07.ReportDataLineR07; +import com.capgemini.reports.definition.r07report.printing.*; +import com.capgemini.reports.exceptions.FileLoadingException; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.ReportPrintException; +import com.capgemini.reports.execution.mapconstructor.IMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.printing.PrintReportHelper; +import com.capgemini.reports.reports.parameters.Generics; +import com.google.common.collect.SetMultimap; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.Map.Entry; + +/** + * Prints a R07 report using data carried in the {@link ExecutionR07}. + */ +@Getter +@Setter(value = AccessLevel.PROTECTED) +public class R07Printer implements IMapConstructor { + + private static final String EMPTY_STRING = ""; + private static final long serialVersionUID = 8191686574681618653L; + private int nbMaxChangeNotice; + private String conf1Name; + private String conf2Name; + + private static String getConfName(final Generics genericParam) throws ReportPrintException { + switch (genericParam.getType()) { + case GENERIC: + return StringHelper.implode(" - ", genericParam.getProductUnit().getProductID(), genericParam.getGeneric(), genericParam.getProductUnit().getUnitStr(), today()); + case GENERIC_ASSEMB: + return StringHelper.implode(" - ", genericParam.getProductUnit().getProductID(), genericParam.getGenericAssemb(), genericParam.getProductUnit().getUnitStr(), today()); + case ONLY_PRODUCT: + return StringHelper.implode(" - ", genericParam.getProductUnit().getProductID(), genericParam.getProductUnit().getUnitStr(), today()); + default: + throw new ReportPrintException("Unsupported Configuration type: " + genericParam.toString()); + } + } + + private static String makeTitleContent(final int confNum, final Generics generics, final int nbConfLine) throws ReportPrintException { + return "Nombre de triplets ou couples dans la configuration " + confNum + " ( " + getConfName(generics) + ") : " + nbConfLine; + } + + private static String today() { + Date dateActual = new Date(); + DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy"); + return dateFormat.format(dateActual); + } + + @Override + public PrintParameters makeMasterTemplate(final ExecutionR07 report, final ReportDataR07 data) throws ReportPrintException, FileLoadingException, + InvalidInputException { + conf1Name = getConfName(report.getGenericParam1()); + conf2Name = getConfName(report.getGenericParam2()); + nbMaxChangeNotice = data.getMaxCN(); + BuilderTemplateR07 templateBuilder = new BuilderTemplateR07(collectParamDifference(), nbMaxChangeNotice, conf1Name, conf2Name, report.getNameSheet()); + String template = templateBuilder.createDynamicTemplate(); + String storageFolder = ReportFolderOutputHelper.getStorageFolderLocation(report.getLaunchType()); + String fileName = report.getFileNameOnDisc(); + return PrintReportHelper.setupPrintParameters(template, storageFolder, fileName, report); + } + + @Override + public void constructDataMaps(final TcSession session, final PrintParameters printParameters, final ReportDataR07 reportData) throws KurtException { + // On recupere toutes les donnees dans la map et apres on etudie chaque map de la liste pour voir les CR et CN + List> lstMapData = new ArrayList<>(); + for (ReportDataLineR07 elem : reportData.getReportDataList()) { + SnecmaLine line = elem.getLine(); + Map structureMap = makeMap(line); // Map representing the structural elements (receptor/repere/component) + SetMultimap bundles = elem.getBundles(); + + // If no CR nor CN were found, add a line anyway + if (bundles.isEmpty()) { + fillerMapDataEffectivity(structureMap, elem.isConf1()); + fillerMapDataDifference(structureMap, elem.isExclusive(), elem.getHasMod()); + fillEmptyCrColumns(structureMap); // Fill unused CR column with blanks + fillEmptyCnColumns(structureMap, 0); // Fill all CN columns with blanks + lstMapData.add(structureMap); + continue; + } + + Set orphans = bundles.removeAll(ReportDataLineR07.FAKE); // Get orphans apart + + /* + * 4 configurations for change objects acting on this component: + * 1) a CR mentions the component, but has zero CNs ------> (put a single line, no CNs on it) + * 2) a CR mentions the component, has some children CNs -> (put a single line, all CNs that also mention the component on the line) + * 3) a CN mentions the component, has a parent CR -------> (DO NOTHING this is handled in 2) because CR<->CN link is reflexive) + * 4) a CN mentions the component, has no parent CR ------> (gather all those CNs -> single line) + */ + + // Put the CR lines with REAL CRs first + for (Entry> entry : bundles.asMap().entrySet()) { + TcChangeRequestRevision changeRequestRevision = entry.getKey(); + // Copy the cnList as we need to remove any eventual null value, but we don't want to update the underlying multimap! + Collection childrenCN = new ArrayList<>(entry.getValue()); + childrenCN.remove(null); + Map mapTemporary = new HashMap<>(structureMap); // Structural map is copied to keep the content the same throughout all the lines + addChangeRequestAndChangeNotice(mapTemporary, changeRequestRevision, childrenCN); + fillerMapDataEffectivity(mapTemporary, elem.isConf1()); + fillerMapDataDifference(mapTemporary, elem.isExclusive(), elem.getHasMod()); + // Now fill with blanks any unused CN columns + fillEmptyCnColumns(mapTemporary, childrenCN.size()); + // finally add the map + lstMapData.add(mapTemporary); + } + + // Finally print the CNs that have no CR parent all in the same line + if (!orphans.isEmpty()) { // SetMultimap.findAll never returns null, but at least an empty map + Map mapTemporary = addChangeNoticeWithoutCR(orphans, structureMap); + fillerMapDataEffectivity(mapTemporary, elem.isConf1()); + fillerMapDataDifference(mapTemporary, elem.isExclusive(), elem.getHasMod()); + lstMapData.add(mapTemporary); + } + } + + // FIX CONFIGURATION WITH NUMBER OF RELATION (recepteur-repere-composant) + Map parameters = new EnumMap<>(EnumChangeR07.class); + parameters.put(EnumChangeR07.TITLE_FIRST_CONFIGURATION, makeTitleContent(1, reportData.getGenericParam1(), reportData.getNumberOfLinesInConf1())); + parameters.put(EnumChangeR07.TITLE_SECOND_CONFIGURATION, makeTitleContent(2, reportData.getGenericParam2(), reportData.getNumberOfLinesInConf2())); + printParameters.addReportParameters(parameters); + if (lstMapData.isEmpty()) { + lstMapData.add(createEmptyMap()); + } + printParameters.addReportData(lstMapData); + } + + private Map createEmptyMap() { + Map mapEmpty = new HashMap<>(); + mapEmpty.put(EnumRecepteurR07.EFFECTIVITE.toString(), EMPTY_STRING); + mapEmpty.put(EnumRecepteurR07.ID_RECEPTEUR.toString(), EMPTY_STRING); + mapEmpty.put(EnumRecepteurR07.REVISION_RECEPTEUR.toString(), EMPTY_STRING); + mapEmpty.put(EnumRecepteurR07.NOM_RECEPTEUR.toString(), EMPTY_STRING); + mapEmpty.put(EnumRepereR07.REPERE_FONCTIONNEL.toString(), EMPTY_STRING); + mapEmpty.put(EnumRepereR07.REVISION_REPERE_FONCTIONNEL.toString(), EMPTY_STRING); + mapEmpty.put(EnumRepereR07.RESPONSABLE_REPERE.toString(), EMPTY_STRING); + mapEmpty.put(EnumRepereR07.SUIVI_MONTAGE.toString(), EMPTY_STRING); + mapEmpty.put(EnumComposantR07.REF_FABRICANT.toString(), EMPTY_STRING); + mapEmpty.put(EnumComposantR07.REVISION_REFERENCE.toString(), EMPTY_STRING); + mapEmpty.put(EnumComposantR07.TYPE_REFERENCE.toString(), EMPTY_STRING); + mapEmpty.put(EnumComposantR07.NOM_REFERENCE.toString(), EMPTY_STRING); + mapEmpty.put(EnumComposantR07.REFERENCE_CONCEPTEUR.toString(), EMPTY_STRING); + mapEmpty.put(EnumComposantR07.REFERENCE_TRANSPOSEE.toString(), EMPTY_STRING); + mapEmpty.put(EnumComposantR07.REFERENCE_ASSOCIEE.toString(), EMPTY_STRING); + mapEmpty.put(EnumComposantR07.RESPONSABLLE_CONCEPTION.toString(), EMPTY_STRING); + mapEmpty.put(EnumComposantR07.ARTICLE_GESTION.toString(), EMPTY_STRING); + mapEmpty.put(EnumComposantR07.CLASSEMENT.toString(), EMPTY_STRING); + mapEmpty.put(EnumComposantR07.SUIVI_UTILISATION.toString(), EMPTY_STRING); + mapEmpty.put(EnumComposantR07.SUIVI_DUREE_VIE.toString(), EMPTY_STRING); + mapEmpty.put(EnumComposantR07.LISTE_FOURNISSEUR.toString(), EMPTY_STRING); + mapEmpty.put(EnumLienNomenclatureR07.ALT.toString(), EMPTY_STRING); + mapEmpty.put(EnumLienNomenclatureR07.SUIVANT_BESOIN.toString(), EMPTY_STRING); + mapEmpty.put(EnumLienNomenclatureR07.QUANTITE_CUMULEE.toString(), EMPTY_STRING); + mapEmpty.put(EnumLienNomenclatureR07.PANACHAGE.toString(), EMPTY_STRING); + mapEmpty.put(EnumLienNomenclatureR07.QUANTITE.toString(), EMPTY_STRING); + mapEmpty.put(EnumChangeR07.ID_CR.toString(), EMPTY_STRING); + mapEmpty.put(EnumChangeR07.REVISION_CR.toString(), EMPTY_STRING); + mapEmpty.put(EnumChangeR07.TYPE_CR.toString(), EMPTY_STRING); + mapEmpty.put(EnumChangeR07.NOM_CR.toString(), EMPTY_STRING); + return mapEmpty; + } + + private void fillEmptyCrColumns(final Map mapTemporary) { + mapTemporary.put(EnumChangeR07.ID_CR.toString(), EMPTY_STRING); + mapTemporary.put(EnumChangeR07.REVISION_CR.toString(), EMPTY_STRING); + mapTemporary.put(EnumChangeR07.TYPE_CR.toString(), EMPTY_STRING); + mapTemporary.put(EnumChangeR07.NOM_CR.toString(), EMPTY_STRING); + } + + /** + * Fills the remaining CN columns with empty cells.
+ * If there are [0..cnMax[ columns, but on this line there are 'n' CNs (n<cnMax) then provide colNum=n=cnList.size().
+ * As a result, all [n..cnMax[ columns will be filled with empty cells + * + * @param mapTemporary the map to fill + * @param colStart the last non-empty CN column + */ + private void fillEmptyCnColumns(final Map mapTemporary, final int colStart) { + for (int colNum = colStart + 1; colNum <= nbMaxChangeNotice; colNum++) { + // For some reason, the printer expects [1..n] instead of [0..n[ + // So here since all [1..n] columns contain some real CNs, we need to fill all ]n..cnMax] columns with blanks ! + mapTemporary.put(EnumChangeR07.ID_CN.toString() + "_" + colNum, EMPTY_STRING); + mapTemporary.put(EnumChangeR07.REVISION_CN.toString() + "_" + colNum, EMPTY_STRING); + mapTemporary.put(EnumChangeR07.TYPE_CN.toString() + "_" + colNum, EMPTY_STRING); + mapTemporary.put(EnumChangeR07.NOM_CN.toString() + "_" + colNum, EMPTY_STRING); + } + } + + private Map makeMap(final SnecmaLine line) { + Map map = new HashMap<>(); + mapReceptor(map, line); + mapRepere(map, line); + mapComponent(map, line); + return map; + } + + private void mapReceptor(final Map map, final SnecmaLine line) { + map.put(EnumRecepteurR07.ID_RECEPTEUR.toString(), line.getIDReceptor()); + map.put(EnumRecepteurR07.REVISION_RECEPTEUR.toString(), line.getRevisionReceptor()); + map.put(EnumRecepteurR07.NOM_RECEPTEUR.toString(), line.getNameReceptor()); + } + + private void mapRepere(final Map map, final SnecmaLine line) { + map.put(EnumRepereR07.REPERE_FONCTIONNEL.toString(), line.getRepereName()); + map.put(EnumRepereR07.REVISION_REPERE_FONCTIONNEL.toString(), line.getRepereRevision()); + map.put(EnumRepereR07.RESPONSABLE_REPERE.toString(), line.getResponsableRepere()); + map.put(EnumRepereR07.SUIVI_MONTAGE.toString(), LanguageHelper.french(line.getSuiviMontage())); // French + } + + private void mapComponent(final Map map, final SnecmaLine line) { + map.put(EnumComposantR07.REF_FABRICANT.toString(), line.getIDComponent()); + map.put(EnumComposantR07.REVISION_REFERENCE.toString(), line.getIDRevisionComponent()); + map.put(EnumComposantR07.TYPE_REFERENCE.toString(), line.getTypeReference()); // French + map.put(EnumComposantR07.NOM_REFERENCE.toString(), line.getNameReference()); + map.put(EnumComposantR07.REFERENCE_CONCEPTEUR.toString(), line.getReferenceConceptor()); + map.put(EnumComposantR07.REFERENCE_TRANSPOSEE.toString(), line.getReferenceTransposed()); + map.put(EnumComposantR07.REFERENCE_ASSOCIEE.toString(), line.getReferenceAssociated()); + map.put(EnumComposantR07.RESPONSABLLE_CONCEPTION.toString(), line.getResponsableConception()); + map.put(EnumComposantR07.ARTICLE_GESTION.toString(), line.getArticleGestion()); + map.put(EnumComposantR07.CLASSEMENT.toString(), line.getClassement()); + map.put(EnumComposantR07.SUIVI_UTILISATION.toString(), LanguageHelper.french(line.getSuiviUtilisation())); // French + map.put(EnumComposantR07.SUIVI_DUREE_VIE.toString(), LanguageHelper.french(line.getSuiviDureeVie())); // French + map.put(EnumComposantR07.LISTE_FOURNISSEUR.toString(), StringHelper.implode(", ", line.getSuppliersList())); + map.put(EnumLienNomenclatureR07.ALT.toString(), line.getALT()); + map.put(EnumLienNomenclatureR07.SUIVANT_BESOIN.toString(), line.getSB()); + map.put(EnumLienNomenclatureR07.QUANTITE_CUMULEE.toString(), line.getQuantiteCumulee()); + map.put(EnumLienNomenclatureR07.PANACHAGE.toString(), LanguageHelper.french(line.getPanachage())); + map.put(EnumLienNomenclatureR07.QUANTITE.toString(), line.getQuantite()); + } + + private Map addChangeNoticeWithoutCR(final Collection changeNoticeList, + final Map structureMap) { + Map mapTemporary = new HashMap<>(structureMap); // Structural map is copied to keep the content the same throughout all the lines + int changeNum = 0; + for (TcChangeNoticeRevision changeNoticeRevision : changeNoticeList) { + addChangeNoticeAtPosition(mapTemporary, changeNoticeRevision, changeNum++); + } + fillEmptyCrColumns(mapTemporary); // Fill unused CR column with blanks + fillEmptyCnColumns(mapTemporary, changeNoticeList.size()); // Fill all remaining CN columns with blanks + return mapTemporary; + } + + private void addChangeRequestAndChangeNotice(final Map map, final TcChangeRequestRevision changeRequesteRevision, + final Collection cnList) { + map.put(EnumChangeR07.ID_CR.toString(), changeRequesteRevision.getItemId()); + map.put(EnumChangeR07.REVISION_CR.toString(), changeRequesteRevision.getRevisionId()); + map.put(EnumChangeR07.TYPE_CR.toString(), LanguageHelper.french(changeRequesteRevision.getTypeModSupportProcess())); + map.put(EnumChangeR07.NOM_CR.toString(), changeRequesteRevision.getChangeName()); + int posCn = 0; + for (TcChangeNoticeRevision changeNoticeRevision : cnList) { + addChangeNoticeAtPosition(map, changeNoticeRevision, posCn++); + } + } + + /** + * Add a CN to the CN columns.
+ * If there are [0..cnMax[ columns, puts the CN in the nth column (n + */ + private void addChangeNoticeAtPosition(final Map mapTemporary, final TcChangeNoticeRevision changeNoticeRevision, + final int changeNum) { + int realPos = changeNum + 1; // For some reason, the printer expects [1..n] instead of [0..n[ + mapTemporary.put(EnumChangeR07.ID_CN.toString() + "_" + realPos, changeNoticeRevision.getItemId()); + mapTemporary.put(EnumChangeR07.REVISION_CN.toString() + "_" + realPos, changeNoticeRevision.getRevisionId()); + mapTemporary.put(EnumChangeR07.TYPE_CN.toString() + "_" + realPos, LanguageHelper.french(changeNoticeRevision.getTypeModification())); + mapTemporary.put(EnumChangeR07.NOM_CN.toString() + "_" + realPos, changeNoticeRevision.getChangeName()); + } + + private void fillerMapDataEffectivity(final Map mapTemporary, final boolean isConf1) { + mapTemporary.put(EnumRecepteurR07.EFFECTIVITE.toString(), isConf1 ? conf1Name : conf2Name); + mapTemporary.put(EnumChangeR07.CONFIGURATION_CONCERNED.toString(), isConf1); + } + + private void fillerMapDataDifference(final Map mapTemporary, final boolean isExclusif, final Map mapMod) { + if (isExclusif) { + mapTemporary.put(EnumMapDelta.ALL_LINE_DIFFERENCE.toString(), true); + } else { + for (Entry elem : mapMod.entrySet()) { + mapTemporary.put(elem.getKey().toString(), elem.getValue()); + } + mapTemporary.put(EnumMapDelta.ALL_LINE_DIFFERENCE.toString(), false); + } + } + + private List collectParamDifference() { + List lstParamDiff = new ArrayList<>(); + lstParamDiff.add(EnumMapDelta.ID_RECEPTEUR_ECART.toString()); + lstParamDiff.add(EnumMapDelta.NOM_RECEPTEUR_ECART.toString()); + lstParamDiff.add(EnumMapDelta.REPERE_FONCTIONNEL_ECART.toString()); + lstParamDiff.add(EnumMapDelta.RESPONSABLE_REPERE_ECART.toString()); + lstParamDiff.add(EnumMapDelta.SUIVI_MONTAGE_ECART.toString()); + lstParamDiff.add(EnumMapDelta.REF_FABRICANT_ECART.toString()); + lstParamDiff.add(EnumMapDelta.TYPE_REFERENCE_ECART.toString()); + lstParamDiff.add(EnumMapDelta.NOM_REFERENCE_ECART.toString()); + lstParamDiff.add(EnumMapDelta.REFERENCE_CONCEPTEUR_ECART.toString()); + lstParamDiff.add(EnumMapDelta.REFERENCE_TRANSPOSEE_ECART.toString()); + lstParamDiff.add(EnumMapDelta.REFERENCE_ASSOCIEE_ECART.toString()); + lstParamDiff.add(EnumMapDelta.RESPONSABLE_CONCEPTION_ECART.toString()); + lstParamDiff.add(EnumMapDelta.ARTICLE_GESTION_ECART.toString()); + lstParamDiff.add(EnumMapDelta.CLASSEMENT_ECART.toString()); + lstParamDiff.add(EnumMapDelta.SUIVI_UTILISATION_ECART.toString()); + lstParamDiff.add(EnumMapDelta.SUIVI_DUREE_VIE_ECART.toString()); + lstParamDiff.add(EnumMapDelta.LISTE_FOURNISSEUR_ECART.toString()); + lstParamDiff.add(EnumMapDelta.ALT_ECART.toString()); + lstParamDiff.add(EnumMapDelta.SUIVI_BESOIN_ECART.toString()); + lstParamDiff.add(EnumMapDelta.QUANTITE_CUMULEE_ECART.toString()); + lstParamDiff.add(EnumMapDelta.PANACHAGE_ECART.toString()); + lstParamDiff.add(EnumMapDelta.QUANTITE_ECART.toString()); + lstParamDiff.add(EnumMapDelta.ALL_LINE_DIFFERENCE.toString()); + return lstParamDiff; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/ReportDataR07.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/ReportDataR07.java new file mode 100644 index 0000000..37e9078 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/ReportDataR07.java @@ -0,0 +1,22 @@ +package com.capgemini.reports.definition.r07report; + +import com.capgemini.reports.definition.r07report.data.DataReportPreparatorR07.ReportDataLineR07; +import com.capgemini.reports.reports.parameters.Generics; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.List; + +/** + * Regroups all the data that is necessary to produce a line in the final report: the written date, the configuration it belongs to, which cells to highlight. + */ +@Getter +@AllArgsConstructor +public class ReportDataR07 { + private final Generics genericParam1; + private final Generics genericParam2; + private final int numberOfLinesInConf1; + private final int numberOfLinesInConf2; + private final int maxCN; + private final List reportDataList; +} \ No newline at end of file diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/checker/R07ProductUnitChecker.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/checker/R07ProductUnitChecker.java new file mode 100644 index 0000000..e8f0898 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/checker/R07ProductUnitChecker.java @@ -0,0 +1,41 @@ +package com.capgemini.reports.definition.r07report.checker; + +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.reports.parameters.checker.ProductUnitChecker; + +/** + * This class checks if a a given Product-Unit is valid for a R07 report. + */ +public class R07ProductUnitChecker extends ProductUnitChecker { + + private final R07Configuration conf; + + /** + * Constructor. + * + * @param productUnit {@link ProductUnit} - the product unit + * @param isConf1 boolean - Is true if it is the configuration 1. Else false. + */ + public R07ProductUnitChecker(final ProductUnit productUnit, final boolean isConf1) { + super(productUnit); + this.conf = isConf1 ? R07Configuration.CONF_1 : R07Configuration.CONF_2; + } + + @Override + protected UserInputErrorEnum getErrorMessage() { + switch (conf) { + case CONF_1: + return UserInputErrorEnum.THE_UNIT_1_IS_NOT_ASSOCIATED_TO_THE_PRODUCT_1; + case CONF_2: + return UserInputErrorEnum.THE_UNIT_2_IS_NOT_ASSOCIATED_TO_THE_PRODUCT_2; + default: + return UserInputErrorEnum.PRODUCT_AND_UNIT_DOES_NOT_EXIST; + } + } + + private enum R07Configuration { + CONF_1, + CONF_2 + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/DataReportPreparatorR07.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/DataReportPreparatorR07.java new file mode 100644 index 0000000..50ed4dd --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/DataReportPreparatorR07.java @@ -0,0 +1,177 @@ +package com.capgemini.reports.definition.r07report.data; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.bomlineholder.flattener.line.SnecmaLine; +import com.capgemini.reports.changeobjects.change.TcChangeNoticeRevision; +import com.capgemini.reports.changeobjects.change.TcChangeRequestRevision; +import com.capgemini.reports.definition.r07report.CRExtractorHelper; +import com.capgemini.reports.definition.r07report.ExecutionR07; +import com.capgemini.reports.definition.r07report.R07Printer; +import com.capgemini.reports.definition.r07report.ReportDataR07; +import com.capgemini.reports.definition.r07report.data.extractor.BomFlattenerR07; +import com.capgemini.reports.definition.r07report.data.extractor.DataExtractorR07; +import com.capgemini.reports.definition.r07report.data.filter.ConfigurationFilterR07; +import com.capgemini.reports.definition.r07report.data.sorter.R07DataSorter; +import com.capgemini.reports.definition.r07report.data.sorter.R07DataSorter.ConfLine; +import com.capgemini.reports.definition.r07report.printing.EnumMapDelta; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.printing.PrintParameters; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.SetMultimap; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * This class will allow to prepare data and findAll back data for making report R07. + */ +public class DataReportPreparatorR07 implements IDataReportPreparator { + private static final long serialVersionUID = 6255355550254874091L; + private static final Logger LOGGER = LoggerFactory.getLogger(DataReportPreparatorR07.class); + + @Override + public String print(TcSession session, ExecutionR07 execution, IExecutionStrategy executionStrategy) throws KurtException { + PrintParameters printParameters = prepareData(session, execution); + executionStrategy.print(printParameters, execution); + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + } + + private PrintParameters prepareData(final TcSession session, final ExecutionR07 report) throws KurtException { + LOGGER.debug("PrepareData started on: {}", report.getReportIdentifier().getReportTitle()); + + // Extract the Tc data + DataExtractorR07 extractor = new DataExtractorR07(session, report); + extractor.extractData(); + + // Flatten the bomLines to extract all links in a List + BomFlattenerR07 flatConf = new BomFlattenerR07(); + flatConf.visitTopReceptorBom(session, extractor.getTopBomConf1(), extractor.getTopBomConf2()); + + // Define number of triplet for each configuration + int sizeTripletConf1 = flatConf.getConfig1().size(); + int sizeTripletConf2 = flatConf.getConfig2().size(); + + // Filter the data to remove objects that are identical in both configuration. Also isolates exclusive items in each onf. + ConfigurationFilterR07 filter = new ConfigurationFilterR07(); + filter.filter(flatConf); + + // Sort the data according to the original bomLine browsing order + R07DataSorter dataSorter = new R07DataSorter(); + Collection reportLines = dataSorter.sort(filter); + + // Obtain the Change Requests and Change Notices + List dataList = extractCrCn(session, reportLines); + + // Count the maximum number of CNs + int maxCN = countMaxCN(dataList); + ReportDataR07 dataR07 = new ReportDataR07(report.getGenericParam1(), report.getGenericParam2(), sizeTripletConf1, sizeTripletConf2, maxCN, dataList); + R07Printer printer = new R07Printer(); + PrintParameters printParameters = printer.makeMasterTemplate(report, dataR07); + printer.constructDataMaps(session, printParameters, dataR07); + + LOGGER.debug("PrepareData ended on: {}", report.getReportIdentifier().getReportTitle()); + return printParameters; + } + + int countMaxCN(final List dataList) { + int maxCN = 1; // Minimum 1 column + for (ReportDataLineR07 line : dataList) { + // There can be CNs bundled behind a CR. Amongst these lines, the FAKE CR points to the CNs that have no father, so the line length is correct + for (Collection cnInThisLine : line.getBundles().asMap().values()) { + maxCN = Math.max(maxCN, cnInThisLine.size()); + } + } + return maxCN; + } + + List extractCrCn(final TcSession session, final Collection reportLines) { + // Extract CRs and CNs + CRExtractorHelper crExtractor = new CRExtractorHelper(session); + List reportDataList = new ArrayList<>(); + for (ConfLine line : reportLines) { + // Obtain all related CRs and CNs + SnecmaLine snecmaLine = line.getLine(); + String componentId = snecmaLine.getIDComponent(); + String componentRevision = snecmaLine.getIDRevisionComponent(); + List crList = crExtractor.getCrOnPart(componentId, componentRevision); + List cnList = crExtractor.getCnOnPart(componentId, componentRevision); + + // Build map: CR -> CN + SetMultimap bundles = makeBundles(crList, cnList); + reportDataList.add(new ReportDataLineR07(snecmaLine, bundles, line.isConf1(), line.isExclusive(), line.getHasMod())); + } + return reportDataList; + } + + /** + * Remove and group in bundles the CNs that have a common ancestor CR, and leave only the CNs that have no ancestor in the input list. + * + * @param lstCN a {@link List} of {@link TcChangeNoticeRevision}s. Those CNs all mention the part. This list will be altered, only the CNs without a CR 'father' will be left. + * @return a {@link Map} grouping a {@link List} of {@link TcChangeNoticeRevision} sharing a common {@link TcChangeRequestRevision} 'father'. + */ + private SetMultimap makeBundles(final List lstCR, + final List lstCN) { + SetMultimap bundles = HashMultimap.create(); + // Put all the CR first. Link them to their Children CNs IF those children are in the CNlist (they mention the Part in their pseudo-folder 'after') + for (TcChangeRequestRevision changeRequestRevision : lstCR) { + for (TcChangeNoticeRevision child : changeRequestRevision.getChangeNoticesList()) { + if (lstCN.contains(child)) { + bundles.put(changeRequestRevision, child); + } + } + if (!bundles.containsKey(changeRequestRevision)) { + bundles.put(changeRequestRevision, null); + } + } + // Then put all CNs in the map. If they have one or more father CRs, add the CN to the CR's children list. Otherwise, put them in FAKE's list + for (TcChangeNoticeRevision changeNoticeRevision : lstCN) { + if (changeNoticeRevision.getImplementsCR() != null && !changeNoticeRevision.getImplementsCR().isEmpty()) { + for (TcChangeRequestRevision father : changeNoticeRevision.getImplementsCR()) { + bundles.put(father, changeNoticeRevision); + bundles.remove(father, null); // Try to remove a null from the father's sons. May have happened if the father had no known CN. It now has at least one. + } + } else { + bundles.put(ReportDataLineR07.FAKE, changeNoticeRevision); + } + } + return bundles; + } + + /** + * Regroups all the data that is necessary to produce a line in the final report: the written date, the configuration it belongs to, which cells to highlight. + */ + @Getter + @AllArgsConstructor + public static class ReportDataLineR07 { + + /** + * This is a placeholder. + */ + public static final TcChangeRequestRevision FAKE = new TcChangeRequestRevision(null, null) { + private static final long serialVersionUID = -3143088096659343939L; + + }; + + private final SnecmaLine line; + /** + * These CRs keys do not mention the component. However, the CNs in the value List do, and the CR is their 'father'. + */ + private final SetMultimap bundles; + private final boolean conf1; + private final boolean exclusive; + Map hasMod; + + @Override + public String toString() { + return "Data: " + (exclusive ? "E" : "") + (conf1 ? "1" : "2") + line.toString() + " with " + bundles.size() + " CR(s)"; + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/TransformerR07.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/TransformerR07.java new file mode 100644 index 0000000..6fdad30 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/TransformerR07.java @@ -0,0 +1,51 @@ +package com.capgemini.reports.definition.r07report.data; + +import com.capgemini.reports.definition.r07report.data.extractor.lines.*; + +/** + * Interface for generating an index with a different algorithm for each line type. + */ +public interface TransformerR07 { + + /** + * Creates an identifier for a {@link R07Quad}. + * + * @param line the line from which to create the Identifier + * @return the {@link String} identifier + */ + String makeIdentifier(final R07Quad line); + + /** + * Creates an identifier for a {@link R07PartRfPart}. + * + * @param line the line from which to create the Identifier + * @return the {@link String} identifier + */ + String makeIdentifier(final R07PartRfPart line); + + + /** + * Creates an identifier for a {@link R07ReceptorLine}. + * + * @param line the line from which to create the Identifier + * @return the {@link String} identifier + */ + String makeIdentifier(final R07ReceptorLine line); + + /** + * Creates an identifier for a {@link R07ProductGeneric}. + * + * @param r07ProductGeneric the line from which to create the Identifier + * @return the {@link String} identifier + */ + String makeIdentifier(final R07ProductGeneric r07ProductGeneric); + + /** + * Creates an identifier for a {@link R07AltPart}. + * + * @param altPart the line from which to create the Identifier + * @return the {@link String} identifier + */ + String makeIdentifier(final R07AltPart altPart); + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/BomFlattenerR07.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/BomFlattenerR07.java new file mode 100644 index 0000000..fb0527a --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/BomFlattenerR07.java @@ -0,0 +1,153 @@ +package com.capgemini.reports.definition.r07report.data.extractor; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.comparison.AbstractDualBomLineFlattener; +import com.capgemini.reports.bomlineholder.flattener.AbstractBomLineFlattener; +import com.capgemini.reports.bomlineholder.flattener.line.*; +import com.capgemini.reports.definition.r07report.data.TransformerR07; +import com.capgemini.reports.definition.r07report.data.extractor.lines.*; +import com.capgemini.reports.releasestatus.EffectivityBehaviourHelper; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +/** + * This class analyses two {@link BOMLineHolder} and flattens their tree structure into an array of father-son relationships.
+ * The configuration lines are numbered according to the order of the structure, so the structure can be reconstructed after the flattening has been performed. + */ +@Getter +public class BomFlattenerR07 extends AbstractDualBomLineFlattener { + + /** + * Compares two {@link ISnecmaObject} by their Identifiers (Name, or ID). + */ + private static final Comparator ITEM_COMPARATOR = new ItemComparatorR07(); + /** + * Compares to {@link BOMLineHolder}s. Uses the {@link ItemComparatorR07} to compare the {@link ISnecmaObject}s inside. + */ + private static final Comparator BOM_COMPARATOR = new BomComparatorR07(); + + /** + * This counter increments at every new line.
+ * Enables to uniquely identify chronologically every SnecmaLine found on the configuration.
+ * After all the filtering is done, the chronological identifier can be used to mimic the original tree structure of the bom. + */ + private int counter; + + /** + * Builds an {@link AbstractBomLineFlattener} for the R07 report. + */ + public BomFlattenerR07() { + // ***** Spec R07 **** + // - visit only unit-managed parts + // - visit parts in pseudo-folder Alternative + // - Do not retrieve part numbers below RF Generics + // - Do not investigate Parts wwithout a RF above (do not follow Part->Part links + // - Unable to provide the pseudo-folder behaviour yet, will be setup after call to super(...) + // - usual Bom comparator + // - usual item comparator + // - Visit brothers below a parent part BEFORE recursing through the brothers' children + super(EffectivityBehaviourHelper.visitOnlyUnitManagedParts(), true, false, false, null, BOM_COMPARATOR, ITEM_COMPARATOR, true); + this.setPseudoFolderBehaviour(new R07AltOrDetPseudoFolderBehaviour()); + } + + @Override + protected AbstractQuad makeQuad(final TcSession session, final BOMLineHolder receptor, final BOMLineHolder rfReceptor, + final BOMLineHolder component, final BOMLineHolder rfComponent) { + return new R07Quad(session, receptor, rfReceptor, component, rfComponent, counter++); + } + + @Override + protected AbstractTopLine maketopline(final BOMLineHolder aTopBomLine) { + return null; // No need to put the topLine in the report: return null, it will not be put inside the list + } + + @Override + protected AbstractProductGeneric makeProductGeneric(final TcSession session, final BOMLineHolder productReceptor, + final BOMLineHolder genericComponent, final BOMLineHolder rfGenericComponent) { + return new R07ProductGeneric(session, productReceptor, genericComponent, rfGenericComponent, counter++); + } + + @Override + protected AbstractPartNumber makePartNumber(final BOMLineHolder genericReceptor, final BOMLineHolder rfGeneric, + final BOMLineHolder partAero) { + return null; // No need to put part Number in the report: return null, it will not be put inside the list + } + + @Override + protected AbstractPartRfPart makePartRfPart(final TcSession session, final BOMLineHolder partReceptor, final BOMLineHolder rfPartComponent, + final BOMLineHolder partComponent) { + return new R07PartRfPart(session, partReceptor, rfPartComponent, partComponent, counter++); + } + + @Override + protected AbstractReceptorLine makeReceptorLine(final TcSession session, final BOMLineHolder part, final BOMLineHolder rfPart) { + return new R07ReceptorLine(session, part, rfPart, counter++); + } + + @Override + protected AbstractPartPart makePartPart(final BOMLineHolder partReceptor, final BOMLineHolder partComponent) { + return null; // No need to cater for this event in R07, nomenclature should be stopped before: return null, it will not be put inside the list + } + + private static final class ItemComparatorR07 implements Comparator, Serializable { + + private static final long serialVersionUID = 1212463997223603766L; + + @Override + public int compare(final ISnecmaObject obj1, final ISnecmaObject obj2) { + int cmpType = obj1.getType().compareTo(obj2.getType()); + if (cmpType != 0) { + return cmpType; + } + if (obj1.isRF() && obj2.isRF()) { + return obj1.getName().compareTo(obj2.getName()); + } else { + return obj1.getItemId().compareTo(obj2.getItemId()); + } + } + } + + private static final class BomComparatorR07 implements Comparator, Serializable { + + private static final long serialVersionUID = 2176721559188935877L; + + @Override + public int compare(final BOMLineHolder bom1, final BOMLineHolder bom2) { + final int cmp; + if (bom1 == null) { + if (bom2 == null) { + cmp = 0; + } else { + cmp = 1; + } + } else { + if (bom2 == null) { + cmp = -1; + } else { + cmp = ITEM_COMPARATOR.compare(bom1.getSnecmaObject(), bom2.getSnecmaObject()); + } + } + return cmp; + } + } + + @AllArgsConstructor + private class R07AltOrDetPseudoFolderBehaviour implements DealWithAltOrDetPseudoFolder { + @Override + public List> dealWithIt(final BOMLineHolder alt, final AbstractPart partInPseudoFolder) { + List> contents = new ArrayList<>(); + if (alt != null && alt.getSnecmaObject() != null && partInPseudoFolder != null) { + contents.add(new R07AltPart(alt, partInPseudoFolder, counter++)); + } + return contents; + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/DataExtractorR07.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/DataExtractorR07.java new file mode 100644 index 0000000..95f07c1 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/DataExtractorR07.java @@ -0,0 +1,130 @@ +package com.capgemini.reports.definition.r07report.data.extractor; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoSuchBomViewException; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObjectFactory; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRule; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRuleProperties; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.product.TcProduct; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindow; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindowConfiguration; +import com.capgemini.framework.teamcenter.object.runtime.TcRevisionRulesConfiguration; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderFactory; +import com.capgemini.reports.bomlineholder.processor.DefaultAltOrDetBehaviour; +import com.capgemini.reports.definition.r07report.ExecutionR07; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.MalformedNomenclatureException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.filter.AllIsGoodFilter; +import com.capgemini.reports.reports.parameters.Generics; +import com.capgemini.reports.teamcenter.resolution.structureservice.MultiStructureServiceCaller; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Form; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +/** + * Extracts both raw nemenclature from Teamcenter, puts the result into the ExecutionR07. + */ +@Slf4j +public class DataExtractorR07 { + + private static final AllIsGoodFilter ACCEPT_ALL = new AllIsGoodFilter(); + private final TcSession session; + private final ExecutionR07 report; + + // Data gathered + @Getter + private BOMLineHolder topBomConf1; + @Getter + private BOMLineHolder topBomConf2; + + /** + * Creates a {@link DataExtractorR07} object. + * + * @param session the Tc session + * @param report the report holding the necessary bom data + */ + public DataExtractorR07(final TcSession session, final ExecutionR07 report) { + this.session = session; + this.report = report; + } + + /** + * Extracts the two configurations to be compared in the R07 report. + * + * @throws InvalidInputException if the parameters are incorrect + * @throws EmptyNomenclatureException if the nomeclature is empty + * @throws NoSuchBomViewException if the bomview could not be found + * @throws MalformedNomenclatureException if the nomeclature cannot be formed + */ + public void extractData() throws KurtException { + log.debug("PrepareData started on: " + report.getReportIdentifier().getReportTitle()); + long start = System.currentTimeMillis(); + + // Setup the policy + session.setObjectPropPolicy(report.getFullPolicy()); + + String revisionRule = report.getRevisionRule(); + + log.debug("Check the data structures using revision rule {}.", revisionRule); + Generics genericParam1 = report.getGenericParam1(); + Generics genericParam2 = report.getGenericParam2(); + + log.debug("Resolve Configuration 1"); + topBomConf1 = resolveTopBom(genericParam1); + + log.debug("Resolve Configuration 2"); + topBomConf2 = resolveTopBom(genericParam2); + + log.debug("Data gathering time : {} ms", System.currentTimeMillis() - start); + } + + private BOMLineHolder resolveTopBom(final Generics generic) throws KurtException { + TcBomObject topLineObject = new TcBomObjectFactory(session, generic.getItem(session)).create(); + TcProduct productObject = new TcProduct(session, generic.getProductUnit().getProduct(session)); + int unit = generic.getProductUnit().getUnit(); + + TcRevisionRuleProperties revisionRuleProperties = new TcRevisionRuleProperties(productObject, unit); + + TcRevisionRule revisionRule = session.findRevRule(report.getRevisionRule()); + TcRevisionRulesConfiguration revRulesConfiguration = new TcRevisionRulesConfiguration(revisionRule, revisionRuleProperties); + + // Perform the job + log.debug("Data configured, now starting nomenclature resolution"); + try (TcBomWindow bomWindow = session.createBomWindow(new TcBomWindowConfiguration(topLineObject, revRulesConfiguration))) { + session.setObjectPropPolicy(report.getFullPolicy()); + + BOMLineHolder unbuiltTopLine = new MultiStructureServiceCaller(session).resolve(bomWindow.topLine(), ACCEPT_ALL); + List itemRevMaster = unbuiltTopLine.getAllItemRevMasters(); + session.loadProperties(itemRevMaster.toArray(new ModelObject[itemRevMaster.size()])); + + log.debug("Building the Snecma Objects"); + BOMLineHolderFactory.buildTopBom(session, unbuiltTopLine, ACCEPT_ALL); + + log.debug("Loading the correct revisions of all Items in the pseudo-folders of Alt And DET parts"); + DefaultAltOrDetBehaviour altOrDetBehaviour = new DefaultAltOrDetBehaviour<>(session, null); + unbuiltTopLine.process(altOrDetBehaviour); + + log.debug("All required data was loaded, freezing the BomLineHolder..."); + unbuiltTopLine.freeze(); + return unbuiltTopLine; + } catch (EmptyNomenclatureException e) { + switch (generic.getType()) { + case GENERIC: + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_PRODUCT_AND_UNIT, e); + case GENERIC_ASSEMB: + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_ASSEMB_PRODUCT_AND_UNIT, e); + default: + throw e; + } + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/lines/ComparableLine.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/lines/ComparableLine.java new file mode 100644 index 0000000..390e089 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/lines/ComparableLine.java @@ -0,0 +1,57 @@ +package com.capgemini.reports.definition.r07report.data.extractor.lines; + + +/** + * Interface used in the R07 for comparing lines to each other. + */ +public interface ComparableLine { + /** + * Compares a line to any other {@link ComparableLine}. + * + * @param other the other line + * @return the difference + */ + int compareLineContent(final ComparableLine other); + + /** + * Compares a line a to a {@link R07Quad}. + * + * @param other the other line + * @return the difference + */ + int compareContent(final R07Quad other); + + /** + * Compares a line a to a {@link R07PartRfPart}. + * + * @param other the other line + * @return the difference + */ + int compareContent(final R07PartRfPart other); + + /** + * Compares a line a to a {@link R07ReceptorLine}. + * + * @param other the other line + * @return the difference + */ + int compareContent(final R07ReceptorLine other); + + /** + * Compares a line a to a {@link R07ProductGeneric}. + * + * @param other the other line + * @return the difference + */ + int compareContent(final R07ProductGeneric other); + + /** + * Compares a line a to a {@link R07AltPart}. + * + * @param other the other line + * @return the difference + */ + int compareContent(final R07AltPart other); + + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/lines/R07AltPart.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/lines/R07AltPart.java new file mode 100644 index 0000000..534634f --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/lines/R07AltPart.java @@ -0,0 +1,74 @@ +package com.capgemini.reports.definition.r07report.data.extractor.lines; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.flattener.line.AbstractAltPart; +import com.capgemini.reports.definition.r07report.data.TransformerR07; +import com.capgemini.reports.definition.r07report.data.filter.comparators.AbstractBomLineComparator; +import com.capgemini.reports.definition.r07report.data.filter.comparators.AbstractItemComparator; +import com.capgemini.reports.exceptions.NotSupportedException; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import lombok.extern.slf4j.Slf4j; + +/** + * Represents The link between an Alt and a Part in its pseudo-folder. + */ +@Slf4j +public class R07AltPart extends AbstractAltPart implements ComparableLine { + + /** + * builds the link between an Altenrate and a Part in its pseudo-folder. + * + * @param alt the Alternate + * @param child the child part + * @param counter the position of this line in the nomenclature. + */ + public R07AltPart(final BOMLineHolder alt, final AbstractPart child, final int counter) { + super(alt, child, counter); + } + + @Override + public String transform(final TransformerR07 transformer) { + return transformer.makeIdentifier(this); + } + + @Override + public int compareLineContent(final ComparableLine other) { + return other.compareContent(this); + } + + @Override + public int compareContent(final R07AltPart other) { + try { + int cmp = AbstractBomLineComparator.compareReceptors(this.getAltBL(), other.getAltBL()); + if (cmp != 0) { + return cmp; + } + cmp = AbstractItemComparator.compareComponents(this.getChild(), other.getChild()); + return cmp; + } catch (NotSupportedException e) { + log.info("Failed object comparison", e); + return 1; + } + } + + @Override + public int compareContent(final R07Quad other) { + return 1; + } + + @Override + public int compareContent(final R07ReceptorLine other) { + return 1; + } + + @Override + public int compareContent(final R07ProductGeneric other) { + return 1; + } + + @Override + public int compareContent(final R07PartRfPart other) { + return 1; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/lines/R07PartRfPart.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/lines/R07PartRfPart.java new file mode 100644 index 0000000..c5f71a5 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/lines/R07PartRfPart.java @@ -0,0 +1,78 @@ +package com.capgemini.reports.definition.r07report.data.extractor.lines; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.flattener.line.AbstractPartRfPart; +import com.capgemini.reports.definition.r07report.data.TransformerR07; +import com.capgemini.reports.definition.r07report.data.filter.comparators.AbstractBomLineComparator; +import com.capgemini.reports.definition.r07report.data.filter.comparators.rf.RfComparator; +import com.capgemini.reports.exceptions.NotSupportedException; +import lombok.extern.slf4j.Slf4j; + +/** + * Represents a classical 'triplet' between a Part, a Rf Part and a Part. + */ +@Slf4j +public class R07PartRfPart extends AbstractPartRfPart implements ComparableLine { + + + /** + * Builds a classical 'triplet' between a Part, a Rf Part and a Part. + * + * @param partReceptor a {@link BOMLineHolder} + * @param rfPartComponent a {@link BOMLineHolder} + * @param partComponent a {@link BOMLineHolder} + * @param counter the position of the line in the nomenclature. + */ + public R07PartRfPart(final TcSession session, final BOMLineHolder partReceptor, final BOMLineHolder rfPartComponent, final BOMLineHolder partComponent, + final int counter) { + super(session, partReceptor, rfPartComponent, partComponent, counter); + } + + @Override + public String transform(final TransformerR07 transformer) { + return transformer.makeIdentifier(this); + } + + @Override + public int compareLineContent(final ComparableLine other) { + return other.compareContent(this); + } + + @Override + public int compareContent(final R07PartRfPart other) { + try { + int cmp = AbstractBomLineComparator.compareReceptors(this.getPartReceptorBL(), other.getPartReceptorBL()); + if (cmp == 0) { + cmp = RfComparator.compareRf(this.getRfPartComponentBL(), other.getRfPartComponentBL()); + if (cmp == 0) { + cmp = AbstractBomLineComparator.compareComponents(this.getPartComponentBL(), other.getPartComponentBL()); + } + } + return cmp; + } catch (NotSupportedException e) { + log.warn("Failed object comparison", e); + return 1; + } + } + + @Override + public int compareContent(final R07Quad other) { + return 1; + } + + @Override + public int compareContent(final R07ReceptorLine other) { + return 1; + } + + @Override + public int compareContent(final R07ProductGeneric other) { + return 1; + } + + @Override + public int compareContent(final R07AltPart other) { + return 1; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/lines/R07ProductGeneric.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/lines/R07ProductGeneric.java new file mode 100644 index 0000000..eaf7487 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/lines/R07ProductGeneric.java @@ -0,0 +1,77 @@ +package com.capgemini.reports.definition.r07report.data.extractor.lines; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.flattener.line.AbstractProductGeneric; +import com.capgemini.reports.definition.r07report.data.TransformerR07; +import com.capgemini.reports.definition.r07report.data.filter.comparators.AbstractBomLineComparator; +import com.capgemini.reports.definition.r07report.data.filter.comparators.rf.RfComparator; +import com.capgemini.reports.exceptions.NotSupportedException; +import lombok.extern.slf4j.Slf4j; + +/** + * Represents a Product - Generic line for R07 report. + */ +@Slf4j +public class R07ProductGeneric extends AbstractProductGeneric implements ComparableLine { + + /** + * Builds a Product - Generic line for the R07 report. + * + * @param productReceptor a {@link BOMLineHolder} + * @param genericComponent a {@link BOMLineHolder} + * @param rfGenericComponent a {@link BOMLineHolder} + * @param counter the position of this line in the Bom. + */ + public R07ProductGeneric(final TcSession session, final BOMLineHolder productReceptor, final BOMLineHolder genericComponent, final BOMLineHolder rfGenericComponent, + final int counter) { + super(session, productReceptor, genericComponent, rfGenericComponent, counter); + } + + @Override + public String transform(final TransformerR07 transformer) { + return transformer.makeIdentifier(this); + } + + @Override + public int compareLineContent(final ComparableLine other) { + return other.compareContent(this); + } + + @Override + public int compareContent(final R07PartRfPart other) { + return 1; + } + + @Override + public int compareContent(final R07Quad other) { + return 1; + } + + @Override + public int compareContent(final R07ReceptorLine other) { + return 1; + } + + @Override + public int compareContent(final R07ProductGeneric other) { + try { + int cmp = AbstractBomLineComparator.compareReceptors(this.getProductReceptorBL(), other.getProductReceptorBL()); + if (cmp == 0) { + cmp = RfComparator.compareRf(this.getRfGenericComponentBL(), other.getRfGenericComponentBL()); + if (cmp == 0) { + cmp = AbstractBomLineComparator.compareComponents(this.getGenericComponentBL(), other.getGenericComponentBL()); + } + } + return cmp; + } catch (NotSupportedException e) { + log.warn("Failed object comparison", e); + return 1; + } + } + + @Override + public int compareContent(final R07AltPart other) { + return 1; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/lines/R07Quad.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/lines/R07Quad.java new file mode 100644 index 0000000..8053f8e --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/lines/R07Quad.java @@ -0,0 +1,80 @@ +package com.capgemini.reports.definition.r07report.data.extractor.lines; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.flattener.line.AbstractQuad; +import com.capgemini.reports.definition.r07report.data.TransformerR07; +import com.capgemini.reports.definition.r07report.data.filter.comparators.AbstractBomLineComparator; +import com.capgemini.reports.definition.r07report.data.filter.comparators.rf.RfComparator; +import com.capgemini.reports.exceptions.NotSupportedException; +import lombok.extern.slf4j.Slf4j; + +/** + * Represents a {@link AbstractQuad} line, with receptor and component, both having their own repere.
+ * Receptors and components can be Parts or Generics.
+ * For the R07, the Quad accepts a TransformerR07 which will generate a custom Id for it, for sorting purposes. + */ +@Slf4j +public class R07Quad extends AbstractQuad implements ComparableLine { + + /** + * Builds a 'quad' object, using receptor, its repere, a component, and its repere. + * + * @param recepteurBL a {@link BOMLineHolder} + * @param repereRecepteurBL a {@link BOMLineHolder} + * @param composantBL a {@link BOMLineHolder} + * @param repereComposantBL a {@link BOMLineHolder} + * @param counter the position of this line in the Bom + */ + public R07Quad(final TcSession session, final BOMLineHolder recepteurBL, final BOMLineHolder repereRecepteurBL, final BOMLineHolder composantBL, + final BOMLineHolder repereComposantBL, final int counter) { + super(session, recepteurBL, repereRecepteurBL, composantBL, repereComposantBL, counter); + } + + @Override + public String transform(final TransformerR07 transformer) { + return transformer.makeIdentifier(this); + } + + @Override + public int compareLineContent(final ComparableLine other) { + return other.compareContent(this); + } + + @Override + public int compareContent(final R07Quad other) { + try { + int cmp = AbstractBomLineComparator.compareReceptors(this.getRecepteurBL(), other.getRecepteurBL()); + if (cmp == 0) { + cmp = RfComparator.compareRf(this.getRepereComposantBL(), other.getRepereComposantBL()); + if (cmp == 0) { + cmp = AbstractBomLineComparator.compareComponents(this.getComposantBL(), other.getComposantBL()); + } + } + return cmp; + } catch (NotSupportedException e) { + log.warn("Failed object comparison", e); + return 1; + } + } + + @Override + public int compareContent(final R07PartRfPart other) { + return 1; + } + + @Override + public int compareContent(final R07ReceptorLine other) { + return 1; + } + + @Override + public int compareContent(final R07ProductGeneric other) { + return 1; + } + + @Override + public int compareContent(final R07AltPart other) { + return 1; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/lines/R07ReceptorLine.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/lines/R07ReceptorLine.java new file mode 100644 index 0000000..29fce52 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/extractor/lines/R07ReceptorLine.java @@ -0,0 +1,60 @@ +package com.capgemini.reports.definition.r07report.data.extractor.lines; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.flattener.line.AbstractReceptorLine; +import com.capgemini.reports.definition.r07report.data.TransformerR07; +import com.capgemini.reports.definition.r07report.data.filter.comparators.AbstractBomLineComparator; + +/** + * Represents a Receptor whose Repere does ot have a Component. + */ +public class R07ReceptorLine extends AbstractReceptorLine implements ComparableLine { + + + /** + * Builds a Receptor whose Repere does ot have a Component. + * + * @param recepteurBL the bom line holder of the receptor + * @param repereRecepteurBL the bom line holder of the repere + * @param counter the position of the line in the nomenclature + */ + public R07ReceptorLine(final TcSession session, final BOMLineHolder recepteurBL, final BOMLineHolder repereRecepteurBL, final int counter) { + super(session, recepteurBL, repereRecepteurBL, counter); + } + + @Override + public String transform(final TransformerR07 transformer) { + return transformer.makeIdentifier(this); + } + + @Override + public int compareLineContent(final ComparableLine other) { + return other.compareContent(this); + } + + @Override + public int compareContent(final R07Quad other) { + return 1; + } + + @Override + public int compareContent(final R07PartRfPart other) { + return 1; + } + + @Override + public int compareContent(final R07ReceptorLine other) { + return AbstractBomLineComparator.compareReceptors(this.getRecepteurBL(), other.getRecepteurBL()); + } + + @Override + public int compareContent(final R07ProductGeneric other) { + return 1; + } + + @Override + public int compareContent(final R07AltPart other) { + return 1; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/ConfigurationFilterR07.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/ConfigurationFilterR07.java new file mode 100644 index 0000000..8766402 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/ConfigurationFilterR07.java @@ -0,0 +1,302 @@ +package com.capgemini.reports.definition.r07report.data.filter; + +import com.capgemini.reports.bomlineholder.flattener.line.SnecmaLine; +import com.capgemini.reports.definition.r07report.data.TransformerR07; +import com.capgemini.reports.definition.r07report.data.extractor.BomFlattenerR07; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.*; + +/** + * This class filters two configurations, then extracts the differences. + *
    + *
  • All lines that are identical on both sides are lost
  • + *
  • All lines that boast the same structure (same receptor, repere, component for example) but have a difference in their content, are stored side by side in a {@link List} of {@link Diff} named {@link ConfigurationFilterR07#propDiff propDiff}.
  • + *
  • All lines that are exclusive to either configuration are kept in a separate {@link List} of {@link SnecmaLine}s named {@link ConfigurationFilterR07#exclusiveConf1 exclusiveConf1} and {@link ConfigurationFilterR07#exclusiveConf2 exclusiveConf2}.
  • + *
+ */ +@Getter +public class ConfigurationFilterR07 { + + /** + * Provides capabilities for comparing structure (receptor/repere) between two {@link SnecmaLine}s. + */ + private static final Comparator> STRUCTURAL_COMPARATOR = new StructuralComparator(); + /** + * Provides capabilities for comparing full-depth content between two {@link SnecmaLine}s. + */ + private static final Comparator> CONTENT_COMPARATOR = new ContentComparator(); + /** + * List of differences detected in properties' contents between two objects of the same structure. + */ + private final List propDiff = new ArrayList<>(); + /** + * Pairs exclusively present in Conf1. + */ + private final List> exclusiveConf1 = new ArrayList<>(); + /** + * Pairs exclusively present in Conf2. + */ + private final List> exclusiveConf2 = new ArrayList<>(); + /** + * Number of exact matches in both configurations: same structure, same data content. + */ + private int cloneNum; + + /** + * The main method of the class: performs a Filtering on two configurations.
+ * Leaves this instance in a state where it holds: + *
    + *
  • A {@link List} of {@link Diff} between data pairs conf1-conf2
  • + *
  • Two {@link List}s of exclusive content
  • + *
  • and the number of clones found in both configurations
  • + *
+ *
+ * Note: the input {@link BomFlattenerR07}'s contents will be cleared in the process! + * + * @param conf the configuration holder + */ + public void filter(final BomFlattenerR07 conf) { + List similarBuckets = filterExclusiveContent(conf.getConfig1(), conf.getConfig2()); + for (R07Bucket bucket : similarBuckets) { + bucket.filterSimilarContent(); + } + } + + /** + * Detect exclusive items of each conf, stores them appart, and removes them from their respective conf. + * + * @return a series of data buckets, each holding two sets of objects from either conf, which belong share the same structure + */ + private List filterExclusiveContent(final List> conf1, + final List> conf2) { + List similarBuckets = new ArrayList<>(); + + // Sort both configurations in place, according to the comparator. + // Note several elements may be 'equal' regarding to the comparator: they will keep their respective order + // Sorting several times using increasingly restrictive comparators is not so expensive, because each pass uses the pre-optimised result of the previous pass + Collections.sort(conf1, STRUCTURAL_COMPARATOR); + Collections.sort(conf2, STRUCTURAL_COMPARATOR); + R07Bucket currentBucket = null; + Iterator> iteratorConf1 = conf1.iterator(); + Iterator> iteratorConf2 = conf2.iterator(); + SnecmaLine lowestConf1 = iteratorConf1.next(); + SnecmaLine lowestConf2 = iteratorConf2.next(); + iteratorConf1.remove(); + iteratorConf2.remove(); + boolean keepOn = true; + // Now iterate from 'lowest' member of either conf to 'highest' member of either conf + while (keepOn) { + int compare = STRUCTURAL_COMPARATOR.compare(lowestConf1, lowestConf2); + if (compare == 0) { + // Same structure on both stacks! + if (currentBucket == null) { + currentBucket = new R07Bucket(lowestConf1); // Start new bucket + } else { + // Packet already existing, does it have the same value? + if (currentBucket.compareTo(lowestConf1) != 0) { + similarBuckets.add(currentBucket); // different value detected, let's register the old bucket... + currentBucket = new R07Bucket(lowestConf1); // ...and start a new one + } + } + + // The current bucket has the correct ref value, we just need to add the new data pair in it + currentBucket.add(lowestConf1, lowestConf2); + if (iteratorConf1.hasNext() && iteratorConf2.hasNext()) { + // Prepare next run + lowestConf1 = iteratorConf1.next(); + lowestConf2 = iteratorConf2.next(); + iteratorConf1.remove(); + iteratorConf2.remove(); + } else { + keepOn = false; // End of the while + } + } else { + // Stream of similar-valued object has stopped. Time to register the bucket content (if any) + if (currentBucket != null && !currentBucket.isEmpty()) { + similarBuckets.add(currentBucket); + } + currentBucket = null; + if (compare < 0) { // Stack 1 is strictly lower than stack 2 + exclusiveConf1.add(lowestConf1); // Any encountered value is removed from the conf1 and added to the 'exclusive conf 1' list + if (iteratorConf1.hasNext()) { + // Prepare next run + lowestConf1 = iteratorConf1.next(); + iteratorConf1.remove(); + } else { + keepOn = false; // End of the while loop + } + } else { // Stack 2 is strictly lower than stack 1 + exclusiveConf2.add(lowestConf2); // Any encountered value is removed from the conf2 and added to the 'exclusive conf 2' list + if (iteratorConf2.hasNext()) { + // Prepare next run + lowestConf2 = iteratorConf2.next(); + iteratorConf2.remove(); + } else { + keepOn = false; // End of the while loop + } + } + } + } + // Cleanup: active bucket may need to be added to the list if not empty + if (currentBucket != null && !currentBucket.isEmpty()) { + similarBuckets.add(currentBucket); + } + // Cleanup: Any remaining item between index and the end of its stack is exclusive to that stack + while (!conf1.isEmpty()) { + exclusiveConf1.add(conf1.remove(0)); + } + while (!conf2.isEmpty()) { + exclusiveConf2.add(conf2.remove(0)); + } + return similarBuckets; + } + + /** + * Holds twoLines of either configuration, which are the same, but have a content difference between them. + */ + @AllArgsConstructor + @Getter + public static class Diff { + + private final SnecmaLine first; + private final SnecmaLine second; + + @Override + public String toString() { + return "Diff{" + first.toString() + " != " + second.toString() + "}"; + } + } + + /** + * 'Bucket' class to store 'similar' (According to the BOM_COMPARATOR) objects from both configurations.
+ * Objects that are 'identical' according to the CONTENT_COMPARATOR can then be identified and removed. + */ + @AllArgsConstructor + @Getter + private class R07Bucket { + + /** + * Reference line. Defines the Structure signature of this bucket uniquely. + */ + private final SnecmaLine ref; + /** + * Contains all the SnecmaLine from conf1 that have the same Structure as the REF. + */ + private final List> first = new ArrayList<>(); + /** + * Contains all the SnecmaLine from conf2 that have the same Structure as the REF. + */ + private final List> second = new ArrayList<>(); + + /** + * Compares this bucket's ref to the line. + * + * @param line the line + * @return the result + */ + public int compareTo(final SnecmaLine line) { + return ref.compareTo(line); + } + + /** + * Bucket empty? + * + * @return true if it is empty + */ + public boolean isEmpty() { + return first.isEmpty() && second.isEmpty(); + } + + /** + * Adds a pair to the bucket. Added objects MUST be 'similar' to the bucket's content. + * + * @param conf1 the object from conf1 + * @param conf2 the object from conf2 + */ + public void add(final SnecmaLine conf1, final SnecmaLine conf2) { + first.add(conf1); + second.add(conf2); + } + + /** + * This method: + *
    + *
  1. Removes 'identical' (same content) pairs found in both configurations.
  2. + *
  3. Bundles 'similar' (same structure) but not 'identical' objects from either confs together
  4. + *
  5. Remaining 'surplus' objects from a conf (that therefore cannot be appaired to an object from the other conf) are sent to an 'exclusive' list.
  6. + *
+ */ + void filterSimilarContent() { + removeIdenticalPairs(); + // All exact pairs from this bucket have been found and matched together (they will not show up in the report + bundleSimilarPairs(); + // Any remaining item in the larger list of the two will be shown as an exclusive member of its conf + exclusiveConf1.addAll(first); + exclusiveConf2.addAll(second); + } + + /** + * Finds and removes all identical pairs from this bucket (they will not show up in the report). + */ + private void removeIdenticalPairs() { + Iterator> conf1Iterator = first.iterator(); + while (conf1Iterator.hasNext()) { + SnecmaLine line1 = conf1Iterator.next(); + Iterator> conf2Iterator = second.iterator(); + while (conf2Iterator.hasNext()) { + SnecmaLine line2 = conf2Iterator.next(); + if (CONTENT_COMPARATOR.compare(line1, line2) == 0) { // Exact same content detected, from two lines in the same bucket so same structure) + cloneNum++; + // This pair will never make it to the report + conf1Iterator.remove(); + conf2Iterator.remove(); + break; + } + } + } + } + + /** + * Bundles together any two line from either configuration.
+ * At this point these lines all have a difference otherwise they would have been removed by the previous step {@link R07Bucket#removeIdenticalPairs()}.
+ * In priority, lines from either configuration that have the same Part number will be paired. This is not required, but is nice. + */ + private void bundleSimilarPairs() { + // First pair lines that have the same Part ID. If several can be found, the 1st one is chosen (arbitrary) + Iterator> conf1Iterator = first.iterator(); + while (conf1Iterator.hasNext()) { + SnecmaLine line1 = conf1Iterator.next(); + Iterator> conf2Iterator = second.iterator(); + while (conf2Iterator.hasNext()) { + SnecmaLine line2 = conf2Iterator.next(); + if (line1.getIDComponent().compareTo(line2.getIDComponent()) == 0) { + // This pair will be shown as a content diff between the two configurations + propDiff.add(new Diff(line1, line2)); + conf1Iterator.remove(); + conf2Iterator.remove(); + break; // Find another couple + } + } + } + + // Any remaining item in the bucket will be paired arbitrarily until one conf is emptied + conf1Iterator = first.iterator(); + Iterator> conf2Iterator = second.iterator(); + while (conf1Iterator.hasNext() && conf2Iterator.hasNext()) { + SnecmaLine line1 = conf1Iterator.next(); + SnecmaLine line2 = conf2Iterator.next(); + // This pair will be shown as a content diff between the two configurations + propDiff.add(new Diff(line1, line2)); + conf1Iterator.remove(); + conf2Iterator.remove(); + } + } + + @Override + public String toString() { + return "Pack<" + first.toString() + " vs " + second.toString() + ">"; + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/ContentComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/ContentComparator.java new file mode 100644 index 0000000..12c8462 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/ContentComparator.java @@ -0,0 +1,25 @@ +package com.capgemini.reports.definition.r07report.data.filter; + +import com.capgemini.reports.bomlineholder.flattener.line.SnecmaLine; +import com.capgemini.reports.definition.r07report.data.TransformerR07; +import com.capgemini.reports.definition.r07report.data.extractor.lines.ComparableLine; +import lombok.extern.slf4j.Slf4j; + +import java.util.Comparator; + +/** + * Provides capabilities for comparing full-depth content between two {@link SnecmaLine}s. + */ +@Slf4j +public class ContentComparator implements Comparator> { + @Override + public int compare(final SnecmaLine line1, final SnecmaLine line2) { + if (line1 instanceof ComparableLine && line2 instanceof ComparableLine) { + return ((ComparableLine) line1).compareLineContent((ComparableLine) line2); + } else { + log.warn("A SnecmaLine of unsupported Type was found in the R07 during comparison: {} vs. {}", line1.getClass().getName(), line2 + .getClass().getName()); + return 1; + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/StructuralComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/StructuralComparator.java new file mode 100644 index 0000000..8c8e78a --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/StructuralComparator.java @@ -0,0 +1,31 @@ +package com.capgemini.reports.definition.r07report.data.filter; + +import com.capgemini.reports.bomlineholder.flattener.line.SnecmaLine; +import com.capgemini.reports.definition.r07report.data.TransformerR07; +import com.capgemini.reports.definition.r07report.data.filter.identifiers.ReceptorIdExtractor; +import com.capgemini.reports.definition.r07report.data.filter.identifiers.RepereIdExtractor; + +import java.util.Comparator; + +/** + * Provides capabilities for comparing structure (receptor ID/repere NAME) between two {@link SnecmaLine}s. + */ +public class StructuralComparator implements Comparator> { + + private static final TransformerR07 RECEPTOR_ID_EXTRACTOR = new ReceptorIdExtractor(); + private static final TransformerR07 REPERE_ID_EXTRACTOR = new RepereIdExtractor(); + + @Override + public int compare(final SnecmaLine line1, final SnecmaLine line2) { + String receptorId1 = line1.transform(RECEPTOR_ID_EXTRACTOR); + String receptorId2 = line2.transform(RECEPTOR_ID_EXTRACTOR); + int diff = receptorId1.compareTo(receptorId2); + if (diff != 0) { + return diff; // Structural difference: Receptor mismatch + } + String repereId1 = line1.transform(REPERE_ID_EXTRACTOR); + String repereId2 = line2.transform(REPERE_ID_EXTRACTOR); + diff = repereId1.compareTo(repereId2); + return diff; // last possible structural difference: Repere mismatch + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/AbstractBomLineComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/AbstractBomLineComparator.java new file mode 100644 index 0000000..70f7176 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/AbstractBomLineComparator.java @@ -0,0 +1,73 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.definition.r07report.data.filter.comparators.generics.GenericBLComparator; +import com.capgemini.reports.definition.r07report.data.filter.comparators.part.PartBLComparator; +import com.capgemini.reports.exceptions.NotSupportedException; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; + +import java.io.Serializable; +import java.util.Comparator; + +/** + * Helper class to comapre two {@link BOMLineHolder}s content. + */ +public abstract class AbstractBomLineComparator implements Comparator, Serializable { + private static final long serialVersionUID = 3764547367272622769L; + + private static int mySafeCmp(final String str1, final String str2) { + if (str1 == null) { + return str2 == null ? 0 : 1; + } else if (str2 == null) { + return -1; + } else { + return str1.compareTo(str2); + } + } + + /** + * Compares two Receptors together. Only their item ID and Name are compared. + * + * @param thisBL this object + * @param otherBL an other object + * @return the diff + */ + public static int compareReceptors(final BOMLineHolder thisBL, final BOMLineHolder otherBL) { + ISnecmaObject thisReceptor = thisBL.getSnecmaObject(); + ISnecmaObject otherReceptor = otherBL.getSnecmaObject(); + return AbstractItemComparator.compareReceptors(thisReceptor, otherReceptor); + } + + /** + * Compares two components's contents. The components can be any Part or any Generic. + * + * @param thisBL this object + * @param otherBL an other object + * @return the diff + * @throws NotSupportedException if the objects are of the wrong type + */ + public static int compareComponents(final BOMLineHolder thisBL, final BOMLineHolder otherBL) throws NotSupportedException { + ISnecmaObject thisComponent = thisBL.getSnecmaObject(); + ISnecmaObject otherComponent = otherBL.getSnecmaObject(); + String thisType = thisComponent.getType(); + String otherType = otherComponent.getType(); + int cmp = thisType.compareTo(otherType); + if (cmp != 0) { + return cmp; + } + if (thisComponent.isGeneric()) { + return GenericBLComparator.compareGenerics(thisBL, otherBL); + } + if (thisComponent.isPart()) { + return PartBLComparator.compareParts(thisBL, otherBL); + } else { + throw new NotSupportedException( + StringHelper.concat("Unsupported Component type: ", thisComponent.getItemId(), " of type ", thisType).toString()); + } + } + + protected int safeCmp(final String str1, final String str2) { + return mySafeCmp(str1, str2); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/AbstractItemComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/AbstractItemComparator.java new file mode 100644 index 0000000..e804d29 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/AbstractItemComparator.java @@ -0,0 +1,80 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.reports.definition.r07report.data.filter.comparators.generics.GenericComparator; +import com.capgemini.reports.definition.r07report.data.filter.comparators.part.PartComparator; +import com.capgemini.reports.exceptions.NotSupportedException; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; + +import java.io.Serializable; +import java.util.Comparator; + +/** + * Helper class to comapre two {@link ISnecmaObject}s content. + */ +public abstract class AbstractItemComparator implements Comparator, Serializable { + private static final long serialVersionUID = -8787518342193550661L; + + private static int mySafeCmp(final String str1, final String str2) { + if (str1 == null) { + return str2 == null ? 0 : 1; + } else if (str2 == null) { + return -1; + } else { + return str1.compareTo(str2); + } + } + + /** + * Compares two Receptors together. Only their item ID and Name are compared. + * + * @param thisObj this object + * @param otherObj an other object + * @return the diff + */ + static int compareReceptors(final ISnecmaObject thisObj, final ISnecmaObject otherObj) { + String thisType = thisObj.getType(); + String otherType = otherObj.getType(); + int cmp = thisType.compareTo(otherType); + if (cmp != 0) { + return cmp; + } + // Compare basic data + cmp = mySafeCmp(thisObj.getItemId(), otherObj.getItemId()); + if (cmp != 0) { + return cmp; + } + cmp = mySafeCmp(thisObj.getName(), otherObj.getName()); + return cmp; + } + + /** + * Compares two components's contents. The components can be any Part or any Generic. + * + * @param thisComponent this object + * @param otherComponent an other object + * @return the diff + * @throws NotSupportedException if objects are of the wrong type + */ + public static int compareComponents(final ISnecmaObject thisComponent, final ISnecmaObject otherComponent) throws NotSupportedException { + String thisType = thisComponent.getType(); + String otherType = otherComponent.getType(); + int cmp = thisType.compareTo(otherType); + if (cmp != 0) { + return cmp; + } + if (thisComponent.isGeneric()) { + return GenericComparator.compareGenerics(thisComponent, otherComponent); + } + if (thisComponent.isPart()) { + return PartComparator.compareParts(thisComponent, otherComponent); + } else { + throw new NotSupportedException( + StringHelper.concat("Unsupported Component type: ", thisComponent.getItemId(), " of type ", thisType).toString()); + } + } + + protected int safeCmp(final String str1, final String str2) { + return mySafeCmp(str1, str2); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/generics/GenericBLComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/generics/GenericBLComparator.java new file mode 100644 index 0000000..66eb860 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/generics/GenericBLComparator.java @@ -0,0 +1,58 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.generics; + +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.definition.r07report.data.filter.comparators.AbstractBomLineComparator; +import com.capgemini.reports.exceptions.NotSupportedException; + +/** + * Compares two Generics / Generics Assembs' {@link BOMLineHolder}s to each other. + */ +public class GenericBLComparator extends AbstractBomLineComparator { + private static final long serialVersionUID = -1959398094059231129L; + + /** + * Compares a two Generic/Generic Assemb contents. + * + * @param thisGen this object + * @param otherGen an other object + * @return the difference + * @throws NotSupportedException if either bomline does not hold a Generic / Generic Assemb + */ + public static int compareGenerics(final BOMLineHolder thisGen, final BOMLineHolder otherGen) throws NotSupportedException { + String thisType = thisGen.getSnecmaObject().getType(); + String otherType = otherGen.getSnecmaObject().getType(); + int cmp = thisType.compareTo(otherType); + if (cmp != 0) { + return cmp; + } + if (SnecmaObjectTypes.GENERIC_REVISION.equals(thisType) || SnecmaObjectTypes.GENERIC_ASSEMB_REVISION.equals(thisType)) { + return new GenericBLComparator().compare(thisGen, otherGen); + } else { + throw new NotSupportedException("Unsupported Generic type: " + thisGen.getSnecmaObject().getItemId() + " of type " + thisType); + } + } + + @Override + public int compare(final BOMLineHolder thisGenericBL, final BOMLineHolder otherGenericBL) { + // Compare BOM data + int cmp = safeCmp(thisGenericBL.getBomQty(), otherGenericBL.getBomQty()); + if (cmp == 0) { + cmp = safeCmp(thisGenericBL.getBomAlt(), otherGenericBL.getBomAlt()); + } + if (cmp == 0) { + cmp = safeCmp(thisGenericBL.getBomSb(), otherGenericBL.getBomSb()); + } + if (cmp == 0) { + cmp = safeCmp(thisGenericBL.getBomQtyCumul(), otherGenericBL.getBomQtyCumul()); + } + if (cmp == 0) { + cmp = safeCmp(thisGenericBL.getBomPanache(), otherGenericBL.getBomPanache()); + } + if (cmp == 0) { + // Compare Generic data + cmp = new GenericComparator().compare(thisGenericBL.getSnecmaObject(), otherGenericBL.getSnecmaObject()); + } + return cmp; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/generics/GenericComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/generics/GenericComparator.java new file mode 100644 index 0000000..fe76287 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/generics/GenericComparator.java @@ -0,0 +1,55 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.generics; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.definition.r07report.data.filter.comparators.AbstractItemComparator; +import com.capgemini.reports.exceptions.NotSupportedException; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.generic.AbstractGenericRevision; + +/** + * Compares two Generic's contents. + */ +public class GenericComparator extends AbstractItemComparator { + private static final long serialVersionUID = -1959398094059231129L; + + /** + * Compares two Generic's contents. + * + * @param thisGen this object + * @param otherGen an other object + * @return the diff + * @throws NotSupportedException if objects are not Generics + */ + public static int compareGenerics(final ISnecmaObject thisGen, final ISnecmaObject otherGen) throws NotSupportedException { + String thisType = thisGen.getType(); + String otherType = otherGen.getType(); + int cmp = thisType.compareTo(otherType); + if (cmp != 0) { + return cmp; + } + if (SnecmaObjectTypes.GENERIC_REVISION.equals(thisType) || SnecmaObjectTypes.GENERIC_ASSEMB_REVISION.equals(thisType)) { + return new GenericComparator().compare(thisGen, otherGen); + } else { + throw new NotSupportedException(StringHelper.concat("Unsupported Generic type: ", thisGen.getItemId(), " of type ", thisType).toString()); + } + } + + @Override + public int compare(final ISnecmaObject thisItem, final ISnecmaObject otherItem) { + // Compare Generic data + AbstractGenericRevision thisGeneric = (AbstractGenericRevision) thisItem; + AbstractGenericRevision otherGeneric = (AbstractGenericRevision) otherItem; + int cmp = thisGeneric.getItemId().compareTo(otherGeneric.getItemId()); + if (cmp == 0) { + cmp = safeCmp(thisGeneric.getName(), otherGeneric.getName()); + if (cmp == 0) { + cmp = safeCmp(thisGeneric.getDesignationEN(), otherGeneric.getDesignationEN()); + if (cmp == 0) { + cmp = safeCmp(thisGeneric.getResponsableConception(), otherGeneric.getResponsableConception()); + } + } + } + return cmp; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/AlternateBLComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/AlternateBLComparator.java new file mode 100644 index 0000000..96ab087 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/AlternateBLComparator.java @@ -0,0 +1,21 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.part; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; + +/** + * Compares Alternates' {@link BOMLineHolder}s. + */ +public class AlternateBLComparator extends PartBLComparator { + + private static final long serialVersionUID = 4589727916093844161L; + + @Override + public int compare(final BOMLineHolder thisPartBL, final BOMLineHolder otherPartBL) { + int cmp = super.compare(thisPartBL, otherPartBL); + if (cmp != 0) { + return cmp; + } + return new AlternateComparator().compare(thisPartBL.getSnecmaObject(), otherPartBL.getSnecmaObject()); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/AlternateComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/AlternateComparator.java new file mode 100644 index 0000000..74dfe70 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/AlternateComparator.java @@ -0,0 +1,28 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.part; + +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.part.AlternateRevision; + +/** + * Compares two {@link AlternateRevision}'s contents. + */ +public class AlternateComparator extends PartComparator { + private static final long serialVersionUID = 4589727916093844161L; + + @Override + public int compare(final ISnecmaObject thisPart, final ISnecmaObject otherPart) { + int cmp = super.compare(thisPart, otherPart); + if (cmp != 0) { + return cmp; + } + AlternateRevision thisAlt = (AlternateRevision) thisPart; + AlternateRevision otherAlt = (AlternateRevision) otherPart; + cmp = thisAlt.getTypeAlt1().compareTo(otherAlt.getTypeAlt1()); + if (cmp != 0) { + return cmp; + } + cmp = thisAlt.getTypeAlt2().compareTo(otherAlt.getTypeAlt2()); + return cmp; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/DetBLComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/DetBLComparator.java new file mode 100644 index 0000000..0f8bd1d --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/DetBLComparator.java @@ -0,0 +1,21 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.part; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; + +/** + * Compares DETs' {@link BOMLineHolder}s. + */ +public class DetBLComparator extends PartBLComparator { + + private static final long serialVersionUID = 7467086955431692767L; + + @Override + public int compare(final BOMLineHolder thisPartBL, final BOMLineHolder otherPartBL) { + int cmp = super.compare(thisPartBL, otherPartBL); + if (cmp != 0) { + return cmp; + } + return new DetComparator().compare(thisPartBL.getSnecmaObject(), otherPartBL.getSnecmaObject()); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/DetComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/DetComparator.java new file mode 100644 index 0000000..5a9669c --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/DetComparator.java @@ -0,0 +1,29 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.part; + +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.part.DETRevision; + +/** + * Compares two {@link DETRevision}'s contents. + */ +public class DetComparator extends PartComparator { + + private static final long serialVersionUID = 3412387355420636670L; + + @Override + public int compare(final ISnecmaObject thisPart, final ISnecmaObject otherPart) { + int cmp = super.compare(thisPart, otherPart); + if (cmp != 0) { + return cmp; + } + DETRevision thisDET = (DETRevision) thisPart; + DETRevision otherDET = (DETRevision) otherPart; + cmp = thisDET.getTypeDet1().compareTo(otherDET.getTypeDet1()); + if (cmp != 0) { + return cmp; + } + cmp = thisDET.getTypeDet2().compareTo(otherDET.getTypeDet2()); + return cmp; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartAeroBLComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartAeroBLComparator.java new file mode 100644 index 0000000..89f9198 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartAeroBLComparator.java @@ -0,0 +1,21 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.part; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; + +/** + * Compares two PartAeros' {@link BOMLineHolder}. + */ +public class PartAeroBLComparator extends PartBLComparator { + private static final long serialVersionUID = 4353837710227367827L; + + @Override + public int compare(final BOMLineHolder thisPartBL, final BOMLineHolder otherPartBL) { + int cmp = super.compare(thisPartBL, otherPartBL); + if (cmp != 0) { + return cmp; + } + return new PartAeroComparator().compare(thisPartBL.getSnecmaObject(), otherPartBL.getSnecmaObject()); + + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartAeroComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartAeroComparator.java new file mode 100644 index 0000000..06fec66 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartAeroComparator.java @@ -0,0 +1,28 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.part; + +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.part.PartAeroRevision; + +/** + * Compares two {@link PartAeroRevision}'s contents. + */ +public class PartAeroComparator extends PartComparator { + private static final long serialVersionUID = 5813446144969040585L; + + @Override + public int compare(final ISnecmaObject thisPart, final ISnecmaObject otherPart) { + int cmp = super.compare(thisPart, otherPart); + if (cmp == 0) { + PartAeroRevision thisPartAero = (PartAeroRevision) thisPart; + PartAeroRevision otherPartAero = (PartAeroRevision) otherPart; + cmp = thisPartAero.getTypeAero1().compareTo(otherPartAero.getTypeAero1()); + if (cmp == 0) { + cmp = thisPartAero.getTypeAero2().compareTo(otherPartAero.getTypeAero2()); + if (cmp == 0) { + cmp = thisPartAero.getTypeAero3().compareTo(otherPartAero.getTypeAero3()); + } + } + } + return cmp; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartAssembBLComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartAssembBLComparator.java new file mode 100644 index 0000000..520f29b --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartAssembBLComparator.java @@ -0,0 +1,20 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.part; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; + +/** + * Compares two PartAssembs' {@link BOMLineHolder}s. + */ +public class PartAssembBLComparator extends PartBLComparator { + private static final long serialVersionUID = -8453498458441935461L; + + @Override + public int compare(final BOMLineHolder thisPartBL, final BOMLineHolder otherPartBL) { + int cmp = super.compare(thisPartBL, otherPartBL); + if (cmp != 0) { + return cmp; + } + return new PartAssembComparator().compare(thisPartBL.getSnecmaObject(), otherPartBL.getSnecmaObject()); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartAssembComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartAssembComparator.java new file mode 100644 index 0000000..3df81b4 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartAssembComparator.java @@ -0,0 +1,28 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.part; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.part.PartAssembRevision; + +/** + * Compares two {@link PartAssembRevision}'s {@link BOMLineHolder}s. + */ +public class PartAssembComparator extends PartComparator { + private static final long serialVersionUID = 3276642480323176366L; + + @Override + public int compare(final ISnecmaObject thisParL, final ISnecmaObject otherPart) { + int cmp = super.compare(thisParL, otherPart); + if (cmp != 0) { + return cmp; + } + PartAssembRevision thisPartAssemb = (PartAssembRevision) thisParL; + PartAssembRevision otherPartAssemb = (PartAssembRevision) otherPart; + cmp = thisPartAssemb.getTypePartMontage1().compareTo(otherPartAssemb.getTypePartMontage1()); + if (cmp != 0) { + return cmp; + } + cmp = thisPartAssemb.getTypePartMontage2().compareTo(otherPartAssemb.getTypePartMontage2()); + return cmp; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartBLComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartBLComparator.java new file mode 100644 index 0000000..ff83262 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartBLComparator.java @@ -0,0 +1,74 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.part; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.definition.r07report.data.filter.comparators.AbstractBomLineComparator; +import com.capgemini.reports.exceptions.NotSupportedException; + +/** + * Compares two Parts' {@link BOMLineHolder}s, for any type of Part. + */ +public class PartBLComparator extends AbstractBomLineComparator { + private static final long serialVersionUID = 1847560066180416682L; + + /** + * Compare two part bomlines together. + * + * @param part this object + * @param other an other object + * @return the diff + * @throws NotSupportedException if objects are of the wrong type + */ + public static int compareParts(final BOMLineHolder part, final BOMLineHolder other) throws NotSupportedException { + String thisType = part.getSnecmaObject().getType(); + String otherType = other.getSnecmaObject().getType(); + int cmp = thisType.compareTo(otherType); + if (cmp != 0) { + return cmp; + } + // Same types + if (SnecmaObjectTypes.ALTERNATE_REVISION.equals(thisType)) { + cmp = new AlternateBLComparator().compare(part, other); + } else if (SnecmaObjectTypes.DET_REVISION.equals(thisType)) { + cmp = new DetBLComparator().compare(part, other); + } else if (SnecmaObjectTypes.PART_AERO_REVISION.equals(thisType)) { + cmp = new PartAeroBLComparator().compare(part, other); + } else if (SnecmaObjectTypes.PART_NO_AERO_REVISION.equals(thisType)) { + cmp = new PartNoAeroBLComparator().compare(part, other); + } else if (SnecmaObjectTypes.PART_ASSEMB_REVISION.equals(thisType)) { + cmp = new PartAssembBLComparator().compare(part, other); + } else if (SnecmaObjectTypes.PART_MAT_REVISION.equals(thisType)) { + cmp = new PartMatBLComparator().compare(part, other); + } else if (SnecmaObjectTypes.STANDARD_REVISION.equals(thisType)) { + cmp = new StandardBLComparator().compare(part, other); + } else { + throw new NotSupportedException( + StringHelper.concat("Unsupported Part type: ", part.getSnecmaObject().getItemId(), " of type ", thisType).toString()); + } + return cmp; + } + + @Override + public int compare(final BOMLineHolder thisPartBL, final BOMLineHolder otherPartBL) { + // Compare BOM data + int cmp = safeCmp(thisPartBL.getBomQty(), otherPartBL.getBomQty()); + if (cmp == 0) { + cmp = safeCmp(thisPartBL.getBomAlt(), otherPartBL.getBomAlt()); + } + if (cmp == 0) { + cmp = safeCmp(thisPartBL.getBomSb(), otherPartBL.getBomSb()); + } + if (cmp == 0) { + cmp = safeCmp(thisPartBL.getBomQtyCumul(), otherPartBL.getBomQtyCumul()); + } + if (cmp == 0) { + cmp = safeCmp(thisPartBL.getBomPanache(), otherPartBL.getBomPanache()); + } + if (cmp == 0) { + return new PartComparator().compare(thisPartBL.getSnecmaObject(), otherPartBL.getSnecmaObject()); + } + return cmp; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartComparator.java new file mode 100644 index 0000000..b0ff0aa --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartComparator.java @@ -0,0 +1,89 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.part; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.definition.r07report.data.filter.comparators.AbstractItemComparator; +import com.capgemini.reports.exceptions.NotSupportedException; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; + +/** + * Compares two {@link AbstractPart}'s {@link BOMLineHolder}s. + */ +public class PartComparator extends AbstractItemComparator { + private static final long serialVersionUID = 8767701166124425908L; + + /** + * Compares two Part's contents. + * + * @param part this object + * @param other an other object + * @return the diff + * @throws NotSupportedException when one of the input is not a Part + */ + public static int compareParts(final ISnecmaObject part, final ISnecmaObject other) throws NotSupportedException { + String thisType = part.getType(); + String otherType = other.getType(); + int cmp = thisType.compareTo(otherType); + if (cmp == 0) { + if (SnecmaObjectTypes.ALTERNATE_REVISION.equals(thisType)) { + cmp = new AlternateComparator().compare(part, other); + } else if (SnecmaObjectTypes.DET_REVISION.equals(thisType)) { + cmp = new DetComparator().compare(part, other); + } else if (SnecmaObjectTypes.PART_AERO_REVISION.equals(thisType)) { + cmp = new PartAeroComparator().compare(part, other); + } else if (SnecmaObjectTypes.PART_NO_AERO_REVISION.equals(thisType)) { + cmp = new PartNoAeroComparator().compare(part, other); + } else if (SnecmaObjectTypes.PART_ASSEMB_REVISION.equals(thisType)) { + cmp = new PartAssembComparator().compare(part, other); + } else if (SnecmaObjectTypes.PART_MAT_REVISION.equals(thisType)) { + cmp = new PartMatComparator().compare(part, other); + } else if (SnecmaObjectTypes.STANDARD_REVISION.equals(thisType)) { + cmp = new StandardComparator().compare(part, other); + } else { + throw new NotSupportedException(StringHelper.concat("Unsupported Part type: ", part.getItemId(), " of type ", thisType).toString()); + } + } + return cmp; + } + + @Override + public int compare(final ISnecmaObject thisObj, final ISnecmaObject otherObj) { + AbstractPart thisPart = (AbstractPart) thisObj; + AbstractPart otherPart = (AbstractPart) otherObj; + // Compare part data + int cmp = thisPart.getItemId().compareTo(otherPart.getItemId()); + if (cmp == 0) { + cmp = safeCmp(thisPart.getName(), otherPart.getName()); + } + if (cmp == 0) { + cmp = safeCmp(thisPart.getDesignationEN(), otherPart.getDesignationEN()); + } + if (cmp == 0) { + cmp = safeCmp(thisPart.getRefCompleteConcepteur(), otherPart.getRefCompleteConcepteur()); + } + if (cmp == 0) { + cmp = safeCmp(thisPart.getRefTransposeeSnecma(), otherPart.getRefTransposeeSnecma()); + } + if (cmp == 0) { + cmp = safeCmp(thisPart.getResponsableConception(), otherPart.getResponsableConception()); + } + if (cmp == 0) { + cmp = safeCmp(thisPart.getClassement(), otherPart.getClassement()); + } + if (cmp == 0) { + cmp = safeCmp(thisPart.getSuiviUtilisation(), otherPart.getSuiviUtilisation()); + } + if (cmp == 0) { + cmp = safeCmp(thisPart.getSuiviDureeVie(), otherPart.getSuiviDureeVie()); + } + if (cmp == 0) { + cmp = Double.compare(thisPart.getMass(), otherPart.getMass()); + } + if (cmp == 0) { + cmp = safeCmp(thisPart.getMassUnit(), otherPart.getMassUnit()); + } + return cmp; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartMatBLComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartMatBLComparator.java new file mode 100644 index 0000000..016c0d4 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartMatBLComparator.java @@ -0,0 +1,20 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.part; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; + +/** + * Compares two PartMats' {@link BOMLineHolder}s. + */ +public class PartMatBLComparator extends PartBLComparator { + private static final long serialVersionUID = -2934813561955929208L; + + @Override + public int compare(final BOMLineHolder thisPartBL, final BOMLineHolder otherPartBL) { + int cmp = super.compare(thisPartBL, otherPartBL); + if (cmp != 0) { + return cmp; + } + return new PartMatComparator().compare(thisPartBL.getSnecmaObject(), otherPartBL.getSnecmaObject()); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartMatComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartMatComparator.java new file mode 100644 index 0000000..f615e32 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartMatComparator.java @@ -0,0 +1,25 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.part; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.part.PartMatRevision; + +/** + * Compares two {@link PartMatRevision}'s {@link BOMLineHolder}s. + */ +public class PartMatComparator extends PartComparator { + private static final long serialVersionUID = 4148977376229148277L; + + @Override + public int compare(final ISnecmaObject thisPart, final ISnecmaObject otherPart) { + int cmp = super.compare(thisPart, otherPart); + if (cmp != 0) { + return cmp; + } + PartMatRevision thisPartMat = (PartMatRevision) thisPart; + PartMatRevision otherPartMat = (PartMatRevision) otherPart; + cmp = thisPartMat.getClassementMat().compareTo(otherPartMat.getClassementMat()); + return cmp; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartNoAeroBLComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartNoAeroBLComparator.java new file mode 100644 index 0000000..3594143 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartNoAeroBLComparator.java @@ -0,0 +1,20 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.part; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; + +/** + * Compares two PartNoAeros' {@link BOMLineHolder}s. + */ +public class PartNoAeroBLComparator extends PartBLComparator { + private static final long serialVersionUID = 5954871414512808855L; + + @Override + public int compare(final BOMLineHolder thisPartBL, final BOMLineHolder otherPartBL) { + int cmp = super.compare(thisPartBL, otherPartBL); + if (cmp != 0) { + return cmp; + } + return new PartNoAeroComparator().compare(thisPartBL.getSnecmaObject(), otherPartBL.getSnecmaObject()); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartNoAeroComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartNoAeroComparator.java new file mode 100644 index 0000000..da9a475 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/PartNoAeroComparator.java @@ -0,0 +1,24 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.part; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.part.PartNoAeroRevision; + +/** + * Compares two {@link PartNoAeroRevision}'s {@link BOMLineHolder}s. + */ +public class PartNoAeroComparator extends PartComparator { + private static final long serialVersionUID = -1728487703112167469L; + + @Override + public int compare(final ISnecmaObject thisPart, final ISnecmaObject otherPart) { + int cmp = super.compare(thisPart, otherPart); + if (cmp != 0) { + return cmp; + } + PartNoAeroRevision thisPartNoAero = (PartNoAeroRevision) thisPart; + PartNoAeroRevision otherPartNoAero = (PartNoAeroRevision) otherPart; + cmp = thisPartNoAero.getTypeNoAero().compareTo(otherPartNoAero.getTypeNoAero()); + return cmp; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/StandardBLComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/StandardBLComparator.java new file mode 100644 index 0000000..5daae9a --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/StandardBLComparator.java @@ -0,0 +1,20 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.part; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; + +/** + * Compares two Standards' {@link BOMLineHolder}s. + */ +public class StandardBLComparator extends PartBLComparator { + private static final long serialVersionUID = 7862979771467078306L; + + @Override + public int compare(final BOMLineHolder thisPartBL, final BOMLineHolder otherPartBL) { + int cmp = super.compare(thisPartBL, otherPartBL); + if (cmp != 0) { + return cmp; + } + return new StandardComparator().compare(thisPartBL.getSnecmaObject(), otherPartBL.getSnecmaObject()); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/StandardComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/StandardComparator.java new file mode 100644 index 0000000..6162ed4 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/part/StandardComparator.java @@ -0,0 +1,24 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.part; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.part.StandardRevision; + +/** + * Compares two {@link StandardRevision}'s {@link BOMLineHolder}s. + */ +public class StandardComparator extends PartComparator { + private static final long serialVersionUID = -3007235542630939436L; + + @Override + public int compare(final ISnecmaObject thisPart, final ISnecmaObject otherPart) { + int cmp = super.compare(thisPart, otherPart); + if (cmp != 0) { + return cmp; + } + StandardRevision thisStandard = (StandardRevision) thisPart; + StandardRevision otherStandard = (StandardRevision) otherPart; + cmp = thisStandard.getTypeStandard().compareTo(otherStandard.getTypeStandard()); + return cmp; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/rf/RfComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/rf/RfComparator.java new file mode 100644 index 0000000..4cf3f46 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/rf/RfComparator.java @@ -0,0 +1,49 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.rf; + +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderHelper; +import com.capgemini.reports.definition.r07report.data.filter.comparators.AbstractBomLineComparator; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.exceptions.NotSupportedException; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import lombok.extern.slf4j.Slf4j; + +/** + * Compares two RFs' {@link BOMLineHolder}s together. + */ +@Slf4j +public abstract class RfComparator extends AbstractBomLineComparator { + private static final long serialVersionUID = -1907326362935233365L; + + /** + * Compares two RFs of any subtype. + */ + public static int compareRf(final BOMLineHolder thisRf, final BOMLineHolder otherRf) throws NotSupportedException { + String thisType = thisRf.getSnecmaObject().getType(); + String otherType = otherRf.getSnecmaObject().getType(); + int cmp = thisType.compareTo(otherType); + if (cmp == 0) { + if (SnecmaObjectTypes.RF_GENERIC_REVISION.equals(thisType)) { + cmp = new RfGenericComparator().compare(thisRf, otherRf); + } else if (SnecmaObjectTypes.RF_PART_REVISION.equals(thisType)) { + cmp = new RfPartComparator().compare(thisRf, otherRf); + } else if (SnecmaObjectTypes.RF_PART_ASSEMB_REVISION.equals(thisType)) { + cmp = new RfPartAssembComparator().compare(thisRf, otherRf); + } else { + throw new NotSupportedException("Unsupported RF type: " + thisRf.getSnecmaObject().getItemId() + " of type " + thisType); + } + } + return cmp; + } + + RFAdminRevision findRfAdmin(final BOMLineHolder aRF) { + try { + return BOMLineHolderHelper.findRfAdmin(aRF); + } catch (NotFoundException | InvalidInputException nfe) { + log.warn("No RF Admin AP found below: " + aRF.getSnecmaObject().getName(), nfe); + return null; + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/rf/RfGenericComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/rf/RfGenericComparator.java new file mode 100644 index 0000000..b0ada5d --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/rf/RfGenericComparator.java @@ -0,0 +1,37 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.rf; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import lombok.extern.slf4j.Slf4j; + +/** + * Compares two RF Generics together. + */ +@Slf4j +public class RfGenericComparator extends RfComparator { + + private static final long serialVersionUID = 8420569609216039442L; + + RfGenericComparator() { + } + + @Override + public int compare(final BOMLineHolder thisRfBL, final BOMLineHolder otherRfBL) { + // Bowse children for RF Admin + RFAdminRevision thisRfAdmin = findRfAdmin(thisRfBL); + RFAdminRevision otherRfAdmin = findRfAdmin(otherRfBL); + if (thisRfAdmin == null || otherRfAdmin == null) { + if (thisRfAdmin == null && otherRfAdmin == null) { + log.warn("No RF Admin found below both compared RF Generics: " + thisRfBL.getSnecmaObject().getName() + " / " + + otherRfBL.getSnecmaObject().getName()); + // No difference, then! + return 0; + } else { + log.warn("No RF Admin found below one of the compared RF Generics: " + thisRfBL.getSnecmaObject().getName() + " / " + + otherRfBL.getSnecmaObject().getName()); + return 1; // Diff found + } + } + return safeCmp(thisRfAdmin.getResponsableRepere(), otherRfAdmin.getResponsableRepere()); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/rf/RfPartAssembComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/rf/RfPartAssembComparator.java new file mode 100644 index 0000000..d719b20 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/rf/RfPartAssembComparator.java @@ -0,0 +1,68 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.rf; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderHelper; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision; +import com.capgemini.reports.snecmaobjects.rf.AbstractRF; +import lombok.extern.slf4j.Slf4j; + +/** + * Compares two RFPartAssembs together. + */ +@Slf4j +public class RfPartAssembComparator extends RfComparator { + + private static final long serialVersionUID = -9166209208947984853L; + + RfPartAssembComparator() { + } + + @Override + public int compare(final BOMLineHolder thisRfBL, final BOMLineHolder otherRfBL) { + // Compare part data + AbstractRF thisRf = (AbstractRF) thisRfBL.getSnecmaObject(); + AbstractRF otherRf = (AbstractRF) otherRfBL.getSnecmaObject(); + int cmp = thisRf.getName().compareTo(otherRf.getName()); + if (cmp != 0) { + return cmp; + } + + // Bowse children for RF Admin A + return compareRfAdminA(thisRfBL, otherRfBL); + } + + private int compareRfAdminA(final BOMLineHolder thisRfBL, final BOMLineHolder otherRfBL) { + // Bowse children for RF Admin A + RFAdminARevision thisRfAdminAP = getRfAdminA(thisRfBL); + RFAdminARevision otherRfAdminAP = getRfAdminA(otherRfBL); + + if (thisRfAdminAP == null || otherRfAdminAP == null) { + if (thisRfAdminAP == null && otherRfAdminAP == null) { + log.warn("No RF Admin AP found below both compared RF Parts: " + thisRfBL.getSnecmaObject().getName() + " / " + + otherRfBL.getSnecmaObject().getName()); + // No difference, then! + return 0; + } else { + log.warn("No RF Admin AP found below one of the compared RF Parts: " + thisRfBL.getSnecmaObject().getName() + " / " + + otherRfBL.getSnecmaObject().getName()); + return 1; // Diff found + } + } + int cmp = safeCmp(thisRfAdminAP.getSuiviMontage(), otherRfAdminAP.getSuiviMontage()); + if (cmp == 0) { + cmp = safeCmp(thisRfAdminAP.getResponsableRepere(), otherRfAdminAP.getResponsableRepere()); + } + return cmp; + } + + private RFAdminARevision getRfAdminA(final BOMLineHolder thisRfBL) { + try { + return BOMLineHolderHelper.findRfAdminA(thisRfBL); + } catch (NotFoundException | InvalidInputException nfe) { + log.warn("No RF Admin AP found below: " + thisRfBL.getSnecmaObject().getName(), nfe); + return null; + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/rf/RfPartComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/rf/RfPartComparator.java new file mode 100644 index 0000000..3e38b03 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/comparators/rf/RfPartComparator.java @@ -0,0 +1,91 @@ +package com.capgemini.reports.definition.r07report.data.filter.comparators.rf; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderHelper; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.rf.AbstractRF; +import lombok.extern.slf4j.Slf4j; + +/** + * Comapres two RF Parts together. + */ +@Slf4j +public class RfPartComparator extends RfComparator { + private static final long serialVersionUID = -185746619920561652L; + + RfPartComparator() { + } + + @Override + public int compare(final BOMLineHolder thisRfBL, final BOMLineHolder otherRfBL) { + // Compare part data + AbstractRF thisRf = (AbstractRF) thisRfBL.getSnecmaObject(); + AbstractRF otherRf = (AbstractRF) otherRfBL.getSnecmaObject(); + int cmp = thisRf.getName().compareTo(otherRf.getName()); + if (cmp != 0) { + return cmp; + } + cmp = safeCmp(thisRf.getEquivalentSnsSin(), otherRf.getEquivalentSnsSin()); + if (cmp != 0) { + return cmp; + } + // Bowse children for RF Admin + cmp = compareRfAdmin(thisRfBL, otherRfBL); + if (cmp != 0) { + return cmp; + } + // Bowse children for RF Admin AP + cmp = compareRfAdminAP(thisRfBL, otherRfBL); + return cmp; + } + + private int compareRfAdmin(final BOMLineHolder thisRfBL, final BOMLineHolder otherRfBL) { + // Bowse children for RF Admin + RFAdminRevision thisRfAdmin = findRfAdmin(thisRfBL); + RFAdminRevision otherRfAdmin = findRfAdmin(otherRfBL); + if (thisRfAdmin == null || otherRfAdmin == null) { + if (thisRfAdmin == null && otherRfAdmin == null) { + log.warn("No RF Admin found below both compared RF Generics: " + thisRfBL.getSnecmaObject().getName() + " / " + + otherRfBL.getSnecmaObject().getName()); + // No difference, then! + return 0; + } else { + log.warn("No RF Admin found below one of the compared RF Generics: " + thisRfBL.getSnecmaObject().getName() + " / " + + otherRfBL.getSnecmaObject().getName()); + return 1; // Diff found + } + } + return safeCmp(thisRfAdmin.getResponsableRepere(), otherRfAdmin.getResponsableRepere()); + } + + private int compareRfAdminAP(final BOMLineHolder thisRfBL, final BOMLineHolder otherRfBL) { + // Bowse children for RF Admin + RFAdminAPRevision thisRfAdminAP = findRfAdminAP(thisRfBL); + RFAdminAPRevision otherRfAdminAP = findRfAdminAP(otherRfBL); + + if (thisRfAdminAP == null || otherRfAdminAP == null) { + if (thisRfAdminAP == null && otherRfAdminAP == null) { + log.warn("No RF Admin AP found below both compared RF Parts: " + thisRfBL.getSnecmaObject().getName() + " / " + + otherRfBL.getSnecmaObject().getName()); + return 0; + } else { + log.warn("No RF Admin AP found below one of the compared RF Parts: " + thisRfBL.getSnecmaObject().getName() + " / " + + otherRfBL.getSnecmaObject().getName()); + return 1; + } + } + return safeCmp(thisRfAdminAP.getSuiviMontage(), otherRfAdminAP.getSuiviMontage()); + } + + private RFAdminAPRevision findRfAdminAP(final BOMLineHolder aRF) { + try { + return BOMLineHolderHelper.findRfAdminAP(aRF); + } catch (NotFoundException | InvalidInputException nfe) { + log.warn("No RF Admin AP found below: " + aRF.getSnecmaObject().getName(), nfe); + return null; + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/identifiers/ReceptorIdExtractor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/identifiers/ReceptorIdExtractor.java new file mode 100644 index 0000000..6a0119b --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/identifiers/ReceptorIdExtractor.java @@ -0,0 +1,35 @@ +package com.capgemini.reports.definition.r07report.data.filter.identifiers; + +import com.capgemini.reports.definition.r07report.data.TransformerR07; +import com.capgemini.reports.definition.r07report.data.extractor.lines.*; + +/** + * Extracts a receptor's identifier: its Id. + */ +public class ReceptorIdExtractor implements TransformerR07 { + + @Override + public String makeIdentifier(final R07Quad line) { + return line.getRecepteur().getItemId(); + } + + @Override + public String makeIdentifier(final R07PartRfPart line) { + return line.getPartReceptor().getItemId(); + } + + @Override + public String makeIdentifier(final R07ReceptorLine line) { + return line.getRecepteur().getItemId(); + } + + @Override + public String makeIdentifier(final R07ProductGeneric line) { + return line.getProductReceptor().getItemId(); + } + + @Override + public String makeIdentifier(final R07AltPart altPart) { + return altPart.getAltBL().getSnecmaObject().getItemId(); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/identifiers/RepereIdExtractor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/identifiers/RepereIdExtractor.java new file mode 100644 index 0000000..cde514d --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/filter/identifiers/RepereIdExtractor.java @@ -0,0 +1,36 @@ +package com.capgemini.reports.definition.r07report.data.filter.identifiers; + +import com.capgemini.reports.definition.r07report.data.TransformerR07; +import com.capgemini.reports.definition.r07report.data.extractor.lines.*; + +/** + * Extracts a Repere's identifier: its NAME. + */ +public class RepereIdExtractor implements TransformerR07 { + + @Override + public String makeIdentifier(final R07Quad line) { + return line.getRepereComposant().getName(); + } + + @Override + public String makeIdentifier(final R07PartRfPart line) { + return line.getRfPartComponent().getName(); + } + + @Override + public String makeIdentifier(final R07ReceptorLine line) { + return line.getRepere().getName(); + } + + @Override + public String makeIdentifier(final R07ProductGeneric line) { + return line.getRfGenericComponent().getItemId(); + } + + @Override + public String makeIdentifier(final R07AltPart altPart) { + return ""; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/sorter/R07DataSorter.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/sorter/R07DataSorter.java new file mode 100644 index 0000000..0a0c8f0 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/data/sorter/R07DataSorter.java @@ -0,0 +1,133 @@ +package com.capgemini.reports.definition.r07report.data.sorter; + +import com.capgemini.reports.bomlineholder.flattener.line.SnecmaLine; +import com.capgemini.reports.definition.r07report.data.TransformerR07; +import com.capgemini.reports.definition.r07report.data.filter.ConfigurationFilterR07; +import com.capgemini.reports.definition.r07report.data.filter.ConfigurationFilterR07.Diff; +import com.capgemini.reports.definition.r07report.printing.EnumMapDelta; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.*; + +/** + * Sorts the various differences spotted between the two configuration: puts the lines in the original nomenclature's order. + */ +public class R07DataSorter { + + private static final boolean CONF1 = true; + private static final boolean CONF2 = false; + private static final boolean EXCLU = true; + private static final boolean BOTH_CONF = false; + + /** + * Returns true when there is a diff between the two objects. + */ + private static > Boolean safeDiff(final T obj1, final T obj2) { + if (obj1 == null && obj2 == null) { + return false; + } + if (obj1 != null && obj2 != null) { + return obj1.compareTo(obj2) != 0; + } + return true; + } + + /** + * Main method of the class: sorts the filter's unique diff content back into the original nombenclature's order. + * + * @param filter the filter containging the diff data + * @return a collection of {@link ConfLine}s + */ + public List sort(final ConfigurationFilterR07 filter) { + List list = new ArrayList<>(); + for (SnecmaLine line : filter.getExclusiveConf1()) { + list.add(new ConfLine(line, line.getLineNumber(), CONF1, EXCLU, null)); + } + for (SnecmaLine line : filter.getExclusiveConf2()) { + list.add(new ConfLine(line, line.getLineNumber(), CONF2, EXCLU, null)); + } + for (Diff diff : filter.getPropDiff()) { + SnecmaLine conf1 = diff.getFirst(); + SnecmaLine conf2 = diff.getSecond(); + + // Create the line comparison map to know which cells to highlight in yellow + Map delta = new EnumMap<>(EnumMapDelta.class); + delta.put(EnumMapDelta.ALT_ECART, safeDiff(conf1.getALT(), conf2.getALT())); + delta.put(EnumMapDelta.ARTICLE_GESTION_ECART, safeDiff(conf1.getArticleGestion(), conf2.getArticleGestion())); + delta.put(EnumMapDelta.CLASSEMENT_ECART, safeDiff(conf1.getClassement(), conf2.getClassement())); + delta.put(EnumMapDelta.ID_RECEPTEUR_ECART, safeDiff(conf1.getIDReceptor(), conf2.getIDReceptor())); + delta.put(EnumMapDelta.LISTE_FOURNISSEUR_ECART, compareArray(conf1.getSuppliersList(), conf2.getSuppliersList())); + delta.put(EnumMapDelta.NOM_RECEPTEUR_ECART, safeDiff(conf1.getNameReceptor(), conf2.getNameReceptor())); + delta.put(EnumMapDelta.NOM_REFERENCE_ECART, safeDiff(conf1.getNameReference(), conf2.getNameReference())); + delta.put(EnumMapDelta.PANACHAGE_ECART, safeDiff(conf1.getPanachage(), conf2.getPanachage())); + delta.put(EnumMapDelta.QUANTITE_CUMULEE_ECART, safeDiff(conf1.getQuantiteCumulee(), conf2.getQuantiteCumulee())); + delta.put(EnumMapDelta.QUANTITE_ECART, safeDiff(conf1.getQuantite(), conf2.getQuantite())); + delta.put(EnumMapDelta.REF_FABRICANT_ECART, safeDiff(conf1.getIDComponent(), conf2.getIDComponent())); + delta.put(EnumMapDelta.REFERENCE_ASSOCIEE_ECART, safeDiff(conf1.getReferenceAssociated(), conf2.getReferenceAssociated())); + delta.put(EnumMapDelta.REFERENCE_CONCEPTEUR_ECART, safeDiff(conf1.getReferenceConceptor(), conf2.getReferenceConceptor())); + delta.put(EnumMapDelta.REFERENCE_TRANSPOSEE_ECART, safeDiff(conf1.getReferenceTransposed(), conf2.getReferenceTransposed())); + delta.put(EnumMapDelta.REPERE_FONCTIONNEL_ECART, safeDiff(conf1.getRepereName(), conf2.getRepereName())); + delta.put(EnumMapDelta.RESPONSABLE_REPERE_ECART, safeDiff(conf1.getResponsableRepere(), conf2.getResponsableRepere())); + delta.put(EnumMapDelta.RESPONSABLE_CONCEPTION_ECART, safeDiff(conf1.getResponsableConception(), conf2.getResponsableConception())); + delta.put(EnumMapDelta.SUIVI_BESOIN_ECART, safeDiff(conf1.getSB(), conf2.getSB())); + delta.put(EnumMapDelta.SUIVI_DUREE_VIE_ECART, safeDiff(conf1.getSuiviDureeVie(), conf2.getSuiviDureeVie())); + delta.put(EnumMapDelta.SUIVI_MONTAGE_ECART, safeDiff(conf1.getSuiviMontage(), conf2.getSuiviMontage())); + delta.put(EnumMapDelta.SUIVI_UTILISATION_ECART, safeDiff(conf1.getSuiviUtilisation(), conf2.getSuiviUtilisation())); + delta.put(EnumMapDelta.TYPE_REFERENCE_ECART, safeDiff(conf1.getTypeReference(), conf2.getTypeReference())); + + // Both have the same line number: they will appear side-by-side in the report! + int lineNumber = Math.min(conf1.getLineNumber(), conf2.getLineNumber()); + list.add(new ConfLine(conf1, lineNumber, CONF1, BOTH_CONF, delta)); + list.add(new ConfLine(conf2, lineNumber, CONF2, BOTH_CONF, delta)); + } + + // Do the sorting now + Collections.sort(list, new Comparator() { + + @Override + public int compare(final ConfLine line1, final ConfLine line2) { + return line1.getNum() - line2.getNum(); + } + + }); + return list; + } + + /** + * Compares two lists, returns true if there is a DIFFERENCE. + */ + private boolean compareArray(final String[] conf1, final String[] conf2) { + boolean result = false; + if (conf1.length != conf2.length) { + result = true; + } else { + for (int i = 0; i < conf1.length; i++) { + if (conf1[i] != null && conf2[i] != null) { + return conf1[i].compareTo(conf2[i]) != 0; + } else if (conf1[i] != null || conf2[i] != null) { + return true; + } + } + } + return result; + } + + /** + * Regroups all the data regarding the comparison between two. + */ + @AllArgsConstructor + @Getter + public static class ConfLine { + private final SnecmaLine line; + int num; + boolean conf1; + boolean exclusive; + Map hasMod; + + @Override + public String toString() { + return String.format("%03d", num) + (exclusive ? " EXCLU " : " CONF ") + (conf1 ? "1 " : "2 ") + line.toString(); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/BuilderTemplateR07.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/BuilderTemplateR07.java new file mode 100644 index 0000000..bdefec4 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/BuilderTemplateR07.java @@ -0,0 +1,339 @@ +package com.capgemini.reports.definition.r07report.printing; + +import com.capgemini.reports.exceptions.FileLoadingException; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.templates.Alignment; +import com.capgemini.reports.templates.CellFormat; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Class which allow to build a dynamic template thanks to DynamicTemplateBuilder class. + */ +@Slf4j +@Getter +public class BuilderTemplateR07 { + private static final int COL_WIDTH_NOM_CN = 125; + private static final int COL_WIDTH_TYPE_CN = 110; + private static final int COL_WIDTH_REVISION_CN = 80; + private static final int COL_WIDTH_ID_CN = 80; + private static final int COL_WIDTH_NOM_CR = 125; + private static final int COL_WIDTH_TYPE_CR = 110; + private static final int COL_WIDTH_REVISION_CR = 100; + private static final int COL_WIDTH_ID_CR = 100; + private static final int COL_WIDTH_QUANTITE = 90; + private static final int COL_WIDTH_PANACHAGE = 80; + private static final int COL_WIDTH_QUANTITE_CUMULEE = 80; + private static final int COL_WIDTH_SUIVANT_BESOIN = 80; + private static final int COL_WIDTH_ALT = 40; + private static final int COL_WIDTH_LISTE_FOURNISSEUR = 90; + private static final int COL_WIDTH_SUIVI_DUREE_DE_VIE = 75; + private static final int COL_WIDTH_SUIVI_UTILISATION = 75; + private static final int COL_WIDTH_CLASSEMENT = 70; + private static final int COL_WIDTH_ARTICLE_GESTION = 90; + private static final int COL_WIDTH_RESPONSABLE_CONCEPTION = 80; + private static final int COL_WIDTH_REFERENCE_ASSOCIEE = 80; + private static final int COL_WIDTH_REFERENCE_TRANSPOSEE = 80; + private static final int COL_WIDTH_REFERENCE_CONCEPTEUR = 140; + private static final int COL_WIDTH_NOM_REFERENCE = 100; + private static final int COL_WIDTH_TYPE_REFERENCE = 134; + private static final int COL_WIDTH_REVISION_REFERENCE = 60; + private static final int COL_WIDTH_REF_FABRICANT = 90; + private static final int COL_WIDTH_SUIVI_MONTAGE = 90; + private static final int COL_WIDTH_RESPONSABLE_REPERE = 80; + private static final int COL_WIDTH_REVISION_REPERE_FONCTIONNEL = 100; + private static final int COL_WIDTH_REPERE_FONCTIONNEL = 90; + private static final int COL_WIDTH_NOM_RECEPTEUR = 140; + private static final int COL_WIDTH_REVISION_RECEPTEUR = 70; + private static final int COL_WIDTH_ID_RECEPTEUR = 80; + private static final int COL_WIDTH_EFFECTIVITY = 170; + + private static final Map MAP_VALUE_WIDTH_COLUMN = getWidthColumn(); + private static final boolean DYNAMIC_HEADER_EXCEPT_EFFECTIVIY = false; + private static final boolean STRETCH_OVER_FLOW = true; + + private final List listParam; + private final Integer numberMaxOfChangeNotice; + private final List headerColumnName; + private final String confTitle1; + private final String confTitle2; + private final String nameSheetTemplate; + + /** + * Builds a template for R07 using pre-computed values: number of CNs, etc. + * + * @param aListParam a List of differences + * @param nbMaxCN the max number of CNs encountered + * @param conf1name the name of conf 1 + * @param conf2name the name of conf 2 + * @param nameSheet the sheet name + */ + public BuilderTemplateR07(final List aListParam, final Integer nbMaxCN, final String conf1name, final String conf2name, + final String nameSheet) { + listParam = aListParam; + numberMaxOfChangeNotice = nbMaxCN; + headerColumnName = getHeaderWithoutChangeColumn(); + confTitle1 = conf1name; + confTitle2 = conf2name; + nameSheetTemplate = nameSheet; + } + + private static List getHeaderFieldWithoutChangeColumn() { + List headers = new ArrayList<>(); + headers.add(EnumRecepteurR07.EFFECTIVITE.toString()); + headers.add(EnumRecepteurR07.ID_RECEPTEUR.toString()); + headers.add(EnumRecepteurR07.REVISION_RECEPTEUR.toString()); + headers.add(EnumRecepteurR07.NOM_RECEPTEUR.toString()); + headers.add(EnumRepereR07.REPERE_FONCTIONNEL.toString()); + headers.add(EnumRepereR07.REVISION_REPERE_FONCTIONNEL.toString()); + headers.add(EnumRepereR07.RESPONSABLE_REPERE.toString()); + headers.add(EnumRepereR07.SUIVI_MONTAGE.toString()); + headers.add(EnumComposantR07.REF_FABRICANT.toString()); + headers.add(EnumComposantR07.REVISION_REFERENCE.toString()); + headers.add(EnumComposantR07.TYPE_REFERENCE.toString()); + headers.add(EnumComposantR07.NOM_REFERENCE.toString()); + headers.add(EnumComposantR07.REFERENCE_CONCEPTEUR.toString()); + headers.add(EnumComposantR07.REFERENCE_TRANSPOSEE.toString()); + headers.add(EnumComposantR07.REFERENCE_ASSOCIEE.toString()); + headers.add(EnumComposantR07.RESPONSABLLE_CONCEPTION.toString()); + headers.add(EnumComposantR07.ARTICLE_GESTION.toString()); + headers.add(EnumComposantR07.CLASSEMENT.toString()); + headers.add(EnumComposantR07.SUIVI_UTILISATION.toString()); + headers.add(EnumComposantR07.SUIVI_DUREE_VIE.toString()); + headers.add(EnumComposantR07.LISTE_FOURNISSEUR.toString()); + headers.add(EnumLienNomenclatureR07.ALT.toString()); + headers.add(EnumLienNomenclatureR07.SUIVANT_BESOIN.toString()); + headers.add(EnumLienNomenclatureR07.QUANTITE_CUMULEE.toString()); + headers.add(EnumLienNomenclatureR07.PANACHAGE.toString()); + headers.add(EnumLienNomenclatureR07.QUANTITE.toString()); + headers.add(EnumChangeR07.ID_CR.toString()); + headers.add(EnumChangeR07.REVISION_CR.toString()); + headers.add(EnumChangeR07.TYPE_CR.toString()); + headers.add(EnumChangeR07.NOM_CR.toString()); + return headers; + } + + private static Map getWidthColumn() { + Map mapWidthColumn = new HashMap<>(); + mapWidthColumn.put(EnumRecepteurR07.EFFECTIVITE.toString(), COL_WIDTH_EFFECTIVITY); + mapWidthColumn.put(EnumRecepteurR07.ID_RECEPTEUR.toString(), COL_WIDTH_ID_RECEPTEUR); + mapWidthColumn.put(EnumRecepteurR07.REVISION_RECEPTEUR.toString(), COL_WIDTH_REVISION_RECEPTEUR); + mapWidthColumn.put(EnumRecepteurR07.NOM_RECEPTEUR.toString(), COL_WIDTH_NOM_RECEPTEUR); + mapWidthColumn.put(EnumRepereR07.REPERE_FONCTIONNEL.toString(), COL_WIDTH_REPERE_FONCTIONNEL); + mapWidthColumn.put(EnumRepereR07.REVISION_REPERE_FONCTIONNEL.toString(), COL_WIDTH_REVISION_REPERE_FONCTIONNEL); + mapWidthColumn.put(EnumRepereR07.RESPONSABLE_REPERE.toString(), COL_WIDTH_RESPONSABLE_REPERE); + mapWidthColumn.put(EnumRepereR07.SUIVI_MONTAGE.toString(), COL_WIDTH_SUIVI_MONTAGE); + mapWidthColumn.put(EnumComposantR07.REF_FABRICANT.toString(), COL_WIDTH_REF_FABRICANT); + mapWidthColumn.put(EnumComposantR07.REVISION_REFERENCE.toString(), COL_WIDTH_REVISION_REFERENCE); + mapWidthColumn.put(EnumComposantR07.TYPE_REFERENCE.toString(), COL_WIDTH_TYPE_REFERENCE); + mapWidthColumn.put(EnumComposantR07.NOM_REFERENCE.toString(), COL_WIDTH_NOM_REFERENCE); + mapWidthColumn.put(EnumComposantR07.REFERENCE_CONCEPTEUR.toString(), COL_WIDTH_REFERENCE_CONCEPTEUR); + mapWidthColumn.put(EnumComposantR07.REFERENCE_TRANSPOSEE.toString(), COL_WIDTH_REFERENCE_TRANSPOSEE); + mapWidthColumn.put(EnumComposantR07.REFERENCE_ASSOCIEE.toString(), COL_WIDTH_REFERENCE_ASSOCIEE); + mapWidthColumn.put(EnumComposantR07.RESPONSABLLE_CONCEPTION.toString(), COL_WIDTH_RESPONSABLE_CONCEPTION); + mapWidthColumn.put(EnumComposantR07.ARTICLE_GESTION.toString(), COL_WIDTH_ARTICLE_GESTION); + mapWidthColumn.put(EnumComposantR07.CLASSEMENT.toString(), COL_WIDTH_CLASSEMENT); + mapWidthColumn.put(EnumComposantR07.SUIVI_UTILISATION.toString(), COL_WIDTH_SUIVI_UTILISATION); + mapWidthColumn.put(EnumComposantR07.SUIVI_DUREE_VIE.toString(), COL_WIDTH_SUIVI_DUREE_DE_VIE); + mapWidthColumn.put(EnumComposantR07.LISTE_FOURNISSEUR.toString(), COL_WIDTH_LISTE_FOURNISSEUR); + mapWidthColumn.put(EnumLienNomenclatureR07.ALT.toString(), COL_WIDTH_ALT); + mapWidthColumn.put(EnumLienNomenclatureR07.SUIVANT_BESOIN.toString(), COL_WIDTH_SUIVANT_BESOIN); + mapWidthColumn.put(EnumLienNomenclatureR07.QUANTITE_CUMULEE.toString(), COL_WIDTH_QUANTITE_CUMULEE); + mapWidthColumn.put(EnumLienNomenclatureR07.PANACHAGE.toString(), COL_WIDTH_PANACHAGE); + mapWidthColumn.put(EnumLienNomenclatureR07.QUANTITE.toString(), COL_WIDTH_QUANTITE); + mapWidthColumn.put(EnumChangeR07.ID_CR.toString(), COL_WIDTH_ID_CR); + mapWidthColumn.put(EnumChangeR07.REVISION_CR.toString(), COL_WIDTH_REVISION_CR); + mapWidthColumn.put(EnumChangeR07.TYPE_CR.toString(), COL_WIDTH_TYPE_CR); + mapWidthColumn.put(EnumChangeR07.NOM_CR.toString(), COL_WIDTH_NOM_CR); + return mapWidthColumn; + } + + /** + * Creates the template. + * + * @return the template file content (.jrxml) + * @throws InvalidInputException if a dynamic table could not be created because of invalid grid size (rows/columns) + * @throws FileLoadingException if unable to load a template file + */ + public String createDynamicTemplate() throws InvalidInputException, FileLoadingException { + List contentCellColumn = createListContentCell(); + List lstWidth = createListWidth(finalWidth(), finalTotalHeader()); + String configurationLine = getBackLineConfiguration(); + Map mapStyle = defineStyleReport(); + DynamicGridTemplateR07 template = new DynamicGridTemplateR07(lstWidth, contentCellColumn, null, listStretchOverFlow(headerColumnName), + listParam, configurationLine, mapStyle, nameSheetTemplate); + template.addHeaderLine(30, headerColumnName, listDynamicHeader(headerColumnName), + new CellFormat().setAlignment(Alignment.CENTER).setBold(true), null); + template.ignorePagination(); + return template.generateCode(); + } + + private List listStretchOverFlow(final List lstHeaderFinal) { + List lstDynamic = new ArrayList<>(); + for (int i = 0; i < lstHeaderFinal.size(); i++) { + lstDynamic.add(STRETCH_OVER_FLOW); + } + return lstDynamic; + } + + private Map defineStyleReport() { + Map mapStyle = new HashMap<>(); + mapStyle.put(EnumRecepteurR07.EFFECTIVITE.toString(), "style_static"); + mapStyle.put(EnumRecepteurR07.ID_RECEPTEUR.toString(), "style_ID_RECEPTEUR"); + mapStyle.put(EnumRecepteurR07.REVISION_RECEPTEUR.toString(), "style_static"); + mapStyle.put(EnumRecepteurR07.NOM_RECEPTEUR.toString(), "style_NOM_RECEPTEUR"); + mapStyle.put(EnumRepereR07.REPERE_FONCTIONNEL.toString(), "style_REPERE_FONCTIONNEL"); + mapStyle.put(EnumRepereR07.REVISION_REPERE_FONCTIONNEL.toString(), "style_static"); + mapStyle.put(EnumRepereR07.RESPONSABLE_REPERE.toString(), "style_RESPONSABLE_REPERE"); + mapStyle.put(EnumRepereR07.SUIVI_MONTAGE.toString(), "style_SUIVI_MONTAGE"); + mapStyle.put(EnumComposantR07.REF_FABRICANT.toString(), "style_REF_FABRICANT"); + mapStyle.put(EnumComposantR07.REVISION_REFERENCE.toString(), "style_static"); + mapStyle.put(EnumComposantR07.TYPE_REFERENCE.toString(), "style_TYPE_REFERENCE"); + mapStyle.put(EnumComposantR07.NOM_REFERENCE.toString(), "style_NOM_REFERENCE"); + mapStyle.put(EnumComposantR07.REFERENCE_CONCEPTEUR.toString(), "style_REFERENCE_CONCEPTEUR"); + mapStyle.put(EnumComposantR07.REFERENCE_TRANSPOSEE.toString(), "style_REFERENCE_TRANSPOSEE"); + mapStyle.put(EnumComposantR07.REFERENCE_ASSOCIEE.toString(), "style_REFERENCE_ASSOCIEE"); + mapStyle.put(EnumComposantR07.RESPONSABLLE_CONCEPTION.toString(), "style_RESPONSABLLE_CONCEPTION"); + mapStyle.put(EnumComposantR07.ARTICLE_GESTION.toString(), "style_ARTICLE_GESTION"); + mapStyle.put(EnumComposantR07.CLASSEMENT.toString(), "style_CLASSEMENT"); + mapStyle.put(EnumComposantR07.SUIVI_UTILISATION.toString(), "style_SUIVI_UTILISATION"); + mapStyle.put(EnumComposantR07.SUIVI_DUREE_VIE.toString(), "style_SUIVI_DUREE_VIE"); + mapStyle.put(EnumComposantR07.LISTE_FOURNISSEUR.toString(), "style_LISTE_FOURNISSEUR"); + mapStyle.put(EnumLienNomenclatureR07.ALT.toString(), "style_ALT"); + mapStyle.put(EnumLienNomenclatureR07.SUIVANT_BESOIN.toString(), "style_SUIVI_BESOIN"); + mapStyle.put(EnumLienNomenclatureR07.QUANTITE_CUMULEE.toString(), "style_QUANTITE_CUMULEE"); + mapStyle.put(EnumLienNomenclatureR07.PANACHAGE.toString(), "style_PANACHAGE"); + mapStyle.put(EnumLienNomenclatureR07.QUANTITE.toString(), "style_QUANTITE"); + mapStyle.put(EnumChangeR07.ID_CR.toString(), "style_static"); + mapStyle.put(EnumChangeR07.REVISION_CR.toString(), "style_static"); + mapStyle.put(EnumChangeR07.TYPE_CR.toString(), "style_static"); + mapStyle.put(EnumChangeR07.NOM_CR.toString(), "style_static"); + for (int i = 0; i < numberMaxOfChangeNotice; i++) { + mapStyle.put(EnumChangeR07.ID_CN.toString() + "_" + (i + 1), "style_static"); + mapStyle.put(EnumChangeR07.REVISION_CN.toString() + "_" + (i + 1), "style_static"); + mapStyle.put(EnumChangeR07.TYPE_CN.toString() + "_" + (i + 1), "style_static"); + mapStyle.put(EnumChangeR07.NOM_CN.toString() + "_" + (i + 1), "style_static"); + } + return mapStyle; + } + + private List createListContentCell() { + List contentCellColumn = getHeaderFieldWithoutChangeColumn(); + List lstColumnChangeNotice = createColumnFieldChangeNotice(); + for (String aLstColumnChangeNotice : lstColumnChangeNotice) { + contentCellColumn.add(aLstColumnChangeNotice); + } + return contentCellColumn; + } + + private List createColumnFieldChangeNotice() { + List lstColumnChangeNotice = new ArrayList<>(); + for (int i = 0; i < numberMaxOfChangeNotice; i++) { + lstColumnChangeNotice.add(EnumChangeR07.ID_CN.toString() + "_" + (i + 1)); + lstColumnChangeNotice.add(EnumChangeR07.REVISION_CN.toString() + "_" + (i + 1)); + lstColumnChangeNotice.add(EnumChangeR07.TYPE_CN.toString() + "_" + (i + 1)); + lstColumnChangeNotice.add(EnumChangeR07.NOM_CN.toString() + "_" + (i + 1)); + } + return lstColumnChangeNotice; + } + + private List listDynamicHeader(final List lstHeaderFinal) { + List lstDynamic = new ArrayList<>(); + for (int i = 0; i < lstHeaderFinal.size(); i++) { + lstDynamic.add(DYNAMIC_HEADER_EXCEPT_EFFECTIVIY); + } + return lstDynamic; + } + + private String getBackLineConfiguration() { + return EnumChangeR07.CONFIGURATION_CONCERNED.toString(); + } + + private List getHeaderWithoutChangeColumn() { + List lstHeader = new ArrayList<>(); + lstHeader.add("Effectivité"); + lstHeader.add("Identifiant récepteur"); + lstHeader.add("Révision récepteur"); + lstHeader.add("Nom récepteur"); + lstHeader.add("Repère fonctionnel"); + lstHeader.add("Révision repère fonctionnel"); + lstHeader.add("Responsable repère"); + lstHeader.add("Suivi montage"); + lstHeader.add("Ref. Fabricant / Ref. Snecma"); + lstHeader.add("Révision référence"); + lstHeader.add("Type référence"); + lstHeader.add("Nom référence"); + lstHeader.add("Référence concepteur"); + lstHeader.add("Référence transposée"); + lstHeader.add("Référence associée"); + lstHeader.add("Responsable conception"); + lstHeader.add("Article de gestion"); + lstHeader.add("Classement"); + lstHeader.add("Suivi utilisation"); + lstHeader.add("Suivi durée de vie"); + lstHeader.add("Liste fournisseur(s) validé(s)"); + lstHeader.add("ALT"); + lstHeader.add("SB (Suivant Besoin)"); + lstHeader.add("Quantité cumulée"); + lstHeader.add("Panachage"); + lstHeader.add("Quantité"); + lstHeader.add("Identifiant ChangeRequest"); + lstHeader.add("Révision ChangeRequest"); + lstHeader.add("Type ChangeRequest"); + lstHeader.add("Nom ChangeRequest"); + List lstHeadChange = createColumnChangeNotice(); + for (int i = 0; i < numberMaxOfChangeNotice; i++) { + for (String aLstHeadChange : lstHeadChange) { + lstHeader.add(aLstHeadChange); + } + } + return lstHeader; + } + + private List createColumnChangeNotice() { + List lstColumnChangeNotice = new ArrayList<>(); + lstColumnChangeNotice.add("Identifiant ChangeNotice"); + lstColumnChangeNotice.add("Révision ChangeNotice"); + lstColumnChangeNotice.add("Type ChangeNotice"); + lstColumnChangeNotice.add("Nom ChangeNotice"); + return lstColumnChangeNotice; + } + + private List finalTotalHeader() { + List lstHeader = getHeaderFieldWithoutChangeColumn(); + List lstColumnChangeNotice = createColumnFieldChangeNotice(); + for (String aLstColumnChangeNotice : lstColumnChangeNotice) { + lstHeader.add(aLstColumnChangeNotice); + } + return lstHeader; + } + + private Map finalWidth() { + Map mapWidthColumn = MAP_VALUE_WIDTH_COLUMN; + for (int i = 0; i < numberMaxOfChangeNotice; i++) { + mapWidthColumn.put(EnumChangeR07.ID_CN.toString() + "_" + (i + 1), COL_WIDTH_ID_CN); + mapWidthColumn.put(EnumChangeR07.REVISION_CN.toString() + "_" + (i + 1), COL_WIDTH_REVISION_CN); + mapWidthColumn.put(EnumChangeR07.TYPE_CN.toString() + "_" + (i + 1), COL_WIDTH_TYPE_CN); + mapWidthColumn.put(EnumChangeR07.NOM_CN.toString() + "_" + (i + 1), COL_WIDTH_NOM_CN); + } + return mapWidthColumn; + } + + private List createListWidth(final Map mapWidth, final List headers) { + List lstWidth = new ArrayList<>(); + for (String header : headers) { + for (String valKey : mapWidth.keySet()) { + if (valKey.equals(header)) { + lstWidth.add(mapWidth.get(header)); + break; + } + } + } + return lstWidth; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/DynamicGridTemplateR07.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/DynamicGridTemplateR07.java new file mode 100644 index 0000000..c8874f8 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/DynamicGridTemplateR07.java @@ -0,0 +1,250 @@ +package com.capgemini.reports.definition.r07report.printing; + +import com.capgemini.framework.common.ResourceHelper; +import com.capgemini.reports.exceptions.FileLoadingException; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.templates.CellFormat; +import com.capgemini.reports.templates.Column; +import com.capgemini.reports.templates.DynamicGridTemplateBuilder; + +import java.util.List; +import java.util.Map; + +/** + * Create a dynamic template for the report 07. + */ +public class DynamicGridTemplateR07 extends DynamicGridTemplateBuilder { + private static final int CENTENT_HEIGHT_PX = 13; + private static final int TITLE_HEIGHT_PX = 45; + private static final String BLACK = "#000000\""; + private static final String FORECOLOR = " forecolor=\""; + private static final String BACKCOLOR_WHITE = " backcolor = \"#FFFFFF\" "; + private static final String BACKCOLOR_YELLOW = " backcolor = \"#FFFF00\" "; + private static final String EMPTY_STRING = ""; + private static final String COULEUR_CONFIGURATION_2 = "#FF0000"; + private static final String COULEUR_CONFIGURATION_1 = "#0000FF"; + private static final String TITLE_FIRST_CONFIGURATION = "TITLE_FIRST_CONFIGURATION"; + private static final String TITLE_SECOND_CONFIGURATION = "TITLE_SECOND_CONFIGURATION"; + private final List find; + private final String config; + private final List sizeColumn; + private final Map mapStyle; + private final String nameSheet; + + /** + * Builds a template for the R07 report. + * + * @param widths the column widths + * @param contentKeys the KEYs to the cell's content + * @param formats the cell formats + * @param stretchWithOverFlow stretch with overflow? + * @param findDifference a list of differences found + * @param configNum the number iterated through the conf + * @param aMapStyle a Style map + * @param nameSheetTemplate a spreadsheet template name + * @throws FileLoadingException if unable to load template file + * @throws InvalidInputException if inputs are incorrect (non-matching List sizes) + */ + public DynamicGridTemplateR07(final List widths, final List contentKeys, final List formats, + final List stretchWithOverFlow, final List findDifference, final String configNum, + final Map aMapStyle, final String nameSheetTemplate) throws FileLoadingException, InvalidInputException { + super(widths, contentKeys, formats, stretchWithOverFlow, CENTENT_HEIGHT_PX); + this.sizeColumn = widths; + this.find = findDifference; + this.config = configNum; + this.mapStyle = aMapStyle; + this.heigthTitle = TITLE_HEIGHT_PX; + this.listElementTitle.add(TITLE_FIRST_CONFIGURATION); + this.listElementTitle.add(TITLE_SECOND_CONFIGURATION); + this.nameSheet = nameSheetTemplate; + this.setTemplateContent(ResourceHelper.getResourceContent("/Jasper/template/template_R07.jrxml")); + } + + private StringBuilder getFieldOption() { + StringBuilder stringBuilder = new StringBuilder(200); + for (String aFind : find) { + stringBuilder.append("\n "); + } + stringBuilder.append("\n "); + return stringBuilder; + } + + @Override + public String generateCode() { + defineColumnStyle(); + makeAligment(); + nameSheetDeclaration = nameSheet; + propertyDeclaration = makePropertyDeclaration(); + fieldsDeclaration = getFieldOption(); + contentStyle = makeStyle(this.columns); + parametersDeclaration = makeParamTitle(); + titleDeclaration = makeTitle(); + + super.setTagValue(TITLE, titleDeclaration.toString()); + super.setTagValue(TITLE_HEIGHT, String.valueOf(heigthTitle)); + super.setTagValue(NAME_SHEET, nameSheetDeclaration); + super.setTagValue(PROPERTY, propertyDeclaration.toString()); + super.setTagValue(STYLE, contentStyle.toString()); + return super.generateCode(); + } + + private StringBuilder makePropertyDeclaration() { + return new StringBuilder("\n"); + } + + private StringBuilder makeParamTitle() { + StringBuilder stringBuilder = new StringBuilder(); + for (String aListElementTitle : listElementTitle) { + stringBuilder.append(BEGIN_PARAM).append(aListElementTitle).append(END_PARAM); + + } + return stringBuilder; + } + + private StringBuilder makeTitle() { + StringBuilder stringBuilder = new StringBuilder(); + int sizeTitle = 0; + int yPos = 0; + int xPos = 0; + int size = 0; + for (int i = 0; i < 4; i++) { + sizeTitle += sizeColumn.get(i); + } + for (String aListElementTitle : listElementTitle) { + stringBuilder.append("\n \n").append(BEGIN_VARIABLE_PARAM_DATA).append(aListElementTitle) + .append("}]]>\n \n"); + xPos = sizeTitle; + for (int i = 4; i < sizeColumn.size(); i++) { + stringBuilder.append("\n \n\"").append(EMPTY_STRING) + .append("\"\n"); + xPos += sizeColumn.get(i); + } + yPos += 15; + } + for (Integer aSizeColumn : sizeColumn) { + stringBuilder.append(" \n \n\"").append(EMPTY_STRING).append("\"\n"); + size += aSizeColumn; + } + return stringBuilder; + } + + private StringBuilder makeStyle(final List column) { + StringBuilder stringBuilder = new StringBuilder(); + boolean findStyleStatic = false; + int staticStyleFind = 0; + for (int i = 0; i < column.size(); i++) { + if ("style_static".equals(column.get(i).getField().getNameStyle())) { + staticStyleFind++; + if (!findStyleStatic) { + stringBuilder.append(BEGIN_STYLE).append(column.get(i).getField().getNameStyle()).append('\"').append(END_STYLE).append('\n') + .append(BEGIN_CONDITIONAL_STYLE).append(BEGIN_CONDITIONAL_EXPRESSION).append(BEGIN_VARIABLE_DATA_FALSE_BOOLEAN) + .append(find.get(find.size() - 1)).append('}').append(MULTIPLE_CONDITIONAL_INCLUSIF) + .append(BEGIN_VARIABLE_FUNCTION_FALSE_BOOLEAN).append(config).append("}]]>").append(END_CONDITIONAL_EXPRESSION) + .append(BEGIN_STYLE_MODE).append("\"Opaque\"").append(BACKCOLOR_WHITE).append(FORECOLOR + COULEUR_CONFIGURATION_2 + '\"') + .append(END_STYLE).append(BEGIN_BOX).append(TOP_PEN).append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR).append(BLACK) + .append(END).append(LEFT_PEN).append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR).append(BLACK).append(END) + .append(BOTTOM_PEN).append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR).append(BLACK).append(END).append(RIGHT_PEN) + .append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR).append(BLACK).append(END).append(END_BOX).append(END_STYLE_MODE) + .append(END_CONDITIONAL_STYLE).append(BEGIN_CONDITIONAL_STYLE).append(BEGIN_CONDITIONAL_EXPRESSION) + .append(BEGIN_VARIABLE_DATA_FALSE_BOOLEAN).append(find.get(find.size() - 1)).append('}') + .append(MULTIPLE_CONDITIONAL_INCLUSIF).append(BEGIN_VARIABLE_FUNCTION).append(config).append("}]]>") + .append(END_CONDITIONAL_EXPRESSION).append(BEGIN_STYLE_MODE).append("\"Opaque\"").append(BACKCOLOR_WHITE) + .append(FORECOLOR + COULEUR_CONFIGURATION_1 + "\"").append(END_STYLE).append(BEGIN_BOX).append(TOP_PEN).append(LINE_WIDTH) + .append("0.5\"").append(LINE_COLOR).append(BLACK).append(END).append(LEFT_PEN).append(LINE_WIDTH).append("0.5\"") + .append(LINE_COLOR).append(BLACK).append(END).append(BOTTOM_PEN).append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR) + .append(BLACK).append(END).append(RIGHT_PEN).append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR).append(BLACK) + .append(END).append(END_BOX).append(END_STYLE_MODE).append(END_CONDITIONAL_STYLE).append(BEGIN_CONDITIONAL_STYLE) + .append(BEGIN_CONDITIONAL_EXPRESSION).append(BEGIN_VARIABLE_DATA).append(find.get(find.size() - 1)).append('}') + .append(MULTIPLE_CONDITIONAL_INCLUSIF).append(BEGIN_VARIABLE_FUNCTION_FALSE_BOOLEAN).append(config).append("}]]>") + .append(END_CONDITIONAL_EXPRESSION).append(BEGIN_STYLE_MODE).append("\"Opaque\"").append(BACKCOLOR_YELLOW) + .append(FORECOLOR + COULEUR_CONFIGURATION_2 + "\"").append(END_STYLE).append(BEGIN_BOX).append(TOP_PEN).append(LINE_WIDTH) + .append("0.5\"").append(LINE_COLOR).append(BLACK).append(END).append(LEFT_PEN).append(LINE_WIDTH).append("0.5\"") + .append(LINE_COLOR).append(BLACK).append(END).append(BOTTOM_PEN).append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR) + .append(BLACK).append(END).append(RIGHT_PEN).append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR).append(BLACK) + .append(END).append(END_BOX).append(END_STYLE_MODE).append(END_CONDITIONAL_STYLE).append(BEGIN_CONDITIONAL_STYLE) + .append(BEGIN_CONDITIONAL_EXPRESSION).append(BEGIN_VARIABLE_DATA).append(find.get(find.size() - 1)).append('}') + .append(MULTIPLE_CONDITIONAL_INCLUSIF).append(BEGIN_VARIABLE_FUNCTION).append(config).append("}]]>") + .append(END_CONDITIONAL_EXPRESSION).append(BEGIN_STYLE_MODE).append("\"Opaque\"").append(BACKCOLOR_YELLOW) + .append(FORECOLOR).append(COULEUR_CONFIGURATION_1).append('\"').append(END_STYLE).append(BEGIN_BOX).append(TOP_PEN) + .append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR).append(BLACK).append(END).append(LEFT_PEN).append(LINE_WIDTH) + .append("0.5\"").append(LINE_COLOR).append(BLACK).append(END).append(BOTTOM_PEN).append(LINE_WIDTH).append("0.5\"") + .append(LINE_COLOR).append(BLACK).append(END).append(RIGHT_PEN).append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR) + .append(BLACK).append(END).append(END_BOX).append(END_STYLE_MODE).append(END_CONDITIONAL_STYLE).append(END_STYLE_FIRST); + findStyleStatic = true; + } + } else { + stringBuilder.append(BEGIN_STYLE).append(column.get(i).getField().getNameStyle()).append('\"').append(END_STYLE).append('\n') + .append(BEGIN_CONDITIONAL_STYLE).append(BEGIN_CONDITIONAL_EXPRESSION).append(BEGIN_VARIABLE_DATA_FALSE_BOOLEAN_CONDITION) + .append(find.get(find.size() - 1)).append('}').append(MULTIPLE_CONDITIONAL_INCLUSIF) + .append(BEGIN_VARIABLE_FUNCTION_FALSE_BOOLEAN).append(find.get(i - staticStyleFind)).append("}) ") + .append(MULTIPLE_CONDITIONAL_INCLUSIF).append(BEGIN_VARIABLE_FUNCTION_FALSE_BOOLEAN).append(config).append("}]]>") + .append(END_CONDITIONAL_EXPRESSION).append(BEGIN_STYLE_MODE).append("\"Opaque\"").append(BACKCOLOR_WHITE) + .append(FORECOLOR + COULEUR_CONFIGURATION_2 + "\"").append(END_STYLE).append(BEGIN_BOX).append(TOP_PEN).append(LINE_WIDTH) + .append("0.5\"").append(LINE_COLOR).append(BLACK).append(END).append(LEFT_PEN).append(LINE_WIDTH).append("0.5\"") + .append(LINE_COLOR).append(BLACK).append(END).append(BOTTOM_PEN).append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR) + .append(BLACK).append(END).append(RIGHT_PEN).append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR).append(BLACK).append(END) + .append(END_BOX).append(END_STYLE_MODE).append(END_CONDITIONAL_STYLE).append(BEGIN_CONDITIONAL_STYLE) + .append(BEGIN_CONDITIONAL_EXPRESSION).append(BEGIN_VARIABLE_DATA_FALSE_BOOLEAN_CONDITION).append(find.get(find.size() - 1)) + .append('}').append(MULTIPLE_CONDITIONAL_INCLUSIF).append(BEGIN_VARIABLE_FUNCTION_FALSE_BOOLEAN) + .append(find.get(i - staticStyleFind)).append("}) ").append(MULTIPLE_CONDITIONAL_INCLUSIF).append(BEGIN_VARIABLE_FUNCTION) + .append(config).append("}]]>").append(END_CONDITIONAL_EXPRESSION).append(BEGIN_STYLE_MODE).append("\"Opaque\"") + .append(BACKCOLOR_WHITE).append(FORECOLOR + COULEUR_CONFIGURATION_1 + '\"').append(END_STYLE).append(BEGIN_BOX) + .append(TOP_PEN).append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR).append(BLACK).append(END).append(LEFT_PEN) + .append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR).append(BLACK).append(END).append(BOTTOM_PEN).append(LINE_WIDTH) + .append("0.5\"").append(LINE_COLOR).append(BLACK).append(END).append(RIGHT_PEN).append(LINE_WIDTH).append("0.5\"") + .append(LINE_COLOR).append(BLACK).append(END).append(END_BOX).append(END_STYLE_MODE).append(END_CONDITIONAL_STYLE) + .append(BEGIN_CONDITIONAL_STYLE).append(BEGIN_CONDITIONAL_EXPRESSION).append(BEGIN_VARIABLE_DATA_CONDITION) + .append(find.get(find.size() - 1)).append('}').append(MULTIPLE_CONDITIONAL_EXCLUSIF).append(BEGIN_VARIABLE_FUNCTION) + .append(find.get(i - staticStyleFind)).append("}) ").append(MULTIPLE_CONDITIONAL_INCLUSIF) + .append(BEGIN_VARIABLE_FUNCTION_FALSE_BOOLEAN).append(config).append("}]]>").append(END_CONDITIONAL_EXPRESSION) + .append(BEGIN_STYLE_MODE).append("\"Opaque\"").append(BACKCOLOR_YELLOW).append(FORECOLOR + COULEUR_CONFIGURATION_2 + '\"') + .append(END_STYLE).append(BEGIN_BOX).append(TOP_PEN).append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR).append(BLACK) + .append(END).append(LEFT_PEN).append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR).append(BLACK).append(END) + .append(BOTTOM_PEN).append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR).append(BLACK).append(END).append(RIGHT_PEN) + .append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR).append(BLACK).append(END).append(END_BOX).append(END_STYLE_MODE) + .append(END_CONDITIONAL_STYLE).append(BEGIN_CONDITIONAL_STYLE).append(BEGIN_CONDITIONAL_EXPRESSION) + .append(BEGIN_VARIABLE_DATA_CONDITION).append(find.get(find.size() - 1)).append('}').append(MULTIPLE_CONDITIONAL_EXCLUSIF) + .append(BEGIN_VARIABLE_FUNCTION).append(find.get(i - staticStyleFind)).append("}) ").append(MULTIPLE_CONDITIONAL_INCLUSIF) + .append(BEGIN_VARIABLE_FUNCTION).append(config).append("}]]>").append(END_CONDITIONAL_EXPRESSION).append(BEGIN_STYLE_MODE) + .append("\"Opaque\"").append(BACKCOLOR_YELLOW).append(FORECOLOR + COULEUR_CONFIGURATION_1 + '\"').append(END_STYLE) + .append(BEGIN_BOX).append(TOP_PEN).append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR).append(BLACK).append(END) + .append(LEFT_PEN).append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR).append(BLACK).append(END).append(BOTTOM_PEN) + .append(LINE_WIDTH).append("0.5\"").append(LINE_COLOR).append(BLACK).append(END).append(RIGHT_PEN).append(LINE_WIDTH) + .append("0.5\"").append(LINE_COLOR).append(BLACK).append(END).append(END_BOX).append(END_STYLE_MODE) + .append(END_CONDITIONAL_STYLE).append(END_STYLE_FIRST); + } + } + + return stringBuilder; + + } + + private void makeAligment() { + for (Column column : this.columns) { + column.getHeaders().get(0).getFormat().setAlignment("Middle\""); + } + } + + /** + * Allow to associate a style with a column : every column has his own style(except effectivity , revision , CR and CN). + */ + private void defineColumnStyle() { + for (Column column : this.columns) { + if (mapStyle.containsKey(column.getField().getContent())) { + column.getField().setNameStyle(mapStyle.get(column.getField().getContent())); + } else { + column.getField().setNameStyle(null); + } + for (int i = 0; i < column.getHeaders().size(); i++) { + if (mapStyle.containsKey(column.getHeaders().get(i).getContent())) { + column.getHeaders().get(i).setNameStyle(mapStyle.get(column.getHeaders().get(i).getContent())); + } else { + column.getHeaders().get(i).setNameStyle(null); + } + } + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/EnumChangeR07.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/EnumChangeR07.java new file mode 100644 index 0000000..6cd9aa4 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/EnumChangeR07.java @@ -0,0 +1,18 @@ +package com.capgemini.reports.definition.r07report.printing; + +/** + * Enum listing all the keys related to ChangeRequests and ChangeNotices in the R07. + */ +public enum EnumChangeR07 { + ID_CR, + REVISION_CR, + TYPE_CR, + NOM_CR, + CONFIGURATION_CONCERNED, + TITLE_FIRST_CONFIGURATION, + TITLE_SECOND_CONFIGURATION, + ID_CN, + REVISION_CN, + TYPE_CN, + NOM_CN +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/EnumComposantR07.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/EnumComposantR07.java new file mode 100644 index 0000000..fed6d61 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/EnumComposantR07.java @@ -0,0 +1,20 @@ +package com.capgemini.reports.definition.r07report.printing; + +/** + * Enum listing all the keys related to Components in the R07. + */ +public enum EnumComposantR07 { + REF_FABRICANT, + REVISION_REFERENCE, + TYPE_REFERENCE, + NOM_REFERENCE, + REFERENCE_CONCEPTEUR, + REFERENCE_TRANSPOSEE, + REFERENCE_ASSOCIEE, + RESPONSABLLE_CONCEPTION, + ARTICLE_GESTION, + CLASSEMENT, + SUIVI_UTILISATION, + SUIVI_DUREE_VIE, + LISTE_FOURNISSEUR +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/EnumLienNomenclatureR07.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/EnumLienNomenclatureR07.java new file mode 100644 index 0000000..de8887e --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/EnumLienNomenclatureR07.java @@ -0,0 +1,12 @@ +package com.capgemini.reports.definition.r07report.printing; + +/** + * Enum listing all the keys related to Bom data in the R07. + */ +public enum EnumLienNomenclatureR07 { + ALT, + SUIVANT_BESOIN, + QUANTITE_CUMULEE, + PANACHAGE, + QUANTITE +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/EnumMapDelta.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/EnumMapDelta.java new file mode 100644 index 0000000..fb8b727 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/EnumMapDelta.java @@ -0,0 +1,30 @@ +package com.capgemini.reports.definition.r07report.printing; + +/** + * Enum listing all the keys that mark if a column has a diff between conf1 and conf2, in the R07. + */ +public enum EnumMapDelta { + REF_FABRICANT_ECART, + TYPE_REFERENCE_ECART, + NOM_REFERENCE_ECART, + REFERENCE_CONCEPTEUR_ECART, + REFERENCE_TRANSPOSEE_ECART, + REFERENCE_ASSOCIEE_ECART, + RESPONSABLE_CONCEPTION_ECART, + ARTICLE_GESTION_ECART, + CLASSEMENT_ECART, + SUIVI_UTILISATION_ECART, + SUIVI_DUREE_VIE_ECART, + LISTE_FOURNISSEUR_ECART, + ALT_ECART, + SUIVI_BESOIN_ECART, + QUANTITE_CUMULEE_ECART, + PANACHAGE_ECART, + QUANTITE_ECART, + ID_RECEPTEUR_ECART, + NOM_RECEPTEUR_ECART, + REPERE_FONCTIONNEL_ECART, + RESPONSABLE_REPERE_ECART, + SUIVI_MONTAGE_ECART, + ALL_LINE_DIFFERENCE +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/EnumRecepteurR07.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/EnumRecepteurR07.java new file mode 100644 index 0000000..ed9850a --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/EnumRecepteurR07.java @@ -0,0 +1,11 @@ +package com.capgemini.reports.definition.r07report.printing; + +/** + * Enum listing all the keys related to Receptors in the R07. + */ +public enum EnumRecepteurR07 { + EFFECTIVITE, + ID_RECEPTEUR, + REVISION_RECEPTEUR, + NOM_RECEPTEUR +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/EnumRepereR07.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/EnumRepereR07.java new file mode 100644 index 0000000..46d0e90 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r07report/printing/EnumRepereR07.java @@ -0,0 +1,11 @@ +package com.capgemini.reports.definition.r07report.printing; + +/** + * Enum listing all the keys related to Repere data in the R07. + */ +public enum EnumRepereR07 { + REPERE_FONCTIONNEL, + REVISION_REPERE_FONCTIONNEL, + RESPONSABLE_REPERE, + SUIVI_MONTAGE +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/DataReportPreparatorR10.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/DataReportPreparatorR10.java new file mode 100644 index 0000000..4675aee --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/DataReportPreparatorR10.java @@ -0,0 +1,127 @@ +package com.capgemini.reports.definition.r10report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoSuchBomViewException; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObjectFactory; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRule; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRuleProperties; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.product.TcProduct; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindow; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindowConfiguration; +import com.capgemini.framework.teamcenter.object.runtime.TcRevisionRulesConfiguration; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderFactory; +import com.capgemini.reports.definition.r10report.ExecutionR10.ReportDataR10; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.MalformedNomenclatureException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.filter.AllIsGoodFilter; +import com.capgemini.reports.filter.FilterExcludeByType; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.reports.parameters.MonoMulti; +import com.capgemini.reports.teamcenter.resolution.structureservice.IStructureServiceCaller; +import com.capgemini.reports.teamcenter.resolution.structureservice.MultiStructureServiceCaller; +import com.capgemini.reports.teamcenter.resolution.structureservice.TripleStructureServiceCaller; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.BOMLine; +import com.teamcenter.soa.client.model.strong.Form; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * This class will allow to prepare data and findAll back data for making report R10. + */ +public class DataReportPreparatorR10 implements IDataReportPreparator { + private static final long serialVersionUID = 9204365823895275478L; + private static final Logger LOGGER = LoggerFactory.getLogger(DataReportPreparatorR10.class); + + private static final FilterExcludeByType FILTER_MOCKUP_GEOMETRY = new FilterExcludeByType("Mockup Revision", "Geometry Revision"); // Mockup Revision and Geometry Revision can be found in a BOM, but are not needed + + @Override + public String print(TcSession session, ExecutionR10 execution, IExecutionStrategy executionStrategy) throws KurtException { + PrintParameters printParameters = prepareData(session, execution); + executionStrategy.print(printParameters, execution); + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + } + + private PrintParameters prepareData(final TcSession session, final ExecutionR10 report) throws KurtException { + LOGGER.debug("PrepareData started on: {}", report.getReportIdentifier().getReportTitle()); + + TcBomObject topLineObject = new TcBomObjectFactory(session, report.getGenerics().getItem(session)).create(); + TcProduct productObject = new TcProduct(session, report.getGenerics().getProductUnit().getProduct(session)); + int unit = report.getGenerics().getProductUnit().getUnit(); + EffectivityDate effectivityDate = report.getEffectivityDate(); + + TcRevisionRuleProperties revisionRuleProperties = new TcRevisionRuleProperties(productObject, unit, effectivityDate.isNow() ? null : effectivityDate.getDateTime()); + + TcRevisionRule revisionRule = session.findRevRule(report.getRevisionRule()); + TcRevisionRulesConfiguration revRulesConfiguration = new TcRevisionRulesConfiguration(revisionRule, revisionRuleProperties); + + try (TcBomWindow bomWindow = session.createBomWindow(new TcBomWindowConfiguration(topLineObject, revRulesConfiguration))) { + session.setObjectPropPolicy(report.getFullPolicy()); + + // Explode the structure + BOMLineHolder unbuiltTopLine = explode(session, bomWindow.topLine(), report); + + List itemRevMaster = unbuiltTopLine.getAllItemRevMasters(); + session.loadProperties(itemRevMaster.toArray(new ModelObject[itemRevMaster.size()])); + + // build the BomLine + BOMLineHolderFactory.buildTopBom(session, unbuiltTopLine, FILTER_MOCKUP_GEOMETRY); + + // Freeze after processing + unbuiltTopLine.freeze(); + ReportDataR10 dataR10 = new ReportDataR10(unbuiltTopLine); + + R10Printer printer = new R10Printer(report.getEffectivityDate().isNow() ? null : report.getEffectivityDate().getDateTime()); + PrintParameters printParameters = printer.makeMasterTemplate(report, dataR10); + printer.constructDataMaps(session, printParameters, dataR10); + + LOGGER.debug("PrepareData ended on: {}", report.getReportIdentifier().getReportTitle()); + return printParameters; + } catch (EmptyNomenclatureException e) { + switch (report.getGenerics().getType()) { + case GENERIC: + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_PRODUCT_AND_UNIT, e); + case GENERIC_ASSEMB: + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_ASSEMB_PRODUCT_AND_UNIT, e); + default: + throw new KurtException("The TC Nomenclature Resolution returned null", e); + } + } + } + + private BOMLineHolder explode(final TcSession session, final BOMLine topBomLine, final ExecutionR10 report) + throws InvalidInputException, MalformedNomenclatureException { + IStructureServiceCaller service; + if (MonoMulti.MONO.equals(report.getMonoMulti())) { + service = new TripleStructureServiceCaller(session); + } else { + service = new MultiStructureServiceCaller(session); + } + + try { + return service.resolve(topBomLine, new AllIsGoodFilter()); + } catch (EmptyNomenclatureException e) { + switch (report.getGenerics().getType()) { + case GENERIC: + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_PRODUCT_AND_UNIT, e); + case GENERIC_ASSEMB: + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_ASSEMB_PRODUCT_AND_UNIT, e); + default: + throw new InvalidInputException("The TC Nomenclature Resolution returned null", e); + } + } catch (NoSuchBomViewException e) { + throw new InvalidInputException("No such Bom View", e); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/DocumentExtractor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/DocumentExtractor.java new file mode 100644 index 0000000..3c1c9bb --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/DocumentExtractor.java @@ -0,0 +1,257 @@ +package com.capgemini.reports.definition.r10report; + +import com.capgemini.framework.common.LanguageHelper; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.framework.teamcenter.object.pom.status.TcReleaseStatus; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.resolution.filtering.TcTypeInclusionFilter; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderHelper; +import com.capgemini.reports.definition.r10report.lines.*; +import com.capgemini.reports.documentationobjects.*; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.MalformedNomenclatureException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.releasestatus.DefaultRevisionSelector; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import lombok.extern.slf4j.Slf4j; + +import java.util.*; + +import static com.capgemini.framework.teamcenter.object.pom.status.StatusEnum.FROZEN; +import static com.capgemini.framework.teamcenter.object.pom.status.StatusEnum.PUBLISHED; +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.*; + +/** + * Extracts documents' Revision from their Master, stores their status in a Map. + */ +@Slf4j +public class DocumentExtractor implements IDocVisitor> { + + private static final String TYPE_DEFINITION_DOCUMENTS = "Definition documents"; + private static final String TYPE_REFERENCE_DOCUMENTS = "Reference documents"; + private final Calendar effectivityDate; + private final Map docCache; + + public DocumentExtractor(final Calendar effectivityDate, final Map docCache) { + this.effectivityDate = effectivityDate; + this.docCache = docCache; + } + + private static List> noDocuments() { + List> list = new ArrayList<>(); + Map emptyDoc = new EnumMap<>(R10Keys.class); + emptyDoc.put(R10Keys.DOC_CREATION_DATE, StringHelper.EMPTY); + emptyDoc.put(R10Keys.DOC_ID, StringHelper.EMPTY); + emptyDoc.put(R10Keys.DOC_INDEX, StringHelper.EMPTY); + emptyDoc.put(R10Keys.DOC_LINK_TYPE, StringHelper.EMPTY); + emptyDoc.put(R10Keys.DOC_NAME, StringHelper.EMPTY); + emptyDoc.put(R10Keys.DOC_NAME_ENG, StringHelper.EMPTY); + emptyDoc.put(R10Keys.DOC_REVISION, StringHelper.EMPTY); + emptyDoc.put(R10Keys.DOC_STATUS, StringHelper.EMPTY); + emptyDoc.put(R10Keys.DOC_TYPE, StringHelper.EMPTY); + list.add(emptyDoc); + return list; + } + + /** + * Extract the content of each Document of a {@link R10ProductGeneric}. + * + * @param r10ProductGeneric the product/Generic line (the Generic holds the Documents) + * @return a {@link List} of {@link Map}s + * @throws MalformedNomenclatureException if nomenclature is not well-defined + * @throws NotFoundException if no descriptif is found below the RfGeneric of the Generic + * @throws InvalidInputException if generic bomLine is null + */ + public List> extract(final R10ProductGeneric r10ProductGeneric) throws MalformedNomenclatureException, NotFoundException, InvalidInputException { + // For generics, a Descriptif can be found as a bom Child, which owns some pseudo-folders containing the documents + BOMLineHolder genericComponent = r10ProductGeneric.getGenericComponentBL(); + return extractDocsFromGeneric(genericComponent); + } + + /** + * Extract the content of each Document of a {@link R10PartRfPart}. + * + * @param partRfPart the Part/Rf Part/Part (the Part component holds the documents) + * @return a {@link List} of {@link Map}s + */ + public List> extract(final R10PartRfPart partRfPart) { + // For Parts, the documents can be found directly in their pseudo-fodlers + BOMLineHolder component = partRfPart.getPartComponentBL(); + AbstractPart part = (AbstractPart) component.getSnecmaObject(); + return extractDocsFromPart(part); + } + + /** + * Extract the content of each Document of a {@link R10Quad}. + */ + public List> extract(final R10Quad quad) throws InvalidInputException, MalformedNomenclatureException, NotFoundException { + ISnecmaObject component = quad.getComposant(); + if (component.isPart()) { + AbstractPart part = (AbstractPart) component; + return extractDocsFromPart(part); + } else { + BOMLineHolder genericComponent = quad.getComposantBL(); + return extractDocsFromGeneric(genericComponent); + } + } + + /** + * Extract the content of each Document of a {@link R10ReceptorLine}. + */ + public List> extract(final R10ReceptorLine receptorLine) throws InvalidInputException, MalformedNomenclatureException, NotFoundException { + ISnecmaObject receptor = receptorLine.getRecepteur(); + if (receptor.isGeneric()) { + return extractDocsFromGeneric(receptorLine.getRecepteurBL()); + } else { + return noDocuments(); + } + } + + /** + * Extract the content of each Document of a {@link R10TopLine}. + */ + public List> extract(final R10TopLine r10TopLine) throws InvalidInputException, MalformedNomenclatureException, NotFoundException { + ISnecmaObject topComponent = r10TopLine.getBomLineObject(); + if (topComponent.isGeneric()) { + return extractDocsFromGeneric(r10TopLine.getBomLine()); + } else if (topComponent.isProduct()) { + return extractDocsFromProduct((ProductRevision) topComponent); + } else { + log.warn("Unknown behaviour when top object is neither a Generic nor a Product, but is a :" + topComponent.getType()); + return noDocuments(); + } + } + + /** + * Extract the content of each Document of a {@link R10Quad}. + * + * @param r10AltPart The Alt/PArt (the part holds the Documents) + * @return a {@link List} of {@link Map}s + */ + public List> extract(final R10AltPart r10AltPart) { + AbstractPart component = r10AltPart.getChild(); + return extractDocsFromPart(component); + } + + private List> extractDocsFromGeneric(final BOMLineHolder gen) + throws InvalidInputException, MalformedNomenclatureException, NotFoundException { + // For generics, a Descriptif can be found as a bom Child, which owns some pseudo-folders containing the documents + BOMLineHolder rfGeneric = BOMLineHolderHelper.findRfGenericBL(gen); + BOMLineHolder descriptifBL = BOMLineHolderHelper.findFirst(rfGeneric, SnecmaObjectTypes.DESCRIPTIF_REVISION); + DescriptifRevision descriptif = (DescriptifRevision) descriptifBL.getSnecmaObject(); + + // Extract the documents from the Descriptif + List docs = new ArrayList<>(); + docs.addAll(descriptif.getReferenceDocumentsOfTypes( + new TcTypeInclusionFilter(DOC_NORM, DOC_NORM_STANDARD), + new DefaultRevisionSelector(effectivityDate, FROZEN, PUBLISHED), docCache)); + docs.addAll(descriptif.getDefinitionDocumentsOfTypes(new TcTypeInclusionFilter(DOC_TECHNIC_REVISION), docCache)); + return extractDocContent(docs); + } + + private List> extractDocsFromPart(final AbstractPart part) { + List docs = new ArrayList<>(); + docs.addAll(part.getReferenceDocumentsOfTypes( + new TcTypeInclusionFilter(DOC_NORM, DOC_NORM_STANDARD), + new DefaultRevisionSelector(effectivityDate, FROZEN, PUBLISHED), docCache)); + docs.addAll(part.getDefinitionDocumentsOfTypes(new TcTypeInclusionFilter(DOC_TECHNIC_REVISION), docCache)); + docs.addAll(part.getRepresentedDocumentsOfTypes(new TcTypeInclusionFilter(DOC_DRAWING_REVISION), docCache)); + return extractDocContent(docs); + } + + /* ************** This Applies the Visitor on each documents. ******************/ + + private List> extractDocsFromProduct(final ProductRevision product) { + List docs = new ArrayList<>(product.getDefinitionDocumentsOfTypes( + new TcTypeInclusionFilter(DOC_TECHNIC_REVISION), docCache)); + return extractDocContent(docs); + } + + /* ************** This section defines the Visitor behaviour on each documents. ******************/ + + private List> extractDocContent(final List docs) { + if (docs.isEmpty()) { + return noDocuments(); + } + List> docContentList = new ArrayList<>(); + for (AbstractDoc doc : docs) { + docContentList.add(doc.accept(this)); + } + return docContentList; + } + + @Override + public Map visit(final DocDrawing doc) { + Map map = new EnumMap<>(R10Keys.class); + map.put(R10Keys.DOC_LINK_TYPE, TYPE_DEFINITION_DOCUMENTS); + map.put(R10Keys.DOC_ID, doc.getDocId()); + map.put(R10Keys.DOC_REVISION, doc.getRevision()); + map.put(R10Keys.DOC_INDEX, doc.getIndicePlan()); + map.put(R10Keys.DOC_TYPE, "Représentation 2D"); // Devrait être "Représentation 2D / Drawing" mais on demande la partie FR... + map.put(R10Keys.DOC_NAME, doc.getName()); + map.put(R10Keys.DOC_NAME_ENG, doc.getDesignationEn()); + List status = doc.getStatus(); + map.put(R10Keys.DOC_STATUS, status.isEmpty() ? "" : status.get(0).getDisplayableName()); + map.put(R10Keys.DOC_CREATION_DATE, TeamcenterDateFormatter.formatCalendarToFrench(doc.getDateCreation())); + return map; + } + + @Override + public Map visit(final DocGeometry doc) { + return null; // not used in R10 + } + + @Override + public Map visit(final DocNorm doc) { + Map map = new EnumMap<>(R10Keys.class); + map.put(R10Keys.DOC_LINK_TYPE, TYPE_REFERENCE_DOCUMENTS); + map.put(R10Keys.DOC_ID, doc.getDocId()); + map.put(R10Keys.DOC_REVISION, doc.getRevision()); + map.put(R10Keys.DOC_INDEX, "-"); + map.put(R10Keys.DOC_TYPE, LanguageHelper.french(doc.getTypeDocNorm())); + map.put(R10Keys.DOC_NAME, doc.getItemName()); + map.put(R10Keys.DOC_NAME_ENG, doc.getDesignationEn()); + List status = doc.getStatus(); + map.put(R10Keys.DOC_STATUS, status.isEmpty() ? "" : status.get(0).getDisplayableName()); + map.put(R10Keys.DOC_CREATION_DATE, TeamcenterDateFormatter.formatCalendarToFrench(doc.getDateCreation())); + return map; + } + + @Override + public Map visit(final DocNormStandard doc) { + Map map = new EnumMap<>(R10Keys.class); + map.put(R10Keys.DOC_LINK_TYPE, TYPE_REFERENCE_DOCUMENTS); + map.put(R10Keys.DOC_ID, doc.getDocId()); + map.put(R10Keys.DOC_REVISION, doc.getRevision()); + map.put(R10Keys.DOC_INDEX, "-"); + map.put(R10Keys.DOC_TYPE, "Norme pour acticles standards"); // Specification says to put "Norme pour acticles standards / Norm for Standard ItemsStringHelper.EMPTY, but also says to extract the french part ^^ + map.put(R10Keys.DOC_NAME, doc.getItemName()); + map.put(R10Keys.DOC_NAME_ENG, doc.getDesignationEn()); + List status = doc.getStatus(); + map.put(R10Keys.DOC_STATUS, status.isEmpty() ? "" : status.get(0).getDisplayableName()); + map.put(R10Keys.DOC_CREATION_DATE, TeamcenterDateFormatter.formatCalendarToFrench(doc.getDateCreation())); + return map; + } + + @Override + public Map visit(final DocTechnic doc) { + String docId = (doc.getIdOrigine() == null || doc.getIdOrigine().isEmpty()) ? doc.getDocId() : doc.getIdOrigine(); + Map map = new EnumMap<>(R10Keys.class); + map.put(R10Keys.DOC_LINK_TYPE, TYPE_DEFINITION_DOCUMENTS); + map.put(R10Keys.DOC_ID, docId); + map.put(R10Keys.DOC_REVISION, doc.getRevision()); + map.put(R10Keys.DOC_INDEX, doc.getIndice()); + map.put(R10Keys.DOC_TYPE, LanguageHelper.french(doc.getTypeDocTechnic1()) + " / " + LanguageHelper.french(doc.getTypeDocTechnic2())); + map.put(R10Keys.DOC_NAME, doc.getName()); + map.put(R10Keys.DOC_NAME_ENG, doc.getDesignationEn()); + List status = doc.getStatus(); + map.put(R10Keys.DOC_STATUS, status.isEmpty() ? "" : status.get(0).getDisplayableName()); + map.put(R10Keys.DOC_CREATION_DATE, TeamcenterDateFormatter.formatCalendarToFrench(doc.getDateCreation())); + return map; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/ExecutionR10.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/ExecutionR10.java new file mode 100644 index 0000000..6d927e8 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/ExecutionR10.java @@ -0,0 +1,168 @@ +package com.capgemini.reports.definition.r10report; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.builder.R10Builder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.definition.r10report.ExecutionR10.ReportDataR10; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.reports.parameters.Generics; +import com.capgemini.reports.reports.parameters.Generics.GenericType; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.reports.parameters.MonoMulti; +import com.capgemini.reports.reports.parameters.checker.*; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +/** + * Class responsible for executing a R10 report. + */ +@Getter +public class ExecutionR10 extends AbstractExecutionReport { + + private static final String SEPARATOR = "-"; + + private static final long serialVersionUID = 5053661528356709081L; + + // Policies parameters + private static final PolicyLocation R10_POLICY_XML_LIGHT = PolicyLocation.make("R10_policy_light", "/xml/policies/r10report/R10_policy_light.xml"); + private static final PolicyLocation R10_POLICY_XML_FULL = PolicyLocation.make("R10_policy_full", "/xml/policies/r10report/R10_policy_full.xml"); + + // Launch type parameter + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R10"); + + // Revision rule parameter + private static final String REPORT_REVISION_RULE = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R10", DEFAULT_REVISION_RULE); + + // Priority parameter + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R10); + + private final Generics generics; + private final MonoMulti monoMulti; + private final EffectivityDate effectivityDate; + + /** + * Usual constructor. + * + * @param generics the {@link Generics} + * @param monoMulti the level of explosion + * @param effectivityDate the effectivity + */ + public ExecutionR10(final Generics generics, final MonoMulti monoMulti, final EffectivityDate effectivityDate) { + super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE); + this.generics = generics; + this.monoMulti = monoMulti; + this.effectivityDate = effectivityDate; + } + + @Override + public List getQuickChecks() { + List quickChecks = new ArrayList<>(); + quickChecks.add(new GenericExistenceChecker(generics)); + quickChecks.add(new ProductChecker(generics.getProductUnit().getProductID())); + quickChecks.add(new ProductUnitChecker(generics.getProductUnit())); + quickChecks.add(new EffectivityChecker(effectivityDate)); + return quickChecks; + } + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R10_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R10_POLICY_XML_FULL; + } + + @Override + public List getLongChecks() { + List longChecks = new ArrayList<>(); + longChecks.add(new GenericUnderProductUnitChecker(generics)); + return longChecks; + } + + @Override + public String getTemplateLocation() { + return JasperTemplate.TEMPLATE_R10.getFilepath(); + } + + @Override + public ReportEnum getReportIdentifier() { + return ReportEnum.REPORT_R10; + } + + @Override + public String getSpecifiedFileName() { + StringBuilder builder = new StringBuilder("R10-"); + if (generics.getType() == GenericType.GENERIC) { + builder.append(generics.getID()).append(SEPARATOR); + } else if (generics.getType() == GenericType.GENERIC_ASSEMB) { + builder.append(generics.getID()).append(SEPARATOR); + } + builder.append(generics.getProductUnit().getProductID()).append(SEPARATOR); + builder.append(generics.getProductUnit().getUnitStr()).append(SEPARATOR); + builder.append((MonoMulti.MONO.equals(monoMulti)) ? "Mono" : "Multi").append(SEPARATOR); + return builder.toString(); + } + + @Override + public PrintFormat getPrintingFormat() { + return PrintFormat.XLSX; + } + + @Override + public List getLaunchData() { + List theCriteria = new ArrayList<>(); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PRODUCT, generics.getProductUnit().getProductID())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.UNIT, generics.getProductUnit().getUnitStr())); + if (generics.getType() == GenericType.GENERIC) { + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC, generics.getID())); + } + if (generics.getType() == GenericType.GENERIC_ASSEMB) { + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC_ASSEMB, generics.getID())); + } + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.MONO_MULTI, monoMulti.toString())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.EFFECTIVITY_DATE, effectivityDate.formatAsInputCriteria())); + return theCriteria; + } + + @Override + public IDataReportPreparator getDataPreparator() { + return new DataReportPreparatorR10(); + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return new ExecutionR10(generics, monoMulti, effectivityDate); + } + + @Override + public Class getReportBuilderClass() { + return R10Builder.class; + } + + /** + * Stores all data obtained from TC. + */ + @AllArgsConstructor + static class ReportDataR10 { + private final BOMLineHolder config; + + public BOMLineHolder getConfig() { + return config; + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/R10BomLineFlattener.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/R10BomLineFlattener.java new file mode 100644 index 0000000..c133b34 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/R10BomLineFlattener.java @@ -0,0 +1,88 @@ +package com.capgemini.reports.definition.r10report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.flattener.AbstractBomLineFlattener; +import com.capgemini.reports.bomlineholder.flattener.line.*; +import com.capgemini.reports.definition.r10report.lines.*; +import com.capgemini.reports.releasestatus.EffectivityBehaviourHelper; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * Flattens a bomLine. + */ +public class R10BomLineFlattener extends AbstractBomLineFlattener>, DocumentExtractor> { + + private static final boolean VISIT_PART_BELOW_PART = false; + private static final boolean RETRIEVE_PART_NUMBER_UNDER_RF_GENERIC = false; + private static final boolean VISIT_PARTS_IN_PSEUDO_FOLDER = true; + private static final boolean GENERATE_BROTHER_LINES_BEFORE_RECURSION = false; + private final TcSession session; + private int counter; + + /** + * Usual constructor. + */ + R10BomLineFlattener(final TcSession session) { + super(EffectivityBehaviourHelper.visitOnlyUnitManagedParts(), VISIT_PARTS_IN_PSEUDO_FOLDER, RETRIEVE_PART_NUMBER_UNDER_RF_GENERIC, + VISIT_PART_BELOW_PART, null, GENERATE_BROTHER_LINES_BEFORE_RECURSION); + this.session = session; + this.setPseudoFolderBehaviour(new R10PseudoFolderBrowser()); + } + + @Override + protected AbstractQuad>, DocumentExtractor> makeQuad(final BOMLineHolder receptor, final BOMLineHolder rfReceptor, + final BOMLineHolder component, final BOMLineHolder rfComponent) { + return new R10Quad(session, receptor, rfReceptor, component, rfComponent, counter++); + } + + @Override + protected AbstractTopLine>, DocumentExtractor> makeTopline(final BOMLineHolder aTopBomLine) { + return new R10TopLine(aTopBomLine, counter++); // Nothing to do for this report: top line is ignored + } + + @Override + protected AbstractPartNumber>, DocumentExtractor> makePartNumber(final BOMLineHolder genericReceptor, + final BOMLineHolder rfGeneric, final BOMLineHolder partAero) { + return null; // Nothing to do for this report: part number is ignored + } + + @Override + protected AbstractPartRfPart>, DocumentExtractor> makePartRfPart(final BOMLineHolder partReceptor, + final BOMLineHolder rfPartComponent, final BOMLineHolder partComponent) { + return new R10PartRfPart(session, partReceptor, rfPartComponent, partComponent, counter++); + } + + @Override + protected AbstractPartPart>, DocumentExtractor> makePartPart(final BOMLineHolder partReceptor, + final BOMLineHolder partComponent) { + return null; // Nothing to do for this report: top line is ignored + } + + @Override + protected AbstractReceptorLine>, DocumentExtractor> makeReceptorLine(final BOMLineHolder part, + final BOMLineHolder rfPart) { + return null; // Nothing to do for this report: When there is no Component, there is no line + } + + @Override + protected AbstractProductGeneric>, DocumentExtractor> makeProductGeneric(final BOMLineHolder productReceptor, + final BOMLineHolder genericComponent, final BOMLineHolder rfGenericComponent) { + return new R10ProductGeneric(session, productReceptor, genericComponent, rfGenericComponent, counter++); + } + + private class R10PseudoFolderBrowser implements AbstractBomLineFlattener.DealWithAltOrDetPseudoFolder>, DocumentExtractor> { + + @Override + public Collection>, DocumentExtractor>> dealWithIt(final BOMLineHolder alt, final AbstractPart partInPseudoFolder) { + Collection>, DocumentExtractor>> list = new ArrayList<>(); + list.add(new R10AltPart(alt, partInPseudoFolder, counter++)); + return list; + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/R10Keys.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/R10Keys.java new file mode 100644 index 0000000..60fded3 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/R10Keys.java @@ -0,0 +1,33 @@ +package com.capgemini.reports.definition.r10report; + +/** + * Key attributes to the Jasper report content. + */ +public enum R10Keys { + RECEPTOR_ID, + RECEPTOR_REVISION, + RECEPTOR_NAME, + REPERE_NAME, + REPERE_REVISION, + RESPONSABLE_REPERE, + QUANTITY, + COMPONENT_ID, + COMPONENT_REVISION, + COMPONENT_TYPE, + COMPONENT_NAME, + COMPONENT_REF_TRANSPOSED, + COMPONENT_DESIGN_MANAGER, + COMPONENT_NAME_ENG, + COMPONENT_CLASSEMENT, + COMPONENT_MASS, + COMPONENT_MASS_UNIT, + DOC_LINK_TYPE, + DOC_ID, + DOC_REVISION, + DOC_INDEX, + DOC_TYPE, + DOC_NAME, + DOC_NAME_ENG, + DOC_STATUS, + DOC_CREATION_DATE +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/R10Printer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/R10Printer.java new file mode 100644 index 0000000..42076f6 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/R10Printer.java @@ -0,0 +1,105 @@ +package com.capgemini.reports.definition.r10report; + +import com.capgemini.framework.common.DoubleFormatter; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.bomlineholder.flattener.line.SnecmaLine; +import com.capgemini.reports.definition.r10report.ExecutionR10.ReportDataR10; +import com.capgemini.reports.documentationobjects.AbstractDoc; +import com.capgemini.reports.execution.mapconstructor.AbstractStaticTemplateMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import lombok.extern.slf4j.Slf4j; + +import java.util.*; + +/** + * Extracts the relevant data obtained from TC into the expected List of Maps for Jasper. + */ +@Slf4j +public class R10Printer extends AbstractStaticTemplateMapConstructor { + private static final long serialVersionUID = 2418903684813779698L; + + private static final int SIGNIFICANT_DIGITS = 6; + private static final Map EMPTY_BOM_MAP = new EnumMap<>(R10Keys.class); + + static { + EMPTY_BOM_MAP.put(R10Keys.COMPONENT_CLASSEMENT, ""); + EMPTY_BOM_MAP.put(R10Keys.COMPONENT_DESIGN_MANAGER, ""); + EMPTY_BOM_MAP.put(R10Keys.COMPONENT_ID, ""); + EMPTY_BOM_MAP.put(R10Keys.COMPONENT_MASS, ""); + EMPTY_BOM_MAP.put(R10Keys.COMPONENT_MASS_UNIT, ""); + EMPTY_BOM_MAP.put(R10Keys.COMPONENT_NAME, ""); + EMPTY_BOM_MAP.put(R10Keys.COMPONENT_NAME_ENG, ""); + EMPTY_BOM_MAP.put(R10Keys.COMPONENT_REF_TRANSPOSED, ""); + EMPTY_BOM_MAP.put(R10Keys.COMPONENT_REVISION, ""); + EMPTY_BOM_MAP.put(R10Keys.COMPONENT_TYPE, ""); + EMPTY_BOM_MAP.put(R10Keys.QUANTITY, ""); + EMPTY_BOM_MAP.put(R10Keys.RECEPTOR_ID, ""); + EMPTY_BOM_MAP.put(R10Keys.RECEPTOR_NAME, ""); + EMPTY_BOM_MAP.put(R10Keys.RECEPTOR_REVISION, ""); + EMPTY_BOM_MAP.put(R10Keys.REPERE_NAME, ""); + EMPTY_BOM_MAP.put(R10Keys.REPERE_REVISION, ""); + EMPTY_BOM_MAP.put(R10Keys.RESPONSABLE_REPERE, ""); + } + + private final Calendar effectivityDate; + + public R10Printer(final Calendar effectivityDate) { + this.effectivityDate = effectivityDate; + } + + @Override + public void constructDataMaps(final TcSession session, final PrintParameters printParameters, final ReportDataR10 reportData) throws KurtException { + log.info("Browsing the Snecma Objects"); + R10BomLineFlattener flattener = new R10BomLineFlattener(session); + flattener.visitTopReceptorBom(session, reportData.getConfig()); + + // Degroup with doc data + log.info("Regrouping conf elements with their documents"); + List> result = new ArrayList<>(); + Map docCache = new HashMap<>(); + for (SnecmaLine>, DocumentExtractor> elem : flattener.getConfig()) { + Map bomMap = generateCommonBomMap(elem); + List> docMaps = elem.transform(new DocumentExtractor(effectivityDate, docCache)); + // Put the bom info in the 1st line, leave the rest blank + Iterator> docIterator = docMaps.iterator(); + docIterator.next().putAll(bomMap); + // Put empty fields in the rest + while (docIterator.hasNext()) { + docIterator.next().putAll(EMPTY_BOM_MAP); + } + result.addAll(docMaps); + } + log.info("{} Lines generated for {} parts.", result.size(), flattener.getConfig().size()); + printParameters.addReportDataFromEnum(result); + } + + private Map generateCommonBomMap(final SnecmaLine>, DocumentExtractor> line) { + String massStr; + if (line.getMass() == null) { + massStr = StringHelper.EMPTY; // when no mass is set (ex: receptor without component) print nothing + } else { + massStr = DoubleFormatter.toSignificantDigits(line.getMass(), SIGNIFICANT_DIGITS); + } + Map map = new EnumMap<>(R10Keys.class); + map.put(R10Keys.RECEPTOR_ID, line.getIDReceptor()); + map.put(R10Keys.RECEPTOR_NAME, line.getNameReceptor()); + map.put(R10Keys.RECEPTOR_REVISION, line.getRevisionReceptor()); + map.put(R10Keys.REPERE_NAME, line.getRepereName()); + map.put(R10Keys.REPERE_REVISION, line.getRepereRevision()); + map.put(R10Keys.RESPONSABLE_REPERE, line.getResponsableRepere()); + map.put(R10Keys.COMPONENT_ID, line.getIDComponent()); + map.put(R10Keys.COMPONENT_REVISION, line.getIDRevisionComponent()); + map.put(R10Keys.COMPONENT_NAME, line.getNameReference()); + map.put(R10Keys.COMPONENT_NAME_ENG, line.getDesignationENG()); + map.put(R10Keys.COMPONENT_TYPE, line.getTypeReference()); + map.put(R10Keys.COMPONENT_REF_TRANSPOSED, line.getReferenceTransposed()); + map.put(R10Keys.COMPONENT_DESIGN_MANAGER, line.getResponsableConception()); + map.put(R10Keys.COMPONENT_CLASSEMENT, line.getClassement()); + map.put(R10Keys.COMPONENT_MASS, massStr); + map.put(R10Keys.COMPONENT_MASS_UNIT, line.getMassUnit()); + map.put(R10Keys.QUANTITY, line.getQuantite()); + return map; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/lines/R10AltPart.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/lines/R10AltPart.java new file mode 100644 index 0000000..4381c62 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/lines/R10AltPart.java @@ -0,0 +1,35 @@ +package com.capgemini.reports.definition.r10report.lines; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.flattener.line.AbstractAltPart; +import com.capgemini.reports.definition.r10report.DocumentExtractor; +import com.capgemini.reports.definition.r10report.R10Keys; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import lombok.Getter; + +import java.util.List; +import java.util.Map; + +/** + * Represents The link between an Alt and a Part in its pseudo-folder. + */ +@Getter +public class R10AltPart extends AbstractAltPart>, DocumentExtractor> { + + /** + * builds the link between an Altenrate and a Part in its pseudo-folder. + * + * @param alt the Alternate + * @param child the child part + * @param counter the position of this line in the nomenclature. + */ + public R10AltPart(final BOMLineHolder alt, final AbstractPart child, final int counter) { + super(alt, child, counter); + } + + @Override + public List> transform(final DocumentExtractor extractor) { + return extractor.extract(this); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/lines/R10PartRfPart.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/lines/R10PartRfPart.java new file mode 100644 index 0000000..8878bdc --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/lines/R10PartRfPart.java @@ -0,0 +1,36 @@ +package com.capgemini.reports.definition.r10report.lines; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.flattener.line.AbstractPartRfPart; +import com.capgemini.reports.definition.r10report.DocumentExtractor; +import com.capgemini.reports.definition.r10report.R10Keys; +import lombok.Getter; + +import java.util.List; +import java.util.Map; + +/** + * Represents a classical 'triplet' between a Part, a Rf Part and a Part. + */ +@Getter +public class R10PartRfPart extends AbstractPartRfPart>, DocumentExtractor> { + + /** + * Builds a classical 'triplet' between a Part, a Rf Part and a Part. + * + * @param partReceptor the {@link BOMLineHolder} Part receptor + * @param rfPartComponent the {@link BOMLineHolder} RF Part receptor + * @param partComponent the {@link BOMLineHolder} APrt component + * @param counter the position of the line in the nomenclature. + */ + public R10PartRfPart(final TcSession session, final BOMLineHolder partReceptor, final BOMLineHolder rfPartComponent, final BOMLineHolder partComponent, + final int counter) { + super(session, partReceptor, rfPartComponent, partComponent, counter); + } + + @Override + public List> transform(final DocumentExtractor extractor) { + return extractor.extract(this); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/lines/R10ProductGeneric.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/lines/R10ProductGeneric.java new file mode 100644 index 0000000..768d48b --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/lines/R10ProductGeneric.java @@ -0,0 +1,62 @@ +package com.capgemini.reports.definition.r10report.lines; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.flattener.line.AbstractProductGeneric; +import com.capgemini.reports.definition.r10report.DocumentExtractor; +import com.capgemini.reports.definition.r10report.R10Keys; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +/** + * Represents a Product - Generic line for R07 report. + */ +@Slf4j +public class R10ProductGeneric extends AbstractProductGeneric>, DocumentExtractor> { + + /** + * Builds a Product - Generic line for the R07 report. + * + * @param productReceptor the {@link BOMLineHolder} product (receptor) + * @param genericComponent the {@link BOMLineHolder} generic (component) + * @param rfGenericComponent the {@link BOMLineHolder} RfGeneric + * @param counter the line num + */ + public R10ProductGeneric(final TcSession session, final BOMLineHolder productReceptor, final BOMLineHolder genericComponent, final BOMLineHolder rfGenericComponent, + final int counter) { + super(session, productReceptor, genericComponent, rfGenericComponent, counter); + } + + @Override + public List> transform(final DocumentExtractor extractor) { + try { + return extractor.extract(this); + } catch (KurtException e) { + log.error("Unable to obtain the list of documents for " + getLineId(), e); + // Make the line still appear by placing an entry in the list. However all fields will be empty. + Map mapWithEmptyStrings = new EnumMap<>(R10Keys.class); + for (R10Keys key : R10Keys.values()) { + mapWithEmptyStrings.put(key, StringHelper.EMPTY); + } + List> listWithOneMapWithEmptyString = new ArrayList<>(); + listWithOneMapWithEmptyString.add(mapWithEmptyStrings); + return listWithOneMapWithEmptyString; + } + } + + @Override + public Double getMass() { + return 0d; + } + + @Override + public String getMassUnit() { + return "Kg"; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/lines/R10Quad.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/lines/R10Quad.java new file mode 100644 index 0000000..78592b2 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/lines/R10Quad.java @@ -0,0 +1,88 @@ +package com.capgemini.reports.definition.r10report.lines; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.flattener.line.AbstractQuad; +import com.capgemini.reports.definition.r10report.DocumentExtractor; +import com.capgemini.reports.definition.r10report.R10Keys; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +/** + * Represents a {@link AbstractQuad} line, with receptor and component, both having their own repere.
+ * Receptors and components can be Parts or Generics.
+ * For the R07, the Quad accepts a TransformerR07 which will generate a custom Id for it, for sorting purposes. + */ +@Slf4j +@Getter +public class R10Quad extends AbstractQuad>, DocumentExtractor> { + + + /** + * Builds a 'quad' object, using receptor, its repere, a component, and its repere. + * + * @param recepteurBL the {@link BOMLineHolder} receptor + * @param repereRecepteurBL the {@link BOMLineHolder} repere of the receptor + * @param composantBL the {@link BOMLineHolder} composant + * @param repereComposantBL the {@link BOMLineHolder} repere of the composant + * @param counter the position of this line in the Bom + */ + public R10Quad(final TcSession session, final BOMLineHolder recepteurBL, final BOMLineHolder repereRecepteurBL, final BOMLineHolder composantBL, + final BOMLineHolder repereComposantBL, final int counter) { + super(session, recepteurBL, repereRecepteurBL, composantBL, repereComposantBL, counter); + } + + @Override + public List> transform(final DocumentExtractor extractor) { + try { + return extractor.extract(this); + } catch (KurtException e) { + log.error("Unable to obtain the list of documents for this Quadline: " + getLineId(), e); + // Make the line still appear by placing an entry in the list. However all fields will be empty. + Map mapWithEmptyStrings = new EnumMap<>(R10Keys.class); + for (R10Keys key : R10Keys.values()) { + mapWithEmptyStrings.put(key, StringHelper.EMPTY); + } + List> listWithOneMapWithEmptyString = new ArrayList<>(); + listWithOneMapWithEmptyString.add(mapWithEmptyStrings); + return listWithOneMapWithEmptyString; + } + + } + + @Override + public String getClassement() { + if (getComposant().isGeneric() || getComposant().isProduct()) { + return "-"; + } else { + return super.getClassement(); + } + } + + @Override + public Double getMass() { + if (getComposant().isGeneric()) { + return 0d; + } else { + return super.getMass(); + } + } + + @Override + public String getMassUnit() { + if (getComposant().isGeneric() || SnecmaObjectTypes.PART_MAT_REVISION.equals(getComposant().getType())) { + return "Kg"; + } else { + return super.getMassUnit(); + } + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/lines/R10ReceptorLine.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/lines/R10ReceptorLine.java new file mode 100644 index 0000000..26608ee --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/lines/R10ReceptorLine.java @@ -0,0 +1,46 @@ +package com.capgemini.reports.definition.r10report.lines; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.flattener.line.AbstractReceptorLine; +import com.capgemini.reports.definition.r10report.DocumentExtractor; +import com.capgemini.reports.definition.r10report.R10Keys; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +/** + * Represents a Receptor whose Repere does ot have a Component. + */ +@Slf4j +public class R10ReceptorLine extends AbstractReceptorLine>, DocumentExtractor> { + + /** + * Builds a Receptor whose Repere does not have a Component. + */ + public R10ReceptorLine(final TcSession session, final BOMLineHolder recepteurBL, final BOMLineHolder repereRecepteurBL, final int counter) { + super(session, recepteurBL, repereRecepteurBL, counter); + } + + @Override + public List> transform(final DocumentExtractor extractor) { + try { + return extractor.extract(this); + } catch (KurtException e) { + log.error("Unable to obtain the list of documents for this TopLine: " + getLineId(), e); + // Make the line still appear by placing an entry in the list. However all fields will be empty. + Map mapWithEmptyStrings = new EnumMap<>(R10Keys.class); + for (R10Keys key : R10Keys.values()) { + mapWithEmptyStrings.put(key, StringHelper.EMPTY); + } + List> listWithOneMapWithEmptyString = new ArrayList<>(); + listWithOneMapWithEmptyString.add(mapWithEmptyStrings); + return listWithOneMapWithEmptyString; + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/lines/R10TopLine.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/lines/R10TopLine.java new file mode 100644 index 0000000..9738dc1 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r10report/lines/R10TopLine.java @@ -0,0 +1,85 @@ +package com.capgemini.reports.definition.r10report.lines; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.flattener.line.AbstractTopLine; +import com.capgemini.reports.definition.r10report.DocumentExtractor; +import com.capgemini.reports.definition.r10report.R10Keys; +import com.capgemini.reports.snecmaobjects.generic.AbstractGenericRevision; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +/** + * Represents a TopLine of nemenclature (i.e. Product or Generic) for R07. + */ +@Slf4j +public class R10TopLine extends AbstractTopLine>, DocumentExtractor> { + + /** + * Simple constructor. + * + * @param topBomLine the original topLine {@link BOMLineHolder} + * @param lineNum the line number (normally zero for a TopLine!) + */ + public R10TopLine(final BOMLineHolder topBomLine, final int lineNum) { + super(topBomLine, lineNum); + } + + @Override + public List> transform(final DocumentExtractor transformer) { + try { + return transformer.extract(this); + } catch (KurtException e) { + log.error("Unable to obtain the list of documents for this TopLine: " + getLineId(), e); + // Make the line still appear by placing an entry in the list. However all fields will be empty. + Map mapWithEmptyStrings = new EnumMap<>(R10Keys.class); + for (R10Keys key : R10Keys.values()) { + mapWithEmptyStrings.put(key, StringHelper.EMPTY); + } + List> listWithOneMapWithEmptyString = new ArrayList<>(); + listWithOneMapWithEmptyString.add(mapWithEmptyStrings); + return listWithOneMapWithEmptyString; + } + } + + @Override + public String getResponsableConception() { + if (getBomLineObject().isGeneric()) { + return ((AbstractGenericRevision) getBomLineObject()).getResponsableConception(); + } else { + return StringHelper.EMPTY; + } + } + + @Override + public String getClassement() { + if (getBomLineObject().isGeneric() || getBomLineObject().isProduct()) { + return "-"; + } else { + return super.getClassement(); + } + } + + @Override + public Double getMass() { + if (getBomLineObject().isGeneric()) { + return 0d; + } else { + return super.getMass(); + } + } + + @Override + public String getMassUnit() { + if (getBomLineObject().isGeneric()) { + return "Kg"; + } else { + return super.getMassUnit(); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/DataReportPreparatorR11.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/DataReportPreparatorR11.java new file mode 100644 index 0000000..799d313 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/DataReportPreparatorR11.java @@ -0,0 +1,106 @@ +package com.capgemini.reports.definition.r11report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObjectFactory; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRule; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRuleProperties; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.product.TcProduct; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindow; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindowConfiguration; +import com.capgemini.framework.teamcenter.object.runtime.TcRevisionRulesConfiguration; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderFactory; +import com.capgemini.reports.definition.r11report.data.extractor.FilterByTypeObject; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.filter.AllIsGoodFilter; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.reports.parameters.Generics; +import com.capgemini.reports.reports.parameters.MonoMulti; +import com.capgemini.reports.teamcenter.resolution.structureservice.IStructureServiceCaller; +import com.capgemini.reports.teamcenter.resolution.structureservice.MultiStructureServiceCaller; +import com.capgemini.reports.teamcenter.resolution.structureservice.TripleStructureServiceCaller; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Form; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + + +/** + * Class which prepare data for the reports. + */ +public class DataReportPreparatorR11 implements IDataReportPreparator { + private static final long serialVersionUID = 6949217671922185431L; + private static final Logger LOGGER = LoggerFactory.getLogger(DataReportPreparatorR11.class); + + @Override + public String print(TcSession session, ExecutionR11 execution, IExecutionStrategy executionStrategy) throws KurtException { + PrintParameters printParameters = prepareData(session, execution); + executionStrategy.print(printParameters, execution); + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + } + + private PrintParameters prepareData(final TcSession session, final ExecutionR11 report) throws KurtException { + LOGGER.debug("PrepareData started on: {}", report.getReportIdentifier().getReportTitle()); + + // Setup the policy + session.setObjectPropPolicy(report.getFullPolicy()); + + Generics generic = report.getGeneric(); + TcBomObject topLineObject = new TcBomObjectFactory(session, report.getGeneric().getItem(session)).create(); + TcProduct productObject = new TcProduct(session, generic.getProductUnit().getProduct(session)); + int unit = generic.getProductUnit().getUnit(); + EffectivityDate effectivityDate = report.getEffectivity(); + + TcRevisionRuleProperties revisionRuleProperties = new TcRevisionRuleProperties(productObject, unit, effectivityDate.isNow() ? null : effectivityDate.getDateTime()); + + TcRevisionRule revisionRule = session.findRevRule(report.getRevisionRule()); + TcRevisionRulesConfiguration revRulesConfiguration = new TcRevisionRulesConfiguration(revisionRule, revisionRuleProperties); + + IStructureServiceCaller service; + if (MonoMulti.MONO.equals(report.getMonoMulti())) { + service = new TripleStructureServiceCaller(session); + } else { + service = new MultiStructureServiceCaller(session); + } + + try (TcBomWindow bomWindow = session.createBomWindow(new TcBomWindowConfiguration(topLineObject, revRulesConfiguration))) { + session.setObjectPropPolicy(report.getFullPolicy()); + + BOMLineHolder unbuiltTopLine = service.resolve(bomWindow.topLine(), new AllIsGoodFilter()); + List itemRevMaster = unbuiltTopLine.getAllItemRevMasters(); + session.loadProperties(itemRevMaster.toArray(new ModelObject[itemRevMaster.size()])); + + BOMLineHolderFactory.buildTopBom(session, unbuiltTopLine, new FilterByTypeObject(SnecmaObjectTypes.ALTERNATE_REVISION, + SnecmaObjectTypes.DET_REVISION, SnecmaObjectTypes.RF_PART_REVISION, SnecmaObjectTypes.PART_AERO_REVISION, + SnecmaObjectTypes.PART_MAT_REVISION, SnecmaObjectTypes.PART_NO_AERO_REVISION, SnecmaObjectTypes.GENERIC_REVISION, + SnecmaObjectTypes.RF_GENERIC_REVISION, SnecmaObjectTypes.STANDARD_REVISION, SnecmaObjectTypes.MOCKUP_REVISION, + SnecmaObjectTypes.RF_ADMIN_AG_REVISION, SnecmaObjectTypes.RF_ADMIN_AP_REVISION, SnecmaObjectTypes.RF_ADMIN_REVISION)); + + + R11Printer printer = new R11Printer(); + PrintParameters printParameters = printer.makeMasterTemplate(report, unbuiltTopLine); + printer.constructDataMaps(session, printParameters, unbuiltTopLine); + + return printParameters; + } catch (EmptyNomenclatureException e) { + switch (generic.getType()) { + case GENERIC: + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_PRODUCT_AND_UNIT, e); + case GENERIC_ASSEMB: + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_ASSEMB_PRODUCT_AND_UNIT, e); + default: + throw new KurtException("The TC Nomenclature Resolution returned null", e); + } + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/ExecutionR11.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/ExecutionR11.java new file mode 100644 index 0000000..8baff2c --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/ExecutionR11.java @@ -0,0 +1,154 @@ +package com.capgemini.reports.definition.r11report; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.builder.R11Builder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.definition.r11report.checker.R11GenericExistenceChecker; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.reports.parameters.*; +import com.capgemini.reports.reports.parameters.Generics.GenericType; +import com.capgemini.reports.reports.parameters.checker.EffectivityChecker; +import com.capgemini.reports.reports.parameters.checker.ProductChecker; +import com.capgemini.reports.reports.parameters.checker.ProductUnitChecker; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +/** + * Class which manage the execution of a R11 report. + */ +@Getter +@EqualsAndHashCode(callSuper = true) +public class ExecutionR11 extends AbstractExecutionReport { + private static final long serialVersionUID = 2431051269754641192L; + + private static final String SEPARATOR = "-"; + private static final String MODEL_DATE = "dd-MM-yyyy"; + // Policies parameters + private static final PolicyLocation R11_POLICY_XML_LIGHT = PolicyLocation.make("R11_policy_light", "/xml/policies/r11report/R11_policy_light.xml"); + private static final PolicyLocation R11_POLICY_XML_FULL = PolicyLocation.make("R11_policy_full", "/xml/policies/r11report/R11_policy_full.xml"); + // Launch type parameter + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R11"); + // Revision rule parameter + private static final String REPORT_REVISION_RULE = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R11", DEFAULT_REVISION_RULE); + // Priority parameter + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R11); + private final Generics generic; + private final MonoMulti monoMulti; + private final EffectivityDate effectivity; + + /** + * Constructor. + * + * @param generic {@link Generics} - the generic configuration with his product unit + * @param aMonoMulti {@link MonoMulti} - the level of the resolution structure + * @param anEffectivity {@link EffectivityDate} - the effectivity date + */ + public ExecutionR11(final Generics generic, final MonoMulti aMonoMulti, final EffectivityDate anEffectivity) { + super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE); + this.generic = generic; + this.monoMulti = aMonoMulti; + this.effectivity = anEffectivity; + } + + @Override + public List getQuickChecks() { + List quickChecks = new ArrayList<>(); + ProductUnit productUnit = generic.getProductUnit(); + quickChecks.add(new ProductChecker(productUnit.getProductID())); + quickChecks.add(new ProductUnitChecker(productUnit)); + quickChecks.add(new R11GenericExistenceChecker(generic)); + quickChecks.add(new EffectivityChecker(effectivity)); + return quickChecks; + } + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R11_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R11_POLICY_XML_FULL; + } + + @Override + public List getLongChecks() { + return new ArrayList<>(); + } + + @Override + public String getTemplateLocation() { + return JasperTemplate.TEMPLATE_R11.getFilepath(); + } + + @Override + public ReportEnum getReportIdentifier() { + return ReportEnum.REPORT_R11; + } + + @Override + public String getSpecifiedFileName() { + String dateSystem = TeamcenterDateFormatter.formatCalendarToPattern(Calendar.getInstance(), MODEL_DATE); + StringBuilder builder = new StringBuilder("R11-"); + if (generic.getType() == GenericType.GENERIC) { + builder.append(generic.getID()).append(SEPARATOR); + } else if (generic.getType() == GenericType.GENERIC_ASSEMB) { + builder.append(generic.getID()).append(SEPARATOR); + } + builder.append(generic.getProductUnit().getProductID()).append(SEPARATOR); + builder.append(generic.getProductUnit().getUnitStr()).append(SEPARATOR); + builder.append((MonoMulti.MONO.equals(monoMulti)) ? "Mono" : "Multi").append(SEPARATOR); + builder.append(effectivity.getDateTime() != null ? effectivity.formatAsInputCriteria() : dateSystem); + return builder.toString(); + } + + @Override + public PrintFormat getPrintingFormat() { + return PrintFormat.XLSX; + } + + @Override + public List getLaunchData() { + List theCriteria = new ArrayList<>(); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PRODUCT, generic.getProductUnit().getProductID())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.UNIT, generic.getProductUnit().getUnitStr())); + if (generic.getType() == GenericType.GENERIC) { + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC, generic.getID())); + } + if (generic.getType() == GenericType.GENERIC_ASSEMB) { + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC_ASSEMB, generic.getID())); + } + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.MONO_MULTI, monoMulti.toString())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.EFFECTIVITY_DATE, effectivity.formatAsInputCriteria())); + return theCriteria; + } + + @Override + public IDataReportPreparator getDataPreparator() { + return new DataReportPreparatorR11(); + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return new ExecutionR11(generic, monoMulti, effectivity); + } + + @Override + public Class getReportBuilderClass() { + return R11Builder.class; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/R11Keys.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/R11Keys.java new file mode 100644 index 0000000..d02ac22 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/R11Keys.java @@ -0,0 +1,36 @@ +package com.capgemini.reports.definition.r11report; + +/** + * Enum class for the report R11. + */ +public enum R11Keys { + IDENTIFIANT_RECEPTEUR, + REVISION_RECEPTEUR, + NOM_RECEPTEUR, + REPERE_FONCTIONNEL, + REVISION_REPERE_FONCTIONNEL, + RESPONSABLE_REPERE, + MAQUETTE_INTERNE_EXTERNE, + STATUT_MISE_EN_MAQUETTE, + REF_FRABRICANT_REF_SNECMA, + REVISION_REFERENCE, + NOM_REFERENCE, + TYPE_OBJET, + DESIGNATION_ANGLAISE, + CONTROLE_COHERENCE, + STATUT_PART_P, + STATUT_PART_S, + STATUT_PART_K, + STATUT_PART_R, + STATUT_PART_M, + STATUT_PART_C, + STATUT_PART_I, + NOMBRE_REPERE_FONCTIONNEL_METTRE_EN_MAQUETTE, + NOMBRE_REPERE_FONCTIONNEL_MAQUETTE, + MISE_EN_MAQUETTE_POURCENTAGE, + NOMBRE_REPERE_FONCTIONNEL_INCOHERENT, + REPERE_FONCTIONNEL_MAQUETTE_INCOHERENTE_POURCENTAGE, + NOMBRE_REPERE_FONCTIONNEL_MISE_EN_MAQUETTE_COHERENTE, + POURCENTAGE_MAQUETTE_COHERENTE, + A_METTRE_EN_MAQUETTE +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/R11Printer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/R11Printer.java new file mode 100644 index 0000000..1e61313 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/R11Printer.java @@ -0,0 +1,236 @@ +package com.capgemini.reports.definition.r11report; + +import com.capgemini.framework.common.LanguageHelper; +import com.capgemini.framework.common.ReportFolderOutputHelper; +import com.capgemini.framework.common.ResourceHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.object.pom.status.TcEffectivity; +import com.capgemini.framework.teamcenter.object.pom.status.TcReleaseStatus; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.definition.r11report.data.extractor.BomLineBrowserR11; +import com.capgemini.reports.definition.r11report.data.extractor.R11ReceptorRepere; +import com.capgemini.reports.exceptions.FileLoadingException; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.ReportPrintException; +import com.capgemini.reports.execution.mapconstructor.IMapConstructor; +import com.capgemini.reports.filter.AllIsGoodFilter; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.printing.PrintReportHelper; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.mockup.MockupRevision; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import com.capgemini.reports.snecmaobjects.rf.AbstractRF; + +import java.util.*; + +/** + * Printer for the report R11. Put in the map all data to send to the template jasper. + */ +public class R11Printer implements IMapConstructor { + private static final long serialVersionUID = -8731017017029400269L; + + private static final int PERCENT = 100; + private static final String COMA = ", "; + private static final String EMPTY = ""; + private static final String NON = "Non"; + private static final String OUI = "Oui"; + + private int nbRepereFonctionnelMettreEnMaquette; + private int nbRepereMisEnMaquette; + private int nbRepereFonctionnelAvecIncoherence; + private int nbRepereFonctionnelAvecCoherence; + + @Override + public void constructDataMaps(final TcSession session, final PrintParameters printParameters, final BOMLineHolder topLine) throws KurtException { + BomLineBrowserR11 bomLineBrowserR11 = new BomLineBrowserR11(); + bomLineBrowserR11.setFilterNomenclature(new AllIsGoodFilter()); + bomLineBrowserR11.visitTopReceptorBom(session, topLine); + List> lstMapData = new ArrayList<>(); + Map parameters = new EnumMap<>(R11Keys.class); + treatementReceptor(bomLineBrowserR11.getConfig(), lstMapData); + printParameters.addReportData(lstMapData); + parameters.put(R11Keys.NOMBRE_REPERE_FONCTIONNEL_METTRE_EN_MAQUETTE, nbRepereFonctionnelMettreEnMaquette); + parameters.put(R11Keys.NOMBRE_REPERE_FONCTIONNEL_INCOHERENT, nbRepereFonctionnelAvecIncoherence); + parameters.put(R11Keys.NOMBRE_REPERE_FONCTIONNEL_MAQUETTE, nbRepereMisEnMaquette); + parameters.put(R11Keys.NOMBRE_REPERE_FONCTIONNEL_MISE_EN_MAQUETTE_COHERENTE, nbRepereFonctionnelAvecCoherence); + String ratioMiseEnMaquette = safeDiv(nbRepereMisEnMaquette, nbRepereFonctionnelMettreEnMaquette); + String ratioMaquettesIncoherentes = safeDiv(nbRepereFonctionnelAvecIncoherence, nbRepereMisEnMaquette); + String ratioMaquettesCoherentes = safeDiv(nbRepereFonctionnelAvecCoherence, nbRepereFonctionnelMettreEnMaquette); + parameters.put(R11Keys.MISE_EN_MAQUETTE_POURCENTAGE, ratioMiseEnMaquette); + parameters.put(R11Keys.REPERE_FONCTIONNEL_MAQUETTE_INCOHERENTE_POURCENTAGE, ratioMaquettesIncoherentes); + parameters.put(R11Keys.POURCENTAGE_MAQUETTE_COHERENTE, ratioMaquettesCoherentes); + printParameters.addReportParameters(parameters); + } + + private String safeDiv(final int num, final int denom) { + if (denom == 0) { + return "0 %"; + } else { + return ((PERCENT * num) / denom) + " %"; + } + } + + private void treatementReceptor(final List lstReceptorRepere, final List> lstMapData) { + for (R11ReceptorRepere element : lstReceptorRepere) { + Map mapLine = new HashMap<>(); + mapLine.put(R11Keys.IDENTIFIANT_RECEPTEUR.toString(), element.getIDReceptor()); + mapLine.put(R11Keys.NOM_RECEPTEUR.toString(), element.getNameReceptor()); + mapLine.put(R11Keys.REVISION_RECEPTEUR.toString(), element.getRevisionReceptor()); + mapLine.put(R11Keys.REPERE_FONCTIONNEL.toString(), element.getRepereName()); + mapLine.put(R11Keys.REVISION_REPERE_FONCTIONNEL.toString(), element.getRepereRevision()); + mapLine.put(R11Keys.RESPONSABLE_REPERE.toString(), element.getResponsableRepere()); + mapLine.put(R11Keys.MAQUETTE_INTERNE_EXTERNE.toString(), element.getMaquetteInterneExterne()); + extratorDataRepere(element, mapLine); + lstMapData.add(mapLine); + } + } + + private void extratorDataRepere(final R11ReceptorRepere receptorRepere, final Map mapLine) { + BOMLineHolder bomLineRepere = receptorRepere.getRepereFonctionnel(); + if (bomLineRepere.getObjectType().equals(SnecmaObjectTypes.RF_GENERIC_REVISION)) { + getRepereGeneric(bomLineRepere, mapLine); + } else { + getReperePart(bomLineRepere, mapLine); + } + defineComponent((AbstractRF) bomLineRepere.getSnecmaObject(), mapLine, bomLineRepere); + } + + private void getReperePart(final BOMLineHolder bomLineRepere, final Map mapLine) { + StringBuilder iDComponent = new StringBuilder(); + int nbPartBrowsed = 0; + int nbPart = retrieveNbPart(bomLineRepere.getBomChilds()); + for (BOMLineHolder child : bomLineRepere.getBomChilds()) { + final ISnecmaObject snecmaObject = child.getSnecmaObject(); + if (snecmaObject.isPart()) { + nbPartBrowsed++; + iDComponent.append(snecmaObject.getItemId()); + if (nbPartBrowsed < nbPart) { + iDComponent.append(COMA); + } + mapLine.put(R11Keys.REVISION_REFERENCE.toString(), snecmaObject.getRevisionId()); + mapLine.put(R11Keys.NOM_REFERENCE.toString(), snecmaObject.getName()); + mapLine.put(R11Keys.DESIGNATION_ANGLAISE.toString(), ((AbstractPart) snecmaObject).getDesignationEN()); + mapLine.put(R11Keys.TYPE_OBJET.toString(), LanguageHelper.getNameTypeWithoutRevision(snecmaObject.getType())); + } + } + mapLine.put(R11Keys.REF_FRABRICANT_REF_SNECMA.toString(), iDComponent.toString()); + } + + private int retrieveNbPart(final List bomChildMap) { + int nbPart = 0; + for (BOMLineHolder bomLineHolder : bomChildMap) { + if (bomLineHolder.getSnecmaObject().isPart()) { + nbPart++; + } + } + return nbPart; + } + + private void getRepereGeneric(final BOMLineHolder bomLineRepere, final Map mapLine) { + final GenericRevision snecmaObject = (GenericRevision) bomLineRepere.getParentBomLine().getSnecmaObject(); + mapLine.put(R11Keys.TYPE_OBJET.toString(), LanguageHelper.getNameTypeWithoutRevision(bomLineRepere.getParentBomLine().getObjectType())); + mapLine.put(R11Keys.REF_FRABRICANT_REF_SNECMA.toString(), snecmaObject.getItemId()); + mapLine.put(R11Keys.REVISION_REFERENCE.toString(), snecmaObject.getRevisionId()); + mapLine.put(R11Keys.NOM_REFERENCE.toString(), snecmaObject.getName()); + mapLine.put(R11Keys.DESIGNATION_ANGLAISE.toString(), snecmaObject.getDesignationEN()); + } + + private void defineComponent(final AbstractRF rf, final Map mapLine, final BOMLineHolder bomLineRepere) { + boolean isFindDMUStatut = false; + boolean isFindDataMockUp = false; + for (TcReleaseStatus status : rf.getStatusList()) { + if (status.getStatusEnum() == StatusEnum.DMU_READY) { + isFindDMUStatut = true; + } + } + for (int nbChild = 0; nbChild < bomLineRepere.getBomChilds().size(); nbChild++) { + if (bomLineRepere.getBomChilds().get(nbChild).getObjectType().equals(SnecmaObjectTypes.RF_ADMIN_REVISION)) { + RFAdminRevision rfAdmin = (RFAdminRevision) bomLineRepere.getBomChilds().get(nbChild).getSnecmaObject(); + if (LanguageHelper.french(rfAdmin.getEnveloppeCinematique()).equals(OUI) + || LanguageHelper.french(rfAdmin.getEnveloppeMaintenance()).equals(OUI) + || LanguageHelper.french(rfAdmin.getEnveloppeMontage()).equals(OUI) + || LanguageHelper.french(rfAdmin.getGeometriePieceRigide()).equals(OUI) + || LanguageHelper.french(rfAdmin.getGeometrieSimplifiee()).equals(OUI) + || LanguageHelper.french(rfAdmin.getTraceAxiale()).equals(OUI) + || LanguageHelper.french(rfAdmin.getInterfaceRfAdmin()).equals(OUI)) { + isFindDataMockUp = true; + } + } + } + mapLine.put(R11Keys.STATUT_MISE_EN_MAQUETTE.toString(), isFindDataMockUp && isFindDMUStatut ? OUI : NON); + mapLine.put(R11Keys.A_METTRE_EN_MAQUETTE.toString(), isFindDataMockUp ? OUI : NON); + nbRepereFonctionnelMettreEnMaquette = isFindDataMockUp ? nbRepereFonctionnelMettreEnMaquette + 1 : nbRepereFonctionnelMettreEnMaquette; + nbRepereMisEnMaquette = isFindDataMockUp && isFindDMUStatut ? nbRepereMisEnMaquette + 1 : nbRepereMisEnMaquette; + MockupRevision mockUpObject = null; + for (BOMLineHolder bomLineChild : bomLineRepere.getBomChilds()) { + if (bomLineChild.getObjectType().equals(SnecmaObjectTypes.MOCKUP_REVISION)) { + mockUpObject = (MockupRevision) bomLineChild.getSnecmaObject(); + mapLine.put(R11Keys.CONTROLE_COHERENCE.toString(), mockUpObject.getCoherenceControl()); + } + } + if (mockUpObject == null) { + mapLine.put(R11Keys.CONTROLE_COHERENCE.toString(), EMPTY); + mapLine.put(R11Keys.STATUT_PART_C.toString(), NON); + mapLine.put(R11Keys.STATUT_PART_S.toString(), NON); + mapLine.put(R11Keys.STATUT_PART_R.toString(), NON); + mapLine.put(R11Keys.STATUT_PART_M.toString(), NON); + mapLine.put(R11Keys.STATUT_PART_K.toString(), NON); + mapLine.put(R11Keys.STATUT_PART_I.toString(), NON); + mapLine.put(R11Keys.STATUT_PART_P.toString(), NON); + nbRepereFonctionnelAvecCoherence = + isFindDataMockUp && isFindDMUStatut ? nbRepereFonctionnelAvecCoherence + 1 : nbRepereFonctionnelAvecCoherence; + + } else { + mapLine.put(R11Keys.CONTROLE_COHERENCE.toString(), mockUpObject.getCoherenceControl()); + boolean isDMUPartK = false; + boolean isDMUPartP = false; + boolean isDMUPartS = false; + boolean isDMUPartR = false; + boolean isDMUPartC = false; + boolean isDMUPartI = false; + boolean isDMUPartM = false; + for (TcReleaseStatus status : mockUpObject.getStatusList()) { + isDMUPartC |= defineIsFindStatutMockup(status, StatusEnum.DMU_KO_PART_C); + isDMUPartK |= defineIsFindStatutMockup(status, StatusEnum.DMU_KO_PART_K); + isDMUPartP |= defineIsFindStatutMockup(status, StatusEnum.DMU_KO_PART_P); + isDMUPartI |= defineIsFindStatutMockup(status, StatusEnum.DMU_KO_PART_I); + isDMUPartR |= defineIsFindStatutMockup(status, StatusEnum.DMU_KO_PART_R); + isDMUPartM |= defineIsFindStatutMockup(status, StatusEnum.DMU_KO_PART_M); + isDMUPartS |= defineIsFindStatutMockup(status, StatusEnum.DMU_KO_PART_S); + } + mapLine.put(R11Keys.STATUT_PART_C.toString(), isDMUPartC ? OUI : NON); + mapLine.put(R11Keys.STATUT_PART_S.toString(), isDMUPartS ? OUI : NON); + mapLine.put(R11Keys.STATUT_PART_R.toString(), isDMUPartR ? OUI : NON); + mapLine.put(R11Keys.STATUT_PART_M.toString(), isDMUPartM ? OUI : NON); + mapLine.put(R11Keys.STATUT_PART_K.toString(), isDMUPartK ? OUI : NON); + mapLine.put(R11Keys.STATUT_PART_I.toString(), isDMUPartI ? OUI : NON); + mapLine.put(R11Keys.STATUT_PART_P.toString(), isDMUPartP ? OUI : NON); + + nbRepereFonctionnelAvecIncoherence = isDMUPartC || isDMUPartI || isDMUPartK || isDMUPartM || isDMUPartP || isDMUPartS || isDMUPartR + ? nbRepereFonctionnelAvecIncoherence + 1 + : nbRepereFonctionnelAvecIncoherence; + nbRepereFonctionnelAvecCoherence = !isDMUPartC && !isDMUPartI && !isDMUPartK & !isDMUPartM && !isDMUPartP && !isDMUPartS && !isDMUPartR + && isFindDataMockUp && isFindDMUStatut ? nbRepereFonctionnelAvecCoherence + 1 : nbRepereFonctionnelAvecCoherence; + } + } + + private boolean defineIsFindStatutMockup(final TcReleaseStatus status, final StatusEnum dmuStatus) { + TcEffectivity effectivity = status.getEffectivity(); + String dateRange = effectivity == null ? null : effectivity.dateRange(); + return (dateRange == null || dateRange.isEmpty()) && status.getStatusEnum() == dmuStatus; + } + + @Override + public PrintParameters makeMasterTemplate(final ExecutionR11 report, final BOMLineHolder optionalData) + throws ReportPrintException, FileLoadingException, InvalidInputException { + String storageFolder = ReportFolderOutputHelper.getStorageFolderLocation(report.getLaunchType()); + String fileName = report.getFileNameOnDisc(); + return PrintReportHelper.setupPrintParameters(ResourceHelper.getResourceContent(report.getTemplateLocation()), storageFolder, fileName, + report); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/checker/R11GenericExistenceChecker.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/checker/R11GenericExistenceChecker.java new file mode 100644 index 0000000..473caa5 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/checker/R11GenericExistenceChecker.java @@ -0,0 +1,41 @@ +package com.capgemini.reports.definition.r11report.checker; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemQuery; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.reports.parameters.Generics; +import com.capgemini.reports.reports.parameters.checker.GenericExistenceChecker; +import com.teamcenter.soa.client.model.strong.Item; + +import java.util.List; + +/** + * This class checks if a Generics (which represents a Generic and/or GenericAssemb) exists within the TC database for a R11 report. + */ +public class R11GenericExistenceChecker extends GenericExistenceChecker { + + /** + * Constructor. + * + * @param generics {@link Generics} - the generic + */ + public R11GenericExistenceChecker(final Generics generics) { + super(generics); + } + + // generic assemb not allowed! + @Override + protected void genericExists(final TcSession session) throws InvalidUserInputException { + List list = new ItemQuery(session).searchID(super.generics.getGeneric()).searchGeneric().findAll(); + List listGenericAssemb = new ItemQuery(session).searchID(generics.getGeneric()).searchGenericAssemb().findAll(); + + if (list == null || list.isEmpty()) { + if (!(listGenericAssemb == null || listGenericAssemb.isEmpty())) { + throw new InvalidUserInputException(UserInputErrorEnum.THE_GENERIC_MUST_BELONG_TO_THE_TECHNICAL_VIEW); + } else { + throw new InvalidUserInputException(getTechnicalErrorMsg()); + } + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/data/extractor/BomLineBrowserR11.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/data/extractor/BomLineBrowserR11.java new file mode 100644 index 0000000..dc6776b --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/data/extractor/BomLineBrowserR11.java @@ -0,0 +1,36 @@ +package com.capgemini.reports.definition.r11report.data.extractor; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.flattener.AbstractRepereFlattener; +import com.capgemini.reports.releasestatus.EffectivityBehaviourHelper; +import com.capgemini.reports.snecmaobjects.part.DETRevision; + +import javax.enterprise.inject.Alternative; + +/** + * This class is specific of the report R11.
+ * Inherits {@link AbstractRepereFlattener}, he gets only receptor and repere.
+ * For the report 11, the explosion of nomenclature is deepth-first, we don't need to findAll {@link Alternative} and {@link DETRevision}, to findAll the part number and only the effectivity by unit. + */ +public class BomLineBrowserR11 extends AbstractRepereFlattener { + private static final boolean VISIT_PART_BELOW_PART = false; + private static final boolean RETRIEVE_PART_NUMBER_UNDER_RF_GENERIC = false; + private static final boolean VISIT_PARTS_IN_PSEUDO_FOLDER = false; + private static final boolean DEEPLY_EXPLOSION = true; + + /** + * Constructor. + */ + public BomLineBrowserR11() { + super(EffectivityBehaviourHelper.visitOnlyUnitManagedParts(), VISIT_PARTS_IN_PSEUDO_FOLDER, RETRIEVE_PART_NUMBER_UNDER_RF_GENERIC, + VISIT_PART_BELOW_PART, DEEPLY_EXPLOSION); + } + + @Override + public R11ReceptorRepere makeRepairReceptorLine(final TcSession session, final BOMLineHolder bomLineReceptor, final BOMLineHolder bomLineRepair) { + return new R11ReceptorRepere(session, bomLineReceptor, bomLineRepair); + + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/data/extractor/FilterByTypeObject.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/data/extractor/FilterByTypeObject.java new file mode 100644 index 0000000..8884b7f --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/data/extractor/FilterByTypeObject.java @@ -0,0 +1,32 @@ +package com.capgemini.reports.definition.r11report.data.extractor; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.resolution.filtering.TcTypeInclusionFilter; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.filter.IFilterExplosionNomenclature; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; + +/** + * Class which allow to filter some objects which is defined in lstTypeObject. + */ +public class FilterByTypeObject extends TcTypeInclusionFilter implements IFilterExplosionNomenclature { + + /** + * Builds a Filter instance, that will ALLOW any object of the provided type. + * + * @param lstTypeObject the object types to be included + */ + public FilterByTypeObject(final String... lstTypeObject) { + super(lstTypeObject); + } + + @Override + public boolean isExcluded(TcSession session, final BOMLineHolder objectToFind) { + return super.isExcluded(objectToFind.getObjectType()); + } + + @Override + public boolean isExcluded(final ISnecmaObject object) { + return super.isExcluded(object.getType()); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/data/extractor/R11ReceptorRepere.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/data/extractor/R11ReceptorRepere.java new file mode 100644 index 0000000..2865725 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r11report/data/extractor/R11ReceptorRepere.java @@ -0,0 +1,52 @@ +package com.capgemini.reports.definition.r11report.data.extractor; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.flattener.line.AbstractReceptorRepere; +import com.capgemini.reports.bomlineholder.flattener.line.SnecmaLine; + +/** + * Class which inherits of {@link AbstractReceptorRepere}.Just need only receptor and rf. + */ +public class R11ReceptorRepere extends AbstractReceptorRepere { + + private static final String EMPTY = ""; + + /** + * Constructor. + * + * @param bomLineReceptor the {@link BOMLineHolder} of a receptor + * @param bomLineRepere the {@link BOMLineHolder} of a repere + */ + R11ReceptorRepere(final TcSession session, final BOMLineHolder bomLineReceptor, final BOMLineHolder bomLineRepere) { + super(session, bomLineReceptor, bomLineRepere); + } + + @Override + public String getLineId() { + return EMPTY; + } + + @Override + public int getLineNumber() { + // nothing to do + return 0; + } + + @Override + public Void transform(final Void transformer) { + // nothing to do because it's all voids + return null; + } + + @Override + public int compareTo(final SnecmaLine line) { + // nothing to do + return 0; + } + + @Override + public String getDesignationENG() { + return EMPTY; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/R13Keys.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/R13Keys.java new file mode 100644 index 0000000..e32425c --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/R13Keys.java @@ -0,0 +1,58 @@ +package com.capgemini.reports.definition.r13report; + +/** + * Enumeration of the columns of the R13 report. + */ +public enum R13Keys { + ATTACHE_PILOTE, + NOM_PILOTE, + STATUT_PILOTE, + ITEM_ID, + ITEM_REVISION, + DATE_CREATION, + DESIGNATION, + LIGNE_PRODUIT, + TYPE, + STATUT, + DATE_STATUT, + NOM_TEMPLATE_WKF, + ATTACHE_PILOTE_WKF, + NOM_PILOTE_WKF, + STATUT_PILOTE_WKF, + NOM_TACHE, + ATTACHE_ACTEUR_TACHE, + NOM_ACTEUR_TACHE, + STATUT_ACTEUR_TACHE, + DATE_CIBLE, + AVANCE_RETARD; + + /** + * Enumeration of the specific columns for a R13 report with CR objects. + */ + public enum CR { + ID_PROBLEM_REPORT, + REVISION_PROBLEM_REPORT, + EFFECTIVITES, + MODULES, + ATTACHE_PILOTE_CN, + NOM_PILOTE_CN, + STATUT_PILOTE_CN, + ITEM_ID_CN, + ITEM_REVISION_CN, + DATE_CREATION_CN, + LIGNE_PRODUIT_CN, + DESIGNATION_CN, + TYPE_CN, + STATUT_CN, + DATE_STATUT_CN, + PARTS_CHANGE_NOTICE, + PARTS_CHANGE_REQUEST + } + + /** + * Enumeration of the specific columns for a R13 report with FPP objects. + */ + public enum FPP { + PARTS_FPP + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/datapreparator/AbstractDataReportPreparatorR13.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/datapreparator/AbstractDataReportPreparatorR13.java new file mode 100644 index 0000000..89af286 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/datapreparator/AbstractDataReportPreparatorR13.java @@ -0,0 +1,84 @@ +package com.capgemini.reports.definition.r13report.datapreparator; + +import com.capgemini.framework.common.DateHelper; +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.capgemini.reports.definition.r13report.execution.AbstractExecutionR13; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.printing.PrintParameters; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.ReleaseStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class will allow to prepare common data for the R13 report. + * + * @param the daughter class: CR or FPP + */ +public abstract class AbstractDataReportPreparatorR13 implements IDataReportPreparator { + private static final long serialVersionUID = -3275014753104915202L; + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractDataReportPreparatorR13.class); + + @Override + public String print(TcSession session, T execution, IExecutionStrategy executionStrategy) throws KurtException { + PrintParameters printParameters = prepareData(session, execution); + executionStrategy.print(printParameters, execution); + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + } + + /** + * Method will allow to prepare data in common between report R13CR and R13FPP. + * + * @param session , the session of TC + * @param report the execution report + * @return a List of the Objects which will make up the report's content + */ + private PrintParameters prepareData(final TcSession session, final T report) throws KurtException { + LOGGER.debug("PrepareData started on: {}", report.getReportIdentifier().getReportTitle()); + session.setObjectPropPolicy(report.getFullPolicy()); + return buildValidatedChangeObjects(session, report); + } + + void addParamPeriod(final AbstractReplicatedQuery query, final T report) { + if (report.getStartDate() != null) { + query.addAfterDate(report.getStartDate().getFormattedDateForTcRequest()); + } + if (report.getFinalDate() != null) { + query.addBeforeDate(TeamcenterDateFormatter.translateDateFormatForRequest(DateHelper.getDatePlusOneWithReferenceCalendar(report.getFinalDate().getDateTime()))); + } + } + + /** + * Detects invalid status. + */ + boolean isStatusValid(final TcSession session, final ItemRevision itemRev) { + session.loadProperties(itemRev, "release_status_list"); + ReleaseStatus[] releaseStatuses = itemRev.get_release_status_list(); + session.loadProperties(releaseStatuses); + for (ReleaseStatus status : releaseStatuses) { + if (!validateStatusByName(status.get_name())) { + return false; + } + } + return true; // By default, if no status exist then the PR must be in the report + } + + /** + * Excludes specific statuses. + * + * @param statusName the input status name + * @return true if the status name is valid, false if it should be discarded + */ + protected abstract boolean validateStatusByName(final String statusName); + + /** + * Specific validation tests of an item, for each version of the R13. + */ + protected abstract boolean specificValidation(final TcSession session, final ItemRevision itemRev); + + protected abstract PrintParameters buildValidatedChangeObjects(final TcSession session, T report) throws KurtException; +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/datapreparator/DataReportPreparatorR13CR.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/datapreparator/DataReportPreparatorR13CR.java new file mode 100644 index 0000000..3e8cdae --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/datapreparator/DataReportPreparatorR13CR.java @@ -0,0 +1,86 @@ +package com.capgemini.reports.definition.r13report.datapreparator; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.capgemini.framework.teamcenter.resolution.filtering.TcTypeExclusionFilter; +import com.capgemini.reports.ItemRevisionComparator; +import com.capgemini.reports.changeobjects.change.TcChangeRequestRevision; +import com.capgemini.reports.definition.r13report.execution.ExecutionR13CR; +import com.capgemini.reports.definition.r13report.printer.R13PrinterCR; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.teamcenter.queries.saved.ChangeRequestWithSeqQuery; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * This class will allow to prepare data and findAll back data for making report R13CR. + */ +@Slf4j +public class DataReportPreparatorR13CR extends AbstractDataReportPreparatorR13 implements IDataReportPreparator { + private static final long serialVersionUID = 811112181278567085L; + + // Configuration + private static final String FINISHED = "Finished"; + private static final String CANCELLED = "Cancelled"; + private static final String SB_DISTRIBUTED = "SB distributed"; + + private static final String CR_DEPRECIE_REVISION = "CR Déprécié Revision"; + private static final String PV4_CR_DEPREC_REVISION = "PV4_CR_DEPRECRevision"; + + private static final TcTypeExclusionFilter FILTER_EXCLUDE_FINISHED_CANCELLED_DISTRIBUTED = new TcTypeExclusionFilter(FINISHED, CANCELLED, SB_DISTRIBUTED); + private static final TcTypeExclusionFilter FILTER_EXCLUDE_CR_DEPREC = new TcTypeExclusionFilter(CR_DEPRECIE_REVISION, PV4_CR_DEPREC_REVISION); + + @Override + protected boolean validateStatusByName(final String statusName) { + return FILTER_EXCLUDE_FINISHED_CANCELLED_DISTRIBUTED.isIncluded(statusName); + } + + @Override + protected boolean specificValidation(final TcSession session, final ItemRevision itemRev) { + // Filter out deprecated CRs + return FILTER_EXCLUDE_CR_DEPREC.isIncluded(itemRev.getTypeObject().getName()); + } + + @Override + protected PrintParameters buildValidatedChangeObjects(final TcSession session, ExecutionR13CR report) throws KurtException { + AbstractReplicatedQuery query = new ChangeRequestWithSeqQuery(session); + addParamPeriod(query, report); + List data = new ArrayList<>(); + for (ItemRevision itemRev : validateChangeObjects(query.searchAllObjects().findAll(), session)) { + data.add(new TcChangeRequestRevision(session, itemRev)); + } + + R13PrinterCR printer = new R13PrinterCR(); + PrintParameters printParameters = printer.makeMasterTemplate(report, data); + printer.constructDataMaps(session, printParameters, data); + + return printParameters; + } + + private List validateChangeObjects(final List objects, final TcSession session) { + List validatedObjects = new ArrayList<>(); + Collections.sort(objects, new ItemRevisionComparator()); + for (ItemRevision itemRev : objects) { + if (itemRev == null) { + continue; + } + // Common treatment on status + if (!isStatusValid(session, itemRev)) { + continue; + } + // Specific treatment if required (FPP) + if (!specificValidation(session, itemRev)) { + continue; + } + validatedObjects.add(itemRev); + } + + return validatedObjects; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/datapreparator/DataReportPreparatorR13FPP.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/datapreparator/DataReportPreparatorR13FPP.java new file mode 100644 index 0000000..9ee9a42 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/datapreparator/DataReportPreparatorR13FPP.java @@ -0,0 +1,105 @@ +package com.capgemini.reports.definition.r13report.datapreparator; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.capgemini.framework.teamcenter.resolution.filtering.TcTypeExclusionFilter; +import com.capgemini.reports.ItemRevisionComparator; +import com.capgemini.reports.changeobjects.change.FPPRevision; +import com.capgemini.reports.definition.r13report.execution.ExecutionR13FPP; +import com.capgemini.reports.definition.r13report.printer.R13PrinterFPP; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.teamcenter.queries.saved.FppWithSeqQuery; +import com.capgemini.reports.teamcenter.queries.saved.WorkflowOnChangeQuery; +import com.capgemini.reports.workflows.Task.TaskState; +import com.teamcenter.soa.client.model.strong.EPMTask; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * This class will allow to prepare data and findAll back data for making report R13FPP. + */ +public class DataReportPreparatorR13FPP extends AbstractDataReportPreparatorR13 implements IDataReportPreparator { + private static final long serialVersionUID = -5070390508126458855L; + + // Configuration + private static final String PB_REPORT_APPROVED = "Pb Report Approved"; + private static final String REFUSED = "Refused"; + private static final String CANCELLED = "Cancelled"; + + @Override + protected boolean validateStatusByName(final String statusName) { + return new TcTypeExclusionFilter(PB_REPORT_APPROVED, REFUSED, CANCELLED).isIncluded(statusName); + } + + @Override + protected boolean specificValidation(final TcSession session, final ItemRevision itemRev) { + String itemID = itemRev.get_item_id(); + String revisionID = itemRev.get_item_revision_id(); + List wkfList = new WorkflowOnChangeQuery(session).searchIDAndRevision(itemID, revisionID) + .searchSequenceId(String.valueOf(itemRev.get_sequence_id())).findAll(); + + // 1st case : wkf list is empty, it must appear in the report + if (wkfList.isEmpty()) { + return true; // Keep this CR + } + + // Remove finished wkf + List wkfToRemove = new ArrayList<>(); + for (EPMTask wkf : wkfList) { + if (TaskState.COMPLETED.matches(wkf.get_state())) { + wkfToRemove.add(wkf); + } + } + wkfList.removeAll(wkfToRemove); + + // 2rd case : all the wkf are finished + if (wkfList.isEmpty()) { + return false; // Discard this CR + } + + // 3rd case : at least 1 wkf is active + return true; // Keep this CR + } + + @Override + protected PrintParameters buildValidatedChangeObjects(final TcSession session, final ExecutionR13FPP report) throws KurtException { + AbstractReplicatedQuery query = new FppWithSeqQuery(session); + addParamPeriod(query, report); + List data = new ArrayList<>(); + for (ItemRevision itemRev : validateChangeObjects(query.searchAllObjects().findAll(), session)) { + data.add(new FPPRevision(session, itemRev)); + } + + R13PrinterFPP printer = new R13PrinterFPP(); + PrintParameters printParameters = printer.makeMasterTemplate(report, data); + printer.constructDataMaps(session, printParameters, data); + + return printParameters; + } + + private List validateChangeObjects(final List objects, final TcSession session) { + List validatedObjects = new ArrayList<>(); + Collections.sort(objects, new ItemRevisionComparator()); + for (ItemRevision itemRev : objects) { + if (itemRev == null) { + continue; + } + // Common treatment on status + if (!isStatusValid(session, itemRev)) { + continue; + } + // Specific treatment if required (FPP) + if (!specificValidation(session, itemRev)) { + continue; + } + validatedObjects.add(itemRev); + } + + return validatedObjects; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/execution/AbstractExecutionR13.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/execution/AbstractExecutionR13.java new file mode 100644 index 0000000..2002b8c --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/execution/AbstractExecutionR13.java @@ -0,0 +1,115 @@ +package com.capgemini.reports.definition.r13report.execution; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.reports.parameters.IChecker; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +/** + * This class controls the execution of a R13 report. + * + * @param generic object for a report + * @param the objects sent by the data preparator to the Printer (FPP or ChangeRequest) + */ +@Getter +@Slf4j +@EqualsAndHashCode(callSuper = true) +public abstract class AbstractExecutionR13, U> extends AbstractExecutionReport> { + + // Policies + protected static final PolicyLocation R13_POLICY_XML_FULL = PolicyLocation.make("R13_policy_full", "/xml/policies/r13report/R13_policy_full.xml"); + protected static final PolicyLocation R13_POLICY_XML_LIGHT = PolicyLocation.make("R13_policy_light", "/xml/policies/r13report/R13_policy_light.xml"); + private static final long serialVersionUID = 7486257915745387797L; + // Priority parameter + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R13); + // Revision rule parameter + private static final String REPORT_REVISION_RULE = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R13", DEFAULT_REVISION_RULE); + // Launch type parameter + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R13"); + // Raw input parameters + protected final String typeObject; + protected final EffectivityDate finalDate; + protected final EffectivityDate startDate; + + /** + * Constructor. + * + * @param typeObject String - the type of the Object + * @param finalDate {@link Calendar} - the final date + * @param startDate {@link Calendar} - the previous date + */ + AbstractExecutionR13(final String typeObject, final EffectivityDate finalDate, final EffectivityDate startDate) { + super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE); + this.typeObject = typeObject; + this.finalDate = finalDate; + this.startDate = startDate; + } + + @Override + public List getLaunchData() { + List theCriteria = new ArrayList<>(); + String prevValue = (startDate == null) ? "" : startDate.formatAsInputCriteria(); + String finalValue = finalDate.formatAsInputCriteria(); + log.info("R13 input:" + typeObject + "\t" + prevValue + "\t" + finalValue); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.TYPE_OBJET, typeObject)); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.DATE_DEBUT, prevValue)); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.DATE_FIN, finalValue)); + return theCriteria; + } + + @Override + public List getQuickChecks() { + return new ArrayList<>(); + } + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R13_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R13_POLICY_XML_FULL; + } + + @Override + public List getLongChecks() { + return new ArrayList<>(); + } + + @Override + public ReportEnum getReportIdentifier() { + return ReportEnum.REPORT_R13; + } + + @Override + public String getSpecifiedFileName() { + String separator = "_"; + StringBuilder builder = new StringBuilder("R13_").append(typeObject).append(separator); + if (startDate != null) { + builder.append(startDate.getFormattedDateForFrenchUser()).append(separator).append(finalDate.getFormattedDateForFrenchUser()); + } else { + builder.append("NoPrevDate").append(separator).append("NoFinalDate"); + } + + return builder.toString(); + } + + @Override + public PrintFormat getPrintingFormat() { + return PrintFormat.XLSX; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/execution/ExecutionR13CR.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/execution/ExecutionR13CR.java new file mode 100644 index 0000000..b04c358 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/execution/ExecutionR13CR.java @@ -0,0 +1,52 @@ +package com.capgemini.reports.definition.r13report.execution; + +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.builder.R13CrBuilder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.changeobjects.change.TcChangeRequestRevision; +import com.capgemini.reports.definition.r13report.datapreparator.DataReportPreparatorR13CR; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +/** + * This class controls the execution of a R13 report with CR objects. + */ +@Getter +@EqualsAndHashCode(callSuper = true) +public class ExecutionR13CR extends AbstractExecutionR13 { + + private static final long serialVersionUID = 2186783921659331654L; + + /** + * Constructor. + * + * @param finalDate {@link EffectivityDate} -the final date + * @param beginDate {@link EffectivityDate} -the previous date + */ + public ExecutionR13CR(final EffectivityDate finalDate, final EffectivityDate beginDate) { + super("CR", finalDate, beginDate); + } + + @Override + public String getTemplateLocation() { + return JasperTemplate.TEMPLATE_R13_CR.getFilepath(); + } + + @Override + public IDataReportPreparator getDataPreparator() { + return new DataReportPreparatorR13CR(); + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return new ExecutionR13CR(finalDate, startDate); + } + + @Override + public Class getReportBuilderClass() { + return R13CrBuilder.class; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/execution/ExecutionR13FPP.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/execution/ExecutionR13FPP.java new file mode 100644 index 0000000..d3d4906 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/execution/ExecutionR13FPP.java @@ -0,0 +1,50 @@ +package com.capgemini.reports.definition.r13report.execution; + +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.builder.R13FppBuilder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.changeobjects.change.FPPRevision; +import com.capgemini.reports.definition.r13report.datapreparator.DataReportPreparatorR13FPP; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import lombok.Getter; + +/** + * This class controls the execution of a R13 report with FPP objects. + */ +@Getter +public class ExecutionR13FPP extends AbstractExecutionR13 { + + private static final long serialVersionUID = 3645528867618039977L; + + /** + * Constructor. + * + * @param finalDate {@link EffectivityDate} -the final date + * @param previousDate {@link EffectivityDate} -the previous date + */ + public ExecutionR13FPP(final EffectivityDate finalDate, final EffectivityDate previousDate) { + super("FPP", finalDate, previousDate); + } + + @Override + public String getTemplateLocation() { + return JasperTemplate.TEMPLATE_R13_FPP.getFilepath(); + } + + @Override + public IDataReportPreparator getDataPreparator() { + return new DataReportPreparatorR13FPP(); + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return new ExecutionR13FPP(finalDate, startDate); + } + + @Override + public Class getReportBuilderClass() { + return R13FppBuilder.class; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/printer/AbstractR13Printer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/printer/AbstractR13Printer.java new file mode 100644 index 0000000..a3b6535 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/printer/AbstractR13Printer.java @@ -0,0 +1,372 @@ +package com.capgemini.reports.definition.r13report.printer; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.status.TcReleaseStatus; +import com.capgemini.reports.changeobjects.change.AbstractChangeObject; +import com.capgemini.reports.changeobjects.change.TcChangeNoticeRevision; +import com.capgemini.reports.definition.r13report.R13Keys; +import com.capgemini.reports.definition.r13report.execution.AbstractExecutionR13; +import com.capgemini.reports.execution.mapconstructor.AbstractStaticTemplateMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.users.SnecmaPerson; +import com.capgemini.reports.users.SnecmaUser; +import com.capgemini.reports.workflows.Task; +import com.google.common.base.Joiner; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +/** + * Printer of a R13 Report. + * + * @param {@link AbstractExecutionR13} - the abstract execution report + * @param The change objects required to make a reprot line (FPP or ChangeRequest) + */ +@Slf4j +@EqualsAndHashCode(callSuper = true) +public abstract class AbstractR13Printer, U extends AbstractChangeObject> + extends AbstractStaticTemplateMapConstructor> { + + private static final long serialVersionUID = 1510278082994267162L; + + private static final long MILLISECONDS_IN_SECONDS = 1000; + private static final long SECONDS_IN_MINUTES = 60; + private static final long MINUTES_IN_HOURS = 60; + private static final long HOURS_IN_DAY = 24; + private static final long MILLIS_PER_DAY = HOURS_IN_DAY * MINUTES_IN_HOURS * SECONDS_IN_MINUTES * MILLISECONDS_IN_SECONDS; + + private static final String INACTIF = "Inactif"; + private static final String ACTIF = "Actif"; + private static final String EMPTY_STRING = ""; + + @Override + public void constructDataMaps(TcSession session, final PrintParameters printParameters, final List changeList) throws KurtException { + long start = System.currentTimeMillis(); + List> reportLines = new ArrayList<>(); + for (U rootChangeObject : changeList) { + Map typeObjectParam = generateChangeObjectParameters(rootChangeObject); + Map> expandedChangeObject = getChangeObjectData(rootChangeObject, typeObjectParam); + for (Entry> entry : expandedChangeObject.entrySet()) { + AbstractChangeObject changeObject = entry.getKey(); + Map prefix = entry.getValue(); + try { + reportLines.addAll(discoverWorkflows(changeObject, prefix)); + } + catch (KurtException e) { + throw new KurtException("Erreur sur la MOD " + changeObject.getItemId(), e); + } + } + } + if (reportLines.isEmpty()) { + reportLines.add(putEmptyLine()); + } + printParameters.addReportData(reportLines); + printParameters.addReportParameters(new EnumMap<>(R13Keys.class)); + log.trace("Execution time : {} ms for {}", System.currentTimeMillis() - start, "data filtering"); + } + + /** + * Creates a map of one or several {@link AbstractChangeObject} to data relative to said change object.
+ * The change objects are related to the provided change object as follows: + *
    + *
  • In the case of a FPP report, the only key is the FPP passed as parameter
  • + *
  • In the case of a CR report, the first key is the CR passed as parameter, the rest are the CNs that depend on the CR. As the order is important, the return type must be a {@link LinkedHashMap} and not a simple {@link Map}/li> + *
+ * The provided prefix is used on each line, it may NOT be modified. + * + * @param data the change object to represent + * @param typeObjectParam prefix (DO NOT MODIFY) + * @return a + */ + protected abstract Map> getChangeObjectData(final U data, + final Map typeObjectParam); + + private Map generateChangeObjectParameters(final U change) { + // Users parameters + Map mapPrinter = makeUserParameters(change); + + // Object parameters + mapPrinter.put(R13Keys.ITEM_ID.toString(), change.getItemId()); + mapPrinter.put(R13Keys.ITEM_REVISION.toString(), change.getRevisionId()); + mapPrinter.put(R13Keys.DATE_CREATION.toString(), new EffectivityDate(change.getDateCreation()).getFormattedDateForFrenchUser()); + mapPrinter.put(R13Keys.DESIGNATION.toString(), change.getChangeName()); + String concatenatedLigneProduit = Joiner.on(StringHelper.LINE_FEED).join(change.getLignesProduit()); // Line jump within the cell + mapPrinter.put(R13Keys.LIGNE_PRODUIT.toString(), concatenatedLigneProduit); + + // Validated status of object parameters + mapPrinter.putAll(makeReleaseStatusParameters(change)); + return mapPrinter; + } + + /** + * These properties are present on both CR and FPP. + */ + Map makeUserParameters(final AbstractChangeObject change) { + final Map param = new HashMap<>(); + SnecmaUser user = change.getUser(); + SnecmaPerson person = user.getPerson(); + String codeCourrier = person.getCodeCourrier(); + if (change instanceof TcChangeNoticeRevision) { + param.put(R13Keys.CR.ATTACHE_PILOTE_CN.toString(), (codeCourrier == null || codeCourrier.isEmpty()) ? EMPTY_STRING : codeCourrier); + param.put(R13Keys.CR.NOM_PILOTE_CN.toString(), person.getPersonName()); + param.put(R13Keys.CR.STATUT_PILOTE_CN.toString(), userStatus(user)); + } else { + param.put(R13Keys.ATTACHE_PILOTE.toString(), (codeCourrier == null || codeCourrier.isEmpty()) ? EMPTY_STRING : codeCourrier); + param.put(R13Keys.NOM_PILOTE.toString(), person.getPersonName()); + param.put(R13Keys.STATUT_PILOTE.toString(), userStatus(user)); + } + return param; + } + + Map makeReleaseStatusParameters(final AbstractChangeObject change) { + TcReleaseStatus validatedStatus = findLastValidatedStatus(change); + boolean isCN = change instanceof TcChangeNoticeRevision; + String valueStatus; + String valueDate; + if (validatedStatus == null) { + valueStatus = EMPTY_STRING; + valueDate = EMPTY_STRING; + } else { + valueStatus = validatedStatus.getDisplayableName(); + valueDate = new EffectivityDate(validatedStatus.dateReleased()).getFormattedDateForFrenchUser(); + } + String keyStatus = (isCN ? R13Keys.CR.STATUT_CN : R13Keys.STATUT).toString(); + String keyDate = (isCN ? R13Keys.CR.DATE_STATUT_CN : R13Keys.DATE_STATUT).toString(); + Map param = new HashMap<>(); + param.put(keyStatus, valueStatus); + param.put(keyDate, valueDate); + return param; + } + + /** + * Returns the last validated status. If no (valid) status, returns null. + */ + private TcReleaseStatus findLastValidatedStatus(final AbstractChangeObject change) { + TcReleaseStatus selectedStatus = null; + for (TcReleaseStatus status : change.getReleaseStatusContainingMaturity()) { + if (isValid(status, change) && (selectedStatus == null || status.dateReleased().after(selectedStatus.dateReleased()))) { + selectedStatus = status; + } + } + return selectedStatus; + } + + /** + * Validates a status of a change. + * + * @param status the TcReleaseStatus of the change + * @param change the change + * @return true if the status of the change is valid (should be kept) or false if the status ishould be ignored. + */ + protected abstract boolean isValid(final TcReleaseStatus status, final AbstractChangeObject change); + + /** + * Returns a description of the status of all Workflows found to be associated with the provided change item. The provided prefix will be added to each line, unmodified. + * + * @param change the {@link AbstractChangeObject} + * @param prefix the first few columns, pre-calculated + * @return aLine for each task of each workflow (each line contains the provided prefix) + */ + private List> discoverWorkflows(final AbstractChangeObject change, final Map prefix) throws KurtException { + List wkfList = change.getWkfList(); + List> result = new ArrayList<>(); + if (wkfList == null || wkfList.isEmpty()) { + result.add(makeEmptyWkfAndTask(prefix)); + } else { + boolean allWorkflowsAreCompleted = true; + for (Task wkf : wkfList) { + if (wkf.isRunning()) { // Remove workflows when not currently running (aborted, skipped, failed, pending, etc.) + allWorkflowsAreCompleted = false; + Map wkfParam = new HashMap<>(prefix); // Copy input prefix + + // Workflow parameters + wkfParam.put(R13Keys.NOM_TEMPLATE_WKF.toString(), wkf.getName()); + + // Users parameters associated to WKF + SnecmaUser wkfResponsibleUser = wkf.getResponsibleUser() ; + SnecmaPerson wkfResponsiblePerson = wkfResponsibleUser.getPerson(); + String codeCourrier = wkfResponsiblePerson.getCodeCourrier(); + wkfParam.put(R13Keys.ATTACHE_PILOTE_WKF.toString(), (codeCourrier == null || codeCourrier.isEmpty()) ? EMPTY_STRING : codeCourrier); + wkfParam.put(R13Keys.NOM_PILOTE_WKF.toString(), wkfResponsiblePerson.getPersonName()); + wkfParam.put(R13Keys.STATUT_PILOTE_WKF.toString(), userStatus(wkfResponsibleUser)); + + // Active task parameters + result.addAll(discoverActiveTasks(wkf, change, wkfParam)); + } + } + if (allWorkflowsAreCompleted) { + result.add(makeEmptyWkfAndTask(prefix)); + } + } + return result; + } + + /** + * Returns a line for each Active Task of the Workflow. The provided prefix will be added to each line, unmodified. + * + * @param change the change item + * @param prefix the first few columns, pre-calculated + * @return a Line for each active task of the Workflow (each containing the provided prefix) + */ + private List> discoverActiveTasks(final Task rootTask, final AbstractChangeObject change, final Map prefix) throws KurtException { + List activeMotherTasks = rootTask.getActiveChildTasks(); + List> result = new ArrayList<>(); + if (activeMotherTasks == null || activeMotherTasks.isEmpty()) { + // Prepare a line containing the prefix, and "" everywhere else + HashMap copy = new HashMap<>(prefix); + addEmptyTask(copy); + result.add(copy); + } else { + for (Task activeMotherTask : activeMotherTasks) { + // Level 0: task representing the whole "Workflow" + // Level 1: 'Mother' tasks --> obtain name & due date here + // Level 2: 'Daughter' tasks --> These are the 'ACTIVE' tasks, obtain users here + + // Here, we always are on the mother task's level + Map line = new HashMap<>(prefix); // Copy prefix without modify it + + // Warning : if a CR has a CN and both of them have workflows, the CR will have its own workflow and the CN's + if (activeMotherTask.isInTargetAttachments(change)) { + // Task name + line.put(R13Keys.NOM_TACHE.toString(), activeMotherTask.getName()); + + // Due date + Calendar parentDueDate = activeMotherTask.getDueDate(); + if (parentDueDate == null) { + line.put(R13Keys.DATE_CIBLE.toString(), EMPTY_STRING); + line.put(R13Keys.AVANCE_RETARD.toString(), EMPTY_STRING); + } else { + line.put(R13Keys.DATE_CIBLE.toString(), new EffectivityDate(parentDueDate).getFormattedDateForFrenchUser()); + line.put(R13Keys.AVANCE_RETARD.toString(), compareWithDateSystem(parentDueDate)); + } + + // The users are found on the daughter task if it exists + SnecmaUser motherOwner = activeMotherTask.getResponsibleUser(); + List activeChildTasks = activeMotherTask.getActiveChildTasks(); + if (!activeChildTasks.isEmpty()) { + for (Task childTask : activeChildTasks) { + // Add a line for each users (they, however, are found on the daughter task...) + result.addAll(discoverUserTasks(childTask, line, motherOwner)); + } + } else { + // Add a line for each users (they, however, are found on the daughter task...) + result.addAll(discoverUserTasks(activeMotherTask, line, motherOwner)); + } + } + } + } + return result; + } + + private List> discoverUserTasks(final Task childTask, final Map taskParam, SnecmaUser motherOwner) { + List validSignoffsValues = childTask.getPendingSignoffsUser(); // Only users that have not yet validated their task + List> result = new ArrayList<>(); + if (!validSignoffsValues.isEmpty()) { + for (SnecmaUser signoffUser : validSignoffsValues) { + Map personParam = new HashMap<>(taskParam); // Defensive copy of prefix + + // Person parameters + SnecmaPerson signoffPerson = signoffUser.getPerson(); + String codeCourrier = signoffPerson.getCodeCourrier(); + personParam.put(R13Keys.ATTACHE_ACTEUR_TACHE.toString(), + (codeCourrier == null || codeCourrier.isEmpty()) ? EMPTY_STRING : codeCourrier); + personParam.put(R13Keys.NOM_ACTEUR_TACHE.toString(), signoffPerson.getPersonName()); + personParam.put(R13Keys.STATUT_ACTEUR_TACHE.toString(), userStatus(signoffUser)); + + // Add to results list + result.add(personParam); + } + } else { + // Default behavior when no users are active on the daughter task + Map personParam = new HashMap<>(taskParam); // Defensive copy of prefix + SnecmaPerson responsibleUser = motherOwner.getPerson(); + String codeCourrier = responsibleUser.getCodeCourrier(); + personParam.put(R13Keys.ATTACHE_ACTEUR_TACHE.toString(), (codeCourrier == null || codeCourrier.isEmpty()) ? EMPTY_STRING : codeCourrier); + personParam.put(R13Keys.NOM_ACTEUR_TACHE.toString(), responsibleUser.getPersonName()); + personParam.put(R13Keys.STATUT_ACTEUR_TACHE.toString(), userStatus(motherOwner)); + result.add(personParam); + } + return result; + } + + String compareWithDateSystem(final Calendar dueDate) { + long epochToDueDate = daysSinceEpoch(dueDate); + long epochToToday = daysSinceEpoch(Calendar.getInstance()); + long diff = epochToDueDate - epochToToday; + return String.valueOf(diff); + } + + /** + * Returns the number of days elapsed since {@link Calendar}'s Epoch (Jan, 1st 1970) until the beggining of the provided Calendar's day : midnight 00:00:000).
+ * Ex: + *
    + *
  • if Calendar is Jan, 1st 1970, 00h:00m:00s:000): 000000000 ms
  • + *
  • if Calendar is Jan, 1st 1970, 00h:00m:00s:125): 000000125 ms
  • + *
  • if Calendar is Jan, 1st 1970, 00h:00m:05s:125): 000005125 ms
  • + *
  • if Calendar is Jan, 1st 1970, 00h:01m:05s:125): 000065125 ms
  • + *
  • if Calendar is Jan, 1st 1970, 01h:00m:05s:125): 003605125 ms
  • + *
  • if Calendar is Jan, 3rd 1970, 00h:00m:00s:000): 259200000 ms
  • + *
  • if Calendar is Jan, 3rd 1970, 00h:00m:05s:125): 259205125 ms
  • + *
+ * + * @param dueDate the Date to calculate + * @return the number of milliseconds elapsed since {@link Calendar}'s Epoch (Jan, 1st 1970) until the beggining of the provided Calendar's day : midnight 00:00:000) + */ + private long daysSinceEpoch(final Calendar dueDate) { + return dueDate.getTimeInMillis() / MILLIS_PER_DAY; // TRUNCATE to remove any trace of time spend past midnight + } + + private Map makeEmptyWkfAndTask(final Map param) { + param.put(R13Keys.NOM_TEMPLATE_WKF.toString(), EMPTY_STRING); + param.put(R13Keys.ATTACHE_PILOTE_WKF.toString(), EMPTY_STRING); + param.put(R13Keys.NOM_PILOTE_WKF.toString(), EMPTY_STRING); + param.put(R13Keys.STATUT_PILOTE_WKF.toString(), EMPTY_STRING); + addEmptyTask(param); + return param; + } + + private void addEmptyTask(final Map taskParam) { + taskParam.put(R13Keys.NOM_TACHE.toString(), EMPTY_STRING); + taskParam.put(R13Keys.ATTACHE_ACTEUR_TACHE.toString(), EMPTY_STRING); + taskParam.put(R13Keys.NOM_ACTEUR_TACHE.toString(), EMPTY_STRING); + taskParam.put(R13Keys.STATUT_ACTEUR_TACHE.toString(), EMPTY_STRING); + taskParam.put(R13Keys.DATE_CIBLE.toString(), EMPTY_STRING); + taskParam.put(R13Keys.AVANCE_RETARD.toString(), EMPTY_STRING); + } + + private Map putEmptyLine() { + Map mapPrinter = makeEmptyWkfAndTask(new HashMap()); + mapPrinter.put(R13Keys.ATTACHE_PILOTE.toString(), EMPTY_STRING); + mapPrinter.put(R13Keys.NOM_PILOTE.toString(), EMPTY_STRING); + mapPrinter.put(R13Keys.STATUT_PILOTE.toString(), EMPTY_STRING); + mapPrinter.put(R13Keys.ITEM_ID.toString(), EMPTY_STRING); + mapPrinter.put(R13Keys.ITEM_REVISION.toString(), EMPTY_STRING); + mapPrinter.put(R13Keys.DATE_CREATION.toString(), EMPTY_STRING); + mapPrinter.put(R13Keys.DESIGNATION.toString(), EMPTY_STRING); + mapPrinter.put(R13Keys.LIGNE_PRODUIT.toString(), EMPTY_STRING); + mapPrinter.put(R13Keys.TYPE.toString(), EMPTY_STRING); + mapPrinter.put(R13Keys.STATUT.toString(), EMPTY_STRING); + mapPrinter.put(R13Keys.DATE_STATUT.toString(), EMPTY_STRING); + mapPrinter.put(R13Keys.CR.PARTS_CHANGE_REQUEST.toString(), EMPTY_STRING); + mapPrinter.put(R13Keys.FPP.PARTS_FPP.toString(), EMPTY_STRING); + specificTreatmentEmptyLines(mapPrinter); + return mapPrinter; + } + + private String userStatus(final SnecmaUser user) { + return (user.isActive()) ? ACTIF : INACTIF; + } + + protected abstract void specificTreatmentEmptyLines(final Map mapPrinter); +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/printer/R13PrinterCR.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/printer/R13PrinterCR.java new file mode 100644 index 0000000..879f8c5 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/printer/R13PrinterCR.java @@ -0,0 +1,246 @@ +package com.capgemini.reports.definition.r13report.printer; + +import com.capgemini.framework.common.LanguageHelper; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.object.pom.status.TcEffectivity; +import com.capgemini.framework.teamcenter.object.pom.status.TcReleaseStatus; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.resolution.filtering.TcTypeExclusionFilter; +import com.capgemini.reports.changeobjects.change.AbstractChangeObject; +import com.capgemini.reports.changeobjects.change.FPPRevision; +import com.capgemini.reports.changeobjects.change.TcChangeNoticeRevision; +import com.capgemini.reports.changeobjects.change.TcChangeRequestRevision; +import com.capgemini.reports.definition.r13report.R13Keys; +import com.capgemini.reports.definition.r13report.execution.ExecutionR13CR; +import com.capgemini.reports.execution.mapconstructor.IMapConstructor; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.snecmaobjects.generic.AbstractGeneric; +import com.google.common.base.Joiner; +import lombok.EqualsAndHashCode; + +import java.util.*; + +import static com.capgemini.reports.changeobjects.change.AbstractChangeObject.getItemIdFromModelObjectSetToString; + +/** + * Printer of a R13 Report for CR objects. + */ +@EqualsAndHashCode(callSuper = true) +public class R13PrinterCR extends AbstractR13Printer implements IMapConstructor> { + private static final long serialVersionUID = 7886687130935534458L; + + private static final String CN_DEPRECIE_REVISION = "CN Déprécié Revision"; + private static final String PV4_CN_DEPREC_REVISION = "PV4_CN_DEPRECRevision"; + private static final String EMPTY_STRING = ""; + private static final String SAUT_LIGNE = "\n"; + private static final String COMMA = " , "; + + @Override + protected LinkedHashMap> getChangeObjectData(final TcChangeRequestRevision change, final Map typeObjectParam) { + Map prefix = new HashMap<>(typeObjectParam); + + // Add FPP cell (optional) + decoratePrefixWithFpp(change, prefix); + + // CR properties + prefix.put(R13Keys.TYPE.toString(), LanguageHelper.french(change.getTypeModSupportProcess())); + prefix.put(R13Keys.CR.EFFECTIVITES.toString(), getEffectivityValue(change)); + prefix.put(R13Keys.CR.PARTS_CHANGE_REQUEST.toString(),getItemIdFromModelObjectSetToString(change.getPartsFromApresPseudoFolder(null))); + + // Discover CNs (1 CN -> 1 additional line) and extract their prefixes + return discoverCN(change, prefix); + } + + private void decoratePrefixWithFpp(final TcChangeRequestRevision change, final Map param) { + List fppList = change.getFppList(); + if (fppList == null || fppList.isEmpty()) { + emptyFPP(param); // No FPP, empty cell + } + else { + StringBuilder builderId = new StringBuilder(); + StringBuilder builderRev = new StringBuilder(); + boolean firstPass = true; + for (FPPRevision fpp : fppList) { + if (firstPass) { + builderId.append(fpp.getItemId()); + builderRev.append(fpp.getRevisionId()); + firstPass = false; + } + else { + builderId.append(SAUT_LIGNE).append(fpp.getItemId()); // If several FPPs are found, add them all in the same cell with a new line + builderRev.append(SAUT_LIGNE).append(fpp.getRevisionId()); + } + } + param.put(R13Keys.CR.ID_PROBLEM_REPORT.toString(), builderId.toString()); + param.put(R13Keys.CR.REVISION_PROBLEM_REPORT.toString(), builderRev.toString()); + } + } + + /** + * Concatenates all effectivities of the ChangeRequest in a String. + * + * @param change the change + * @return a String containing all effectivities, comma-separated + */ + private String getEffectivityValue(final TcChangeRequestRevision change) { + StringBuilder builder = new StringBuilder(); + List statuses = change.getReleaseStatusContainingEffectivity(); + if (statuses != null && !statuses.isEmpty()) { + boolean firstPass = true; + for (TcReleaseStatus status : statuses) { + // Must check because only the TcEffectivity are wanted (and not Set_Effectivity, Old effectivity, Interface todo) + if (SnecmaObjectTypes.EFFECTIVITY.equals(status.getStatusEnum().getIdentifier())) { + for (TcEffectivity effectivity : status.getEffectivities()) { + if (firstPass) { + firstPass = false; + } + else { + builder.append(COMMA); + } + effectivitySentence(builder, effectivity); + } + } + } + } + return builder.toString(); + } + + /** + * Appends the {@link TcEffectivity} description to the {@link StringBuilder}. + */ + private void effectivitySentence(final StringBuilder builder, final TcEffectivity effectivityBuilt) { + String articleFinalId = effectivityBuilt.endItemId(); + builder.append(articleFinalId).append('['); + String unitRange = effectivityBuilt.unitRange(); + if (unitRange.isEmpty()) { + builder.append(effectivityBuilt.dateRange()); + } + else { + builder.append(unitRange); + } + builder.append(']'); + } + + /** + * Complete the CN columns + * @param change + * @param fppCrPrefix + * @return LinkedHashMap> + */ + private LinkedHashMap> discoverCN(final TcChangeRequestRevision change, + final Map fppCrPrefix) { + LinkedHashMap> result = new LinkedHashMap<>(); + // Put a line with the CR alone + Map emptyCnData = makeEmptyCN(fppCrPrefix); + // Override module with CR modules + Set crModuleValues = getModuleValues(change); + emptyCnData.put(R13Keys.CR.MODULES.toString(), StringHelper.implodeList(COMMA, crModuleValues)); + result.put(change, emptyCnData); + + // Now put an extra line for every CN found + for (TcChangeNoticeRevision changeNotice : change.getChangeNoticesList(new TcTypeExclusionFilter(CN_DEPRECIE_REVISION, PV4_CN_DEPREC_REVISION), StatusEnum.forbid(StatusEnum.FINISHED, StatusEnum.CANCELLED))) { + Map cnParam = new HashMap<>(fppCrPrefix); // Copy prefix without modifying it + + // Users parameters of the CN + cnParam.putAll(makeUserParameters(changeNotice)); + + // ChangeNotice parameters + Set cnModuleValues = getModuleValues(changeNotice); + cnParam.put(R13Keys.CR.MODULES.toString(), StringHelper.implodeList(COMMA, cnModuleValues)); + cnParam.put(R13Keys.CR.ITEM_ID_CN.toString(), changeNotice.getItemId()); + cnParam.put(R13Keys.CR.ITEM_REVISION_CN.toString(), changeNotice.getRevisionId()); + cnParam.put(R13Keys.CR.DATE_CREATION_CN.toString(), new EffectivityDate(changeNotice.getDateCreation()).getFormattedDateForFrenchUser()); + cnParam.put(R13Keys.CR.LIGNE_PRODUIT_CN.toString(), Joiner.on(StringHelper.LINE_FEED).join(changeNotice.getLignesProduit())); + cnParam.put(R13Keys.CR.DESIGNATION_CN.toString(), changeNotice.getChangeName()); + cnParam.put(R13Keys.CR.TYPE_CN.toString(), LanguageHelper.french(changeNotice.getTypeModification())); + cnParam.put(R13Keys.CR.PARTS_CHANGE_NOTICE.toString(), getItemIdFromModelObjectSetToString(changeNotice.getPartsFromApresPseudoFolder(null))); + // Validated status of object parameters + cnParam.putAll(makeReleaseStatusParameters(changeNotice)); + + // Register this ChangeNotice for further processing (wkf, tasks etc.) + result.put(changeNotice, cnParam); + } + return result; + } + + /** + * Complete CN columns with empty strings + * @param param + * @return Map + */ + private Map makeEmptyCN(final Map param) { + Map result = new HashMap<>(param); + result.put(R13Keys.CR.ATTACHE_PILOTE_CN.toString(), EMPTY_STRING); + result.put(R13Keys.CR.NOM_PILOTE_CN.toString(), EMPTY_STRING); + result.put(R13Keys.CR.STATUT_PILOTE_CN.toString(), EMPTY_STRING); + result.put(R13Keys.CR.MODULES.toString(), EMPTY_STRING); + result.put(R13Keys.CR.ITEM_ID_CN.toString(), EMPTY_STRING); + result.put(R13Keys.CR.ITEM_REVISION_CN.toString(), EMPTY_STRING); + result.put(R13Keys.CR.DATE_CREATION_CN.toString(), EMPTY_STRING); + result.put(R13Keys.CR.LIGNE_PRODUIT_CN.toString(), EMPTY_STRING); + result.put(R13Keys.CR.DESIGNATION_CN.toString(), EMPTY_STRING); + result.put(R13Keys.CR.TYPE_CN.toString(), EMPTY_STRING); + result.put(R13Keys.CR.STATUT_CN.toString(), EMPTY_STRING); + result.put(R13Keys.CR.DATE_STATUT_CN.toString(), EMPTY_STRING); + result.put(R13Keys.CR.PARTS_CHANGE_NOTICE.toString(), EMPTY_STRING); + return result; + } + + /** + * Compiles the content required for the 'Module' column. + * + * @param changeRequest the {@link TcChangeRequestRevision} of the line + * @return the module column's content + */ + private Set getModuleValues(final TcChangeRequestRevision changeRequest) { + Set moduleNames = new TreeSet<>(); + // Obtain modules in gens with or without rupture of the CR + for (AbstractGeneric gen : changeRequest.getListOfGenericRevWithOrWithoutRupture()) { + moduleNames.add(getModuleName(gen)); + } + // Append all Generics in gens with/without rupture of all child CNs + for (TcChangeNoticeRevision cn : changeRequest.getChangeNoticesList(new TcTypeExclusionFilter(CN_DEPRECIE_REVISION, PV4_CN_DEPREC_REVISION), StatusEnum.forbid(StatusEnum.FINISHED, StatusEnum.CANCELLED))) { + moduleNames.addAll(getModuleValues(cn)); + } + return moduleNames; + } + + /** + * Compiles the content required for the 'Module' column. + * + * @param changeNotice the {@link TcChangeRequestRevision} of the line + * @return the module column's content + */ + private Set getModuleValues(final TcChangeNoticeRevision changeNotice) { + Set moduleNames = new TreeSet<>(); + for (AbstractGeneric gen : changeNotice.getListOfGenericRevWithOrWithoutRupture()) { + String moduleName = getModuleName(gen); + moduleNames.add(moduleName); + } + return moduleNames; + } + + private String getModuleName(final AbstractGeneric gen) { + return gen.getItemId(); + } + + @Override + protected boolean isValid(final TcReleaseStatus status, final AbstractChangeObject change) { + // If change is neither a CR nor a CN, it is not valid + return (change instanceof TcChangeRequestRevision) || (change instanceof TcChangeNoticeRevision); + } + + @Override + protected void specificTreatmentEmptyLines(final Map mapPrinter) { + emptyFPP(mapPrinter); + mapPrinter.put(R13Keys.CR.EFFECTIVITES.toString(), EMPTY_STRING); + mapPrinter.putAll(makeEmptyCN(mapPrinter)); // replace all entries back into the input map + } + + private void emptyFPP(final Map mapPrinter) { + mapPrinter.put(R13Keys.CR.ID_PROBLEM_REPORT.toString(), EMPTY_STRING); + mapPrinter.put(R13Keys.CR.REVISION_PROBLEM_REPORT.toString(), EMPTY_STRING); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/printer/R13PrinterFPP.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/printer/R13PrinterFPP.java new file mode 100644 index 0000000..c761002 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r13report/printer/R13PrinterFPP.java @@ -0,0 +1,53 @@ +package com.capgemini.reports.definition.r13report.printer; + +import com.capgemini.framework.common.LanguageHelper; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.object.pom.status.TcReleaseStatus; +import com.capgemini.reports.changeobjects.change.AbstractChangeObject; +import com.capgemini.reports.changeobjects.change.FPPRevision; +import com.capgemini.reports.definition.r13report.R13Keys; +import com.capgemini.reports.definition.r13report.execution.ExecutionR13FPP; +import com.capgemini.reports.execution.mapconstructor.IMapConstructor; +import lombok.EqualsAndHashCode; + +import java.util.*; + +import static com.capgemini.reports.changeobjects.change.AbstractChangeObject.getItemIdFromModelObjectSetToString; + +/** + * Printer of a R13 Report for FPP objects. + */ +@EqualsAndHashCode(callSuper = true) +public class R13PrinterFPP extends AbstractR13Printer implements IMapConstructor> { + private static final long serialVersionUID = 6460682170787086789L; + + @Override + protected Map> getChangeObjectData(final FPPRevision fpp, final Map typeObjectParam) { + // copyParameters + Map prefixCopy = new HashMap<>(typeObjectParam); + + // Add specific FPP parameters + prefixCopy.put(R13Keys.TYPE.toString(), LanguageHelper.french(fpp.getOrigineDemande())); + prefixCopy.put(R13Keys.FPP.PARTS_FPP.toString(), getItemIdFromModelObjectSetToString(fpp.getPartsOfSubModifications())); + + Map> result = new LinkedHashMap<>(); + result.put(fpp, prefixCopy); // Only ever one object here (the original FPP) + + // Workflow and active task parameters + return result; + } + + @Override + protected boolean isValid(final TcReleaseStatus status, final AbstractChangeObject change) { + boolean validStatus = false; + if (status.getStatusEnum() == StatusEnum.J0) { + validStatus = true; + } + return validStatus; + } + + @Override + protected void specificTreatmentEmptyLines(final Map mapPrinter) { + // No sepcific treatment + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/AbstractDataReportPreparatorR15R16R17.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/AbstractDataReportPreparatorR15R16R17.java new file mode 100644 index 0000000..2f9b592 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/AbstractDataReportPreparatorR15R16R17.java @@ -0,0 +1,206 @@ +package com.capgemini.reports.definition.r15r16r17reports; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.documentationobjects.DocNorm; +import com.capgemini.reports.documentationobjects.DocNormStandard; +import com.capgemini.reports.documentationobjects.DocTechnic; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.releasestatus.RevisionStatusAndDate; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import com.capgemini.reports.teamcenter.ObjectInfoHelper; +import com.google.common.base.Optional; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +/** + * Abstract Class whose goal is to prepare common data to R15 R16 R17 reports. + * + * @param the report {@link AbstractExecutionR15R16R17} + */ +@Slf4j +@EqualsAndHashCode +public abstract class AbstractDataReportPreparatorR15R16R17> implements IDataReportPreparator { + private static final long serialVersionUID = 4533353562306975227L; + + private static final String REC_DEFINITION = "REC-Définition de récupération / Recovery design"; + private static final String MCI_MASSE_CENTRE_DE_GRAVITE = "MCI-Masse, Centre de gravité et inertie / Mass, gravity center and inertia"; + private static final int MINIMUM_SECURITY_LEVEL_FOR_WATERMARK = 3; + private static final String PROP_PS_PARENTS = "ps_parents"; + private static final String REALISATION_ACHIEVEMENT = "Réalisation / Achievement"; + + /** + * Get the date in a specific format for Reports. + * + * @param calendar {@link Calendar} - a calendar + * @return the {@link String} value + */ + protected String getDateFormatDayMonthYear(final Calendar calendar) { + SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy"); + return sdf.format(calendar.getTime()); + } + + /** + * Returns true if the watermark should be present in the report.
+ * It should be present if any of the DocNorm or DocTechnic is considered as "sensible". + * + * @param report - the execution report which provide all informations for the report + * @return true if the watermark should be present in the report + */ + protected boolean isConfidential(final T report) { + for (DocNorm docNorm : report.docNormList) { + String niveauSensibilite = docNorm.getNiveauSensibilite(); + String sensibiliteSecurite = docNorm.getSensibiliteSecurite(); + log.debug("DocNorm " + docNorm.getDocId() + ": niveauSensibilite = " + niveauSensibilite + ", sensibiliteSecurite = " + sensibiliteSecurite); + if (sensibiliteAttributesAreConfidential(niveauSensibilite, sensibiliteSecurite)) { + return true; + } + } + for (DocTechnic docTechnic : report.docTechnicList) { + String niveauSensibilite = docTechnic.getNiveauSensibilite(); + String sensibiliteSecurite = docTechnic.getSensibiliteSecurite(); + log.debug("DocTechnic " + docTechnic.getDocId() + ": niveauSensibilite = " + niveauSensibilite + ", sensibiliteSecurite = " + sensibiliteSecurite); + if (sensibiliteAttributesAreConfidential(niveauSensibilite, sensibiliteSecurite)) { + return true; + } + } + return false; + } + + /** + * This method check values of attributes ip_classification and pv_sensibilite_securite of a DocNorm or a DocTechnic. + * + * @param niveauSensibilite value of ip_classification attribute + * @param sensibiliteSecurite value of pv_sensibilite_securite attribute + * @return true if 'niveau de sensibilite' value contains 'C3' or C4' string + * or if 'niveau de sensibilite' is empty or doesn't contain 'C3' or 'C4' but 'sensibilité securité' has a value of 3 or 4. + * */ + protected boolean sensibiliteAttributesAreConfidential(String niveauSensibilite, String sensibiliteSecurite) { + if (niveauSensibilite != null && (niveauSensibilite.contains("C3") || niveauSensibilite.contains("C4"))) { + return true; + } else { + if (sensibiliteSecurite != null && !sensibiliteSecurite.isEmpty() + && Integer.valueOf(sensibiliteSecurite) >= MINIMUM_SECURITY_LEVEL_FOR_WATERMARK) { + return true; + } + } + return false; + } + + /** + * Returns true if this report execution generated an empty table of documents (no doc found). + * + * @param report - the execution report which provide all informations for the report + * @return true if the table of documents is empty + */ + public boolean isEmptyTable(final T report) { + return report.getDocNormList().isEmpty() && report.getDocNormStandardList().isEmpty() && report.getDocTechnicList().isEmpty(); + } + + /** + * Get the parents with the ps_parents property.
+ * Filter with a wanted type. + * + * @param session {@link TcSession} - the tc session + * @param refObject {@link ItemRevision} - the reference object + * @param typeWanted {@link SnecmaObjectTypes} the selected type we need + * @return List the parents of the reference object + */ + protected List getPsParentsOfPart(final TcSession session, final ItemRevision refObject, final String typeWanted) { + List results = new ArrayList<>(); + session.loadProperties(refObject, PROP_PS_PARENTS); + ModelObject[] parents = refObject.get_ps_parents(); + session.loadProperties(parents); + for (ModelObject object : parents) { + ItemRevision itemRev = (ItemRevision) object; + if (typeWanted.equals(itemRev.getTypeObject().getName())) { + results.add(itemRev); + } + } + return results; + } + + /** + * Retrieve the {@link DocNorm} and the {@link DocNormStandard} in their respective {@link List}s. + * + * @param session {@link TcSession} - the tc session + * @param itemRevision {@link ItemRevision} - the object which possess all the documents + * @param report - the execution report which provide all informations for the report + */ + protected void retrieveDocNormAndDocNormStandardLists(final TcSession session, final ItemRevision itemRevision, final T report) { + List referenceDoclist = AbstractPart.returnReferenceDocuments(session, itemRevision); + if (!referenceDoclist.isEmpty()) { + for (Item docItem : referenceDoclist) { + if (docItem == null) { + continue; + } + String docType = docItem.getTypeObject().getName(); + if (SnecmaObjectTypes.DOC_NORM.equals(docType)) { + ItemRevision selectedDocRev = getDocNormAndDocNormStandardRevisions(session, docItem.get_item_id()); + report.docNormList.add(new DocNorm(session, selectedDocRev)); + } else if (SnecmaObjectTypes.DOC_NORM_STANDARD.equals(docType)) { + ItemRevision selectedDocRev = getDocNormAndDocNormStandardRevisions(session, docItem.get_item_id()); + report.docNormStandardList.add(new DocNormStandard(session, selectedDocRev)); + } + } + } + } + + private ItemRevision getDocNormAndDocNormStandardRevisions(final TcSession session, final String docId) { + // Retrieve the revisions + List listOfDocNormRev = new ItemRevisionQuery(session).searchID(docId).findAll(); + // Try to obtain the revision with the latest release date... + Optional selectedDocRev = ObjectInfoHelper.getRevisionFromStatusWithMostRecentReleaseDate(session, listOfDocNormRev, Calendar.getInstance(), StatusEnum.PUBLISHED, StatusEnum.FROZEN); + if (selectedDocRev.isPresent()) { + return selectedDocRev.get(); + } else { + // No release date found, now obtain the revision with latest modification date + RevisionStatusAndDate revAndStatus = ObjectInfoHelper.getRevisionAndStatusWithMostRecentModificationDate(listOfDocNormRev, Calendar.getInstance()); + return revAndStatus.getItemRevision(); + } + } + + /** + * Retrieve the {@link DocTechnic} in a {@link List}. + */ + protected void retrieveDocTechnicList(final TcSession session, final ItemRevision partItemRevision, final T report) { + List technicDocObjects = AbstractPart.returnDefinitionDocuments(session, partItemRevision); + if (!technicDocObjects.isEmpty()) { + for (ItemRevision docTechnicRev : technicDocObjects) { + if (docTechnicRev != null) { + report.docTechnicList.add(new DocTechnic(session, docTechnicRev)); + } + } + } + } + + /** + * Filter the DocTechnic with specific values on the type_doc_technic_1 and type_doc_technic_2 properties. + * + * @param report - the execution report which provide all informations for the report + */ + protected void filterDocTechnic(final T report) { + List transitList = new ArrayList<>(); + for (DocTechnic docTechnic : report.docTechnicList) { + // These values are forbidden + String typeDocTechnic1 = docTechnic.getTypeDocTechnic1(); + String typeDocTechnic2 = docTechnic.getTypeDocTechnic2(); + if (!(REALISATION_ACHIEVEMENT.equals(typeDocTechnic1) + && (MCI_MASSE_CENTRE_DE_GRAVITE.equals(typeDocTechnic2) || REC_DEFINITION.equals(typeDocTechnic2)))) { + transitList.add(docTechnic); + } + } + report.docTechnicList.clear(); + report.docTechnicList.addAll(transitList); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/AbstractExecutionR15R16R17.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/AbstractExecutionR15R16R17.java new file mode 100644 index 0000000..d139712 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/AbstractExecutionR15R16R17.java @@ -0,0 +1,66 @@ +package com.capgemini.reports.definition.r15r16r17reports; + +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.documentationobjects.DocNorm; +import com.capgemini.reports.documentationobjects.DocNormStandard; +import com.capgemini.reports.documentationobjects.DocTechnic; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.List; + + +/** + * Prepare the common data for report 15, 16 and 17. + * + * @param Generic object for a report + */ +@Getter +@Setter +@EqualsAndHashCode(callSuper = true) +public abstract class AbstractExecutionR15R16R17> extends AbstractExecutionReport { + protected static final String FRENCH_LANGUAGE = "Francais"; + private static final long serialVersionUID = 4911952011990726425L; + // Report parameters + protected final boolean french; + protected final String frenchInput; + protected final String itemId; + // Documents gathered + protected final List docNormList = new ArrayList<>(); + protected final List docNormStandardList = new ArrayList<>(); + protected final List docTechnicList = new ArrayList<>(); + // Data gathered + protected String dateReleased = ""; + protected String revisionArticle = ""; + protected String produitUnit = ""; + protected String typeProduit; + protected String clausePropriete; + + /** + * Builds the super class which helps to execute a R15 R16 or 17 reports. + * + * @param itemID {@link String} - the Id of the top Item + * @param language {@link String} - the chosen language + * @param priorityCode int - the priority code found in the reporting.properties file associated to a report. + * @param revisionRule {@link String} - the revision rule for resolution structure + * @param launchType {@link ReportLaunchTypeEnum} - the launch type of the report + */ + public AbstractExecutionR15R16R17(final String itemID, final String language, final int priorityCode, final String revisionRule, + final ReportLaunchTypeEnum launchType) { + super(priorityCode, revisionRule, launchType); + this.frenchInput = language; + this.french = isFrench(language); + this.itemId = itemID; + } + + protected static boolean isFrench(final String language) { + return FRENCH_LANGUAGE.equals(language); + } + + @Override + public abstract IDataReportPreparator getDataPreparator(); +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/AbstractR15R16R17Printer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/AbstractR15R16R17Printer.java new file mode 100644 index 0000000..0cb70b5 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/AbstractR15R16R17Printer.java @@ -0,0 +1,190 @@ +package com.capgemini.reports.definition.r15r16r17reports; + +import com.capgemini.framework.common.LanguageHelper; +import com.capgemini.framework.common.ResourceHelper; +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.reports.definition.r15r16r17reports.R15R16R17R24R25Keys.Page2; +import com.capgemini.reports.documentationobjects.DocNorm; +import com.capgemini.reports.documentationobjects.DocNormStandard; +import com.capgemini.reports.documentationobjects.DocTechnic; +import com.capgemini.reports.exceptions.FileLoadingException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.mapconstructor.AbstractStaticTemplateMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +/** + * This class allows printing of severel elements that are found in both the R15, R16 and R17 reports. + * + * @param describes which report's {@link AbstractExecutionReport} this printer will print. Must be a subclass of {@link AbstractExecutionR15R16R17}. + */ +@Slf4j +@EqualsAndHashCode(callSuper = true) +public abstract class AbstractR15R16R17Printer> extends AbstractStaticTemplateMapConstructor { + private static final long serialVersionUID = 6114330530182125707L; + + private static final String SNECMA_LOGO_PNG = "/Jasper/images/Snecma_logo.png"; + private static final String CONFIDENTIEL_INDUSTRIE_JPG = "/Jasper/images/confidentiel_industrie.jpg"; + private static final String N_A = "N/A"; + private static final int INT_3 = 3; + private static final List PRODUCT_TYPES_LIST = SettingsHelper.getProductTypes(); + + /** + * Returns true if the product is in the product types list.
+ * It means that the DocDrawing id could'nt be available in the report.
+ * Their id values should be replaced by the id of the Part. + * + * @param productType {@link String} - the product type + * @return true if it is not authorized, false otherwise + */ + protected static boolean isNotAuthorized(final String productType) { + if (productType == null || productType.isEmpty()) { + return false; + } + + // Take the three letters of the left side of the product type value + String type =(productType.length() preparator = (AbstractDataReportPreparatorR15R16R17) execution.getDataPreparator(); + mainReport.addReportParameters(setupStringParameters(execution)); + mainReport.addReportParameter(R15R16R17R24R25Keys.EMPTY_TABLE.toString(), preparator.isEmptyTable(execution)); + try { + mainReport.addReportParameter(R15R16R17R24R25Keys.SNECMA_LOGO, ResourceHelper.loadImage(SNECMA_LOGO_PNG)); + } catch (FileLoadingException e) { + log.warn("Could not read the Snecma logo", e); + } + + if (preparator.isConfidential(execution)) { + try { + mainReport.addReportParameter(R15R16R17R24R25Keys.WATERMARK, ResourceHelper.loadImage(CONFIDENTIEL_INDUSTRIE_JPG)); + } catch (FileLoadingException e) { + log.warn("Could not read the 'confidentiel industrie' watermark", e); + } + } + mainReport.addReportDataFromEnum(setupData(execution)); + + // Now add the specific stuff + addOptionalParameters(execution, mainReport); + } + + protected Map setupStringParameters(final T execution) { + Map params = new EnumMap<>(R15R16R17R24R25Keys.class); + params.put(R15R16R17R24R25Keys.CLAUSE_PROPRIETE, execution.getClausePropriete()); + params.put(R15R16R17R24R25Keys.PRODUCT_TYPE, execution.getTypeProduit()); + params.put(R15R16R17R24R25Keys.REPORT_TITLE, getTitle(execution)); + params.put(R15R16R17R24R25Keys.ITEM_REVISION_ID, execution.getRevisionArticle()); + String dateReleased = execution.getDateReleased(); + params.put(R15R16R17R24R25Keys.RELEASE_DATE, execution.isFrench() ? french(dateReleased) : english(dateReleased)); + return params; + } + + private List> setupData(final T execution) { + List> dataTable = new ArrayList<>(); + boolean isFrench = execution.isFrench(); + for (DocNorm norm : execution.getDocNormList()) { + dataTable.add(getDocNormLine(norm, isFrench)); + } + for (DocNormStandard normStd : execution.getDocNormStandardList()) { + dataTable.add(getDocNormStandardLine(normStd, isFrench)); + } + for (DocTechnic technic : execution.getDocTechnicList()) { + dataTable.add(getDocTechnicLine(technic, isFrench)); + } + + dataTable.addAll(addExtraDocLines(execution)); + + // If there are no documents, add an empty line to provoke band printing + if (dataTable.isEmpty()) { + Map line = new EnumMap<>(Page2.class); + line.put(Page2.DOC_NUMBER, "(No document found)"); + line.put(Page2.ISSUE, N_A); + line.put(Page2.DOC_TYPE, N_A); + line.put(Page2.DOC_TITLE, N_A); + dataTable.add(line); + } + return dataTable; + } + + protected abstract List> addExtraDocLines(final T execution); + + protected Map getDocNormLine(final DocNorm docNorm, final boolean isFrench) { + String idOrigine = docNorm.getIdOrigine(); + Map line = new EnumMap<>(Page2.class); + line.put(Page2.DOC_NUMBER, (idOrigine == null || idOrigine.isEmpty()) ? docNorm.getDocId() : idOrigine); + line.put(Page2.ISSUE, "-"); + String typeDocNorm = docNorm.getTypeDocNorm(); + line.put(Page2.DOC_TYPE, isFrench ? french(typeDocNorm) : english(typeDocNorm)); + line.put(Page2.DOC_TITLE, isFrench ? docNorm.getItemName() : docNorm.getDesignationEn()); + return line; + } + + protected Map getDocNormStandardLine(final DocNormStandard normStd, final boolean isFrench) { + Map line = new EnumMap<>(Page2.class); + String idOrigine = normStd.getIdOrigine(); + line.put(Page2.DOC_NUMBER, (idOrigine == null || idOrigine.isEmpty()) ? normStd.getDocId() : idOrigine); + line.put(Page2.ISSUE, "-"); + line.put(Page2.DOC_TYPE, isFrench ? "Norme pour articles standards" : "Norm for standards items"); + line.put(Page2.DOC_TITLE, isFrench ? normStd.getItemName() : normStd.getDesignationEn()); + return line; + } + + protected Map getDocTechnicLine(final DocTechnic technic, final boolean isFrench) { + Map line = new EnumMap<>(Page2.class); + String idOrigine = technic.getIdOrigine(); + line.put(Page2.DOC_NUMBER, (idOrigine == null || idOrigine.isEmpty()) ? technic.getDocId() : idOrigine); + line.put(Page2.ISSUE, technic.getIndice()); + + String typeDocTechnic1 = technic.getTypeDocTechnic1(); + String type1 = isFrench ? french(typeDocTechnic1) : english(typeDocTechnic1); + String typeDocTechnic2 = technic.getTypeDocTechnic2(); + String type2 = isFrench ? french(typeDocTechnic2) : english(typeDocTechnic2); + line.put(Page2.DOC_TYPE, type1 + " / " + type2); + + line.put(Page2.DOC_TITLE, isFrench ? technic.getName() : technic.getDesignationEn()); + return line; + } + + /** + * Adds parameters that are not common to R15-R16-R17 reports. + * + * @param execution the data-bearing {@link AbstractExecutionR15R16R17} + * @param mainReport the {@link PrintParameters} + */ + protected abstract void addOptionalParameters(final T execution, final PrintParameters mainReport); + + protected abstract String getTitle(final T execution); + + protected abstract IComponentVisitor> getVisitor(final boolean isFrench); +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/CommunR15R16R17ComponentVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/CommunR15R16R17ComponentVisitor.java new file mode 100644 index 0000000..e3823c4 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/CommunR15R16R17ComponentVisitor.java @@ -0,0 +1,222 @@ +package com.capgemini.reports.definition.r15r16r17reports; + +import com.capgemini.framework.common.LanguageHelper; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAGRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision; +import com.capgemini.reports.snecmaobjects.generic.AbstractGenericRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericAssembRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.mockup.MockupRevision; +import com.capgemini.reports.snecmaobjects.part.*; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartAssembRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartRevision; +import com.capgemini.reports.snecmaobjects.supermodel.SuperModelRevision; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; + +import java.util.EnumMap; +import java.util.Map; + +/** + * Visitor for a R15 or a R17 report. + */ +public class CommunR15R16R17ComponentVisitor implements IComponentVisitor> { + + private static final String YES = "Yes"; + private static final String OUI = "Oui"; + private static final String DASH_STR = "-"; + private static final long serialVersionUID = -4111258059351094185L; + private static final String SANS_OBJET = "Sans objet"; + private static final String NOT_APPLICABLE = "Not applicable "; + private final boolean isFrench; + + /** + * Constructor. + * + * @param isFrench boolean - the language of the report. + */ + public CommunR15R16R17ComponentVisitor(final boolean isFrench) { + this.isFrench = isFrench; + } + + private static String french(final String string) { + return LanguageHelper.french(string); + } + + private static String english(final String string) { + return LanguageHelper.english(string); + } + + @Override + public Map visitComponent(final ProductRevision aProductRev) { + // No use + return null; + } + + @Override + public Map visitComponent(final GenericRevision aGenericRev) { + return giveGenericProperties(aGenericRev); + } + + @Override + public Map visitComponent(SuperModelRevision aSuperModelRev) { + return null; + } + + @Override + public Map visitComponent(final GenericAssembRevision aGenericAssembRev) { + return giveGenericProperties(aGenericAssembRev); + } + + private Map giveGenericProperties(final AbstractGenericRevision aGenericRev) { + Map theMap = new EnumMap<>(R15R16R17R24R25Keys.class); + theMap.put(R15R16R17R24R25Keys.ITEM_ID, aGenericRev.getItemId()); + theMap.put(R15R16R17R24R25Keys.PART_NUMBER, aGenericRev.getItemId()); + theMap.put(R15R16R17R24R25Keys.MANUFACTURER_CODE, aGenericRev.getResponsableConception()); + theMap.put(R15R16R17R24R25Keys.FRENCH_DESIGNATION, aGenericRev.getName()); + theMap.put(R15R16R17R24R25Keys.ENGLISH_DESIGNATION, aGenericRev.getDesignationEN()); + theMap.put(R15R16R17R24R25Keys.OBTURATION, isFrench ? SANS_OBJET : NOT_APPLICABLE); + theMap.put(R15R16R17R24R25Keys.CLASSIFICATION, DASH_STR); + theMap.put(R15R16R17R24R25Keys.FIELD_OPN_SERIALISATION, isFrench ? OUI : YES); + theMap.put(R15R16R17R24R25Keys.LOG_DOCUMENT, isFrench ? SANS_OBJET : NOT_APPLICABLE); + theMap.put(R15R16R17R24R25Keys.PART_VERSION, StringHelper.EMPTY); + return theMap; + } + + @Override + public Map visitComponent(final AlternateRevision aAlternateRev) { + Map theMap = giveNotPartMatProperties(aAlternateRev); + String obturation = aAlternateRev.getObturation(); + theMap.put(R15R16R17R24R25Keys.OBTURATION, isFrench ? french(obturation) : english(obturation)); + return theMap; + } + + @Override + public Map visitComponent(final DETRevision aDetRev) { + Map theMap = giveNotPartMatProperties(aDetRev); + String obturation = aDetRev.getObturation(); + theMap.put(R15R16R17R24R25Keys.OBTURATION, isFrench ? french(obturation) : english(obturation)); + return theMap; + } + + @Override + public Map visitComponent(final PartAeroRevision aPartAeroRev) { + Map theMap = giveNotPartMatProperties(aPartAeroRev); + String obturation = aPartAeroRev.getObturation(); + theMap.put(R15R16R17R24R25Keys.OBTURATION, isFrench ? french(obturation) : english(obturation)); + return theMap; + } + + @Override + public Map visitComponent(final PartNoAeroRevision aPartNoAeroRev) { + Map theMap = giveNotPartMatProperties(aPartNoAeroRev); + theMap.put(R15R16R17R24R25Keys.OBTURATION, isFrench ? SANS_OBJET : NOT_APPLICABLE); + return theMap; + } + + @Override + public Map visitComponent(final PartAssembRevision aPartAssembRev) { + Map theMap = giveNotPartMatProperties(aPartAssembRev); + theMap.put(R15R16R17R24R25Keys.OBTURATION, isFrench ? SANS_OBJET : NOT_APPLICABLE); + return theMap; + } + + @Override + public Map visitComponent(final PartMatRevision aPartMatRev) { + Map theMap = givePartProperties(aPartMatRev); // This one does NOT use giveNotPartMatProperties (obviously) + theMap.put(R15R16R17R24R25Keys.OBTURATION, isFrench ? SANS_OBJET : NOT_APPLICABLE); + String classementMat = aPartMatRev.getClassementMat(); + theMap.put(R15R16R17R24R25Keys.CLASSIFICATION, (classementMat == null || classementMat.isEmpty()) ? DASH_STR : classementMat); + theMap.put(R15R16R17R24R25Keys.FIELD_OPN_SERIALISATION, isFrench ? SANS_OBJET : NOT_APPLICABLE); + theMap.put(R15R16R17R24R25Keys.LOG_DOCUMENT, isFrench ? SANS_OBJET : NOT_APPLICABLE); + return theMap; + } + + @Override + public Map visitComponent(final StandardRevision aStandardRev) { + Map theMap = giveNotPartMatProperties(aStandardRev); + theMap.put(R15R16R17R24R25Keys.OBTURATION, isFrench ? SANS_OBJET : NOT_APPLICABLE); + return theMap; + } + + private Map givePartProperties(final AbstractPart aPart) { + Map theMap = new EnumMap<>(R15R16R17R24R25Keys.class); + theMap.put(R15R16R17R24R25Keys.ITEM_ID, aPart.getItemId()); + theMap.put(R15R16R17R24R25Keys.PART_NUMBER, aPart.getItemId()); + theMap.put(R15R16R17R24R25Keys.MANUFACTURER_CODE, aPart.getResponsableConception()); + theMap.put(R15R16R17R24R25Keys.PART_VERSION, aPart.getRevisionId()); + theMap.put(R15R16R17R24R25Keys.FRENCH_DESIGNATION, aPart.getName()); + theMap.put(R15R16R17R24R25Keys.ENGLISH_DESIGNATION, aPart.getDesignationEN()); + return theMap; + } + + private Map giveNotPartMatProperties(final AbstractPart aPart) { + Map theMap = givePartProperties(aPart); + String classement = aPart.getClassement(); + theMap.put(R15R16R17R24R25Keys.CLASSIFICATION, (classement == null || classement.isEmpty()) ? DASH_STR : classement); + String suiviUtilisation = aPart.getSuiviUtilisation(); + theMap.put(R15R16R17R24R25Keys.FIELD_OPN_SERIALISATION, isFrench ? french(suiviUtilisation) : english(suiviUtilisation)); + String documentControle = aPart.getDocumentControle(); + theMap.put(R15R16R17R24R25Keys.LOG_DOCUMENT, isFrench ? french(documentControle) : english(documentControle)); + return theMap; + } + + @Override + public Map visitComponent(final RFGenericRevision aRfGenericRev) { + // No use + return null; + } + + @Override + public Map visitComponent(final RFPartAssembRevision aRfPartAssembRev) { + // No use + return null; + } + + @Override + public Map visitComponent(final RFPartRevision aRfPartRev) { + // No use + return null; + } + + @Override + public Map visitComponent(final RFAdminRevision aRfAdminRev) { + // No use + return null; + } + + @Override + public Map visitComponent(final RFAdminARevision aRfAdminARev) { + // No use + return null; + } + + @Override + public Map visitComponent(final RFAdminAPRevision aRfAdminAPRev) { + // No use + return null; + } + + @Override + public Map visitComponent(final RFAdminAGRevision aRfAdminAGRev) { + // No use + return null; + } + + @Override + public Map visitComponent(final MockupRevision aMockupRev) { + // This object is not use in this report + return null; + } + + @Override + public Map visitComponent(final DescriptifRevision aDescriptifRev) { + // This object is not use in this report + return null; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/R15R16R17R24R25Keys.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/R15R16R17R24R25Keys.java new file mode 100644 index 0000000..340e1ab --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/R15R16R17R24R25Keys.java @@ -0,0 +1,52 @@ +package com.capgemini.reports.definition.r15r16r17reports; + +/** + * Main Parameter keys for R17 report. + */ +public enum R15R16R17R24R25Keys { + REPORT_TITLE, + ITEM_ID, + ITEM_REVISION_ID, + RELEASE_DATE, + CLAUSE_PROPRIETE, + EMPTY_TABLE, + SNECMA_LOGO, + WATERMARK, + PRODUCT_TYPE, + PART_NUMBER, + MANUFACTURER_CODE, + PART_VERSION, + FRENCH_DESIGNATION, + ENGLISH_DESIGNATION, + CLASSIFICATION, + FIELD_OPN_SERIALISATION, + LOG_DOCUMENT, + OBTURATION, + MT_NUMBER, + PREVIOUS_RELEASE_DATE; + + /** + * Report Data. Specific for R15 and R16. + */ + public enum SpecificR15R16 { + PRODUCT_UNIT, + INSTALLATION_INTERFACE, + PARTNER_INTERFACE, + SUB_TITLE, + IS_PREVIOUS_DEF + } + + /** + * Report Data. + */ + public enum Page2 { + REF_DESCRIPTIF, + REV_DESCRIPTIF, + STATUS, + MATURITY_STATUS, + DOC_NUMBER, + ISSUE, + DOC_TYPE, + DOC_TITLE + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/AbstractDataReportPreparatorR15R17.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/AbstractDataReportPreparatorR15R17.java new file mode 100644 index 0000000..1161b5a --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/AbstractDataReportPreparatorR15R17.java @@ -0,0 +1,357 @@ +package com.capgemini.reports.definition.r15r16r17reports.r15r17reports; + +import com.capgemini.framework.common.LanguageHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum.AbstractStatusFilter; +import com.capgemini.framework.teamcenter.object.pom.status.TcReleaseStatus; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.definition.r15r16r17reports.AbstractDataReportPreparatorR15R16R17; +import com.capgemini.reports.documentationobjects.DocDrawing; +import com.capgemini.reports.documentationobjects.DocGeometry; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NotSupportedException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.snecmaobjects.SnecmaObjectFactory; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import com.capgemini.reports.teamcenter.ObjectInfoHelper; +import com.capgemini.reports.teamcenter.ObjectInfoLoader; +import com.capgemini.reports.teamcenter.queries.saved.ChangeFromPartQuery; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.ReleaseStatus; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV4_TYPE_MODIFICATION; + +/** + * Abstract Class whose goal is to prepare common data to R15 R17 reports. + * + * @param the report {@link AbstractExecutionR15R17} + */ +@Slf4j +@EqualsAndHashCode(callSuper = true) +public abstract class AbstractDataReportPreparatorR15R17> extends AbstractDataReportPreparatorR15R16R17 { + private static final long serialVersionUID = -7130318844369564083L; + + private static final AbstractStatusFilter APPROVED_STATUS = StatusEnum.allow(StatusEnum.DEF_APPROVED, StatusEnum.PRELIM_DEF_APPROVED); + private static final AbstractStatusFilter CANCELLED_STATUS = StatusEnum.allow(StatusEnum.CANCELLED); + private static final String REVISION_ENG_CHANGE = SnecmaObjectTypes.REVISION_ENG_CHANGE; + private static final String DEFINITION_EN_COURS = "définition en cours"; + private static final String DEFINITION_ANNULEE = "définition annulée"; + private static final String WHITESPACE = " "; + + /** + * Find the top ItemRevision in the list of all the revisions. + * + * @param wantedRevision {@link String} - the wanted revision + * @param revisionsSnecmaObject List<{@link ItemRevision}> - the list of all the revisions of the top object + * @return the selected ItemRevision + */ + protected ItemRevision retrieveTopItemRevision(final String wantedRevision, final List revisionsSnecmaObject) { + ItemRevision topItemRevision = null; + for (ItemRevision itemRev : revisionsSnecmaObject) { + if (itemRev == null || !SnecmaObjectTypes.isPartRevision(itemRev.getTypeObject().getName())) { + continue; + } + String revision = itemRev.get_item_revision_id(); + if (revision != null && revision.equals(wantedRevision)) { + topItemRevision = itemRev; + break; + } + } + return topItemRevision; + } + + /** + * Prepare all common data between report 15 , report 16 and report 17. + * + * @param session {@link TcSession} - the tc session + * @param topItemRevision {@link ItemRevision} - the top object + * @param revisionsSnecmaObject List<{@link ItemRevision}> - the list of all the revisions of the top object + * @param report - the execution report which provide all informations for the report + * @throws KurtException if anything else goes wrong + * @throws InvalidUserInputException the user-provided top item doesn't seem to exist + */ + protected void doPrepareCommonDataForAllReports(final TcSession session, final ItemRevision topItemRevision, + final List revisionsSnecmaObject, final T report) + throws KurtException { + // Verify the object type: any Part but not an Alternate + checkAndBuildSnecmaObject(session, topItemRevision, report); + + report.setTypeProduit(ObjectInfoLoader.getProductType(session, topItemRevision)); + report.setClausePropriete(ObjectInfoLoader.getClausePropriete(report.getTypeProduit(), session)); + retrieveDateReleased(session, topItemRevision, report); + + retrieveDateLancementAndMT(revisionsSnecmaObject, report.itemRevision, session, report); + retrieveRevisionArticle(session, report); + + retrieveDocGeometryAndDocDrawingLists(session, topItemRevision, report); + retrieveDocNormAndDocNormStandardLists(session, topItemRevision, report); + retrieveDocTechnicList(session, topItemRevision, report); + } + + /** + * Check and build the SnecmaObject. + */ + protected void checkAndBuildSnecmaObject(final TcSession session, final ItemRevision topItemRevision, final T report) + throws InvalidUserInputException, NotSupportedException { + String itemType = topItemRevision.getTypeObject().getName(); + if (!SnecmaObjectTypes.isA(itemType, SnecmaObjectTypes.PART_AERO_REVISION, SnecmaObjectTypes.PART_NO_AERO_REVISION, + SnecmaObjectTypes.PART_ASSEMB_REVISION, SnecmaObjectTypes.PART_MAT_REVISION, SnecmaObjectTypes.DET_REVISION, + SnecmaObjectTypes.STANDARD_REVISION)) { + throw new InvalidUserInputException(UserInputErrorEnum.THE_SELECTED_OBJECT_IS_NOT_PERMITTED_ON_THIS_REPORT); + } + report.snecmaObject = SnecmaObjectFactory.build(session, topItemRevision); + } + + /** + * Retrieve the parameter RevisionArticle. + */ + protected void retrieveRevisionArticle(final TcSession session, final T report) { + // Find an associate Change with the Part + // Maybe the change is a ChangeRequest Revision or a ChangeNotice Revision + List selectedChanges = new ArrayList<>(); + if (report.mostRecentDateReleased != null) { + selectedChanges = returnChangeItemWithSameDateReleased(report.mostRecentDateReleased, report.getItemId(), report.itemRevision, session, + report.statusName); + } + + // Put revision article's parameter for the report + if (selectedChanges.isEmpty() || selectedChanges.size() > 1) { + report.setRevisionArticle(report.snecmaObject.getRevisionId()); + } else { + ItemRevision selectedChange = selectedChanges.get(0); + String typeModif = selectedChange.getPropertyObject(PV4_TYPE_MODIFICATION).getStringValue(); + report.setRevisionArticle(selectedChange.get_item_id() + WHITESPACE + (report.isFrench() ? LanguageHelper.french(typeModif) : LanguageHelper.english(typeModif))); + } + } + + /** + * Return the ChangeItem (ChangeRequest or TcChangeNoticeRevision) with the same date released as the provided Calendar. + * + * @param referenceDate {@link Calendar} - the reference date of the reference object + * @param itemId {@link String} - the id of the reference object + * @param itemRevisionId {@link String} - the revision id of the reference object + * @param session {@link TcSession} - the TC session for query + * @param statusName {@link String} - the reference name of TcReleaseStatus of the reference object + * @return the selected ChangeItem Revision + */ + protected List returnChangeItemWithSameDateReleased(final Calendar referenceDate, final String itemId, final String itemRevisionId, + final TcSession session, final String statusName) { + // Query of all associated Change with the Part + List listChangeRev = new ChangeFromPartQuery(session).searchIDAndRevision(itemId, itemRevisionId).findAll(); + + // Select ONE change associated to the precedent selected ReleaseStatus of the date released of the Part + List selectedChanges = new ArrayList<>(); + for (ItemRevision changeRev : listChangeRev) { + if (changeRev == null) { + continue; + } + + // Filter the Revision EngChange + String typeChange = changeRev.getTypeObject().getName(); + if (REVISION_ENG_CHANGE.equals(typeChange)) { + continue; + } + + // Compare the status name and the date released to the references + boolean isValidated = validChange(session, changeRev, referenceDate, statusName); + if (isValidated) { + selectedChanges.add(changeRev); + } + } + return selectedChanges; + } + + private boolean validChange(final TcSession session, final ItemRevision changeRev, final Calendar referenceDate, final String statusName) { + boolean isValidated = false; + ReleaseStatus[] releaseStatusList = getReleaseStatusList(session, changeRev); + for (ReleaseStatus status : releaseStatusList) { + if (status == null) { + continue; + } + + Calendar changeCalendar = status.get_date_released(); + if (changeCalendar == null) { + continue; + } + + // Filter with the name of the reference ReleaseStatus + if (!statusName.equals(status.get_name())) { + break; + } + + // Only ONE change can have the same ReleaseStatus with the same date released + // Warning : Calendar.MONTH return 0 for January and 11 for December + if (changeCalendar.get(Calendar.DAY_OF_MONTH) == referenceDate.get(Calendar.DAY_OF_MONTH) + && changeCalendar.get(Calendar.MONTH) == referenceDate.get(Calendar.MONTH) + && changeCalendar.get(Calendar.YEAR) == referenceDate.get(Calendar.YEAR)) { + isValidated = true; + } + } + return isValidated; + } + + private void retrieveDocGeometryAndDocDrawingLists(final TcSession session, final ItemRevision partItemRevision, final T report) { + List representedDocObjects = AbstractPart.returnRepresentedDocuments(session, partItemRevision); + for (ItemRevision representedDoc : representedDocObjects) { + if (representedDoc == null) { + continue; + } + String type = representedDoc.getTypeObject().getName(); + if (SnecmaObjectTypes.DOC_GEOMETRY_REVISION.equals(type)) { + DocGeometry docGeo = new DocGeometry(session, representedDoc); + report.docGeometryList.add(docGeo); + } else if (SnecmaObjectTypes.DOC_DRAWING_REVISION.equals(type)) { + DocDrawing docDrawing = new DocDrawing(session, representedDoc); + report.docDrawingList.add(docDrawing); + } + } + } + + /** + * Retrieve the date released of the report through the main itemRevision's properties. + * + * @param partItemRevision {@link ItemRevision} - the part object + * @param report - the execution report which provide all informations for the report + */ + public void retrieveDateReleased(final TcSession session, final ItemRevision partItemRevision, final T report) { + // Find the selected ReleaseStatus + ReleaseStatus selectStatus = selectStatus(session, partItemRevision); + if (selectStatus == null) { + report.setDateReleased(DEFINITION_EN_COURS); + log.warn("No ReleaseStatus were found on the {} {}.", partItemRevision.getTypeObject().getName(), partItemRevision.getUid()); + return; + } + + // Retrieve the date released + Calendar selectedDate = selectStatus.get_date_released(); + if (selectedDate == null) { + report.setDateReleased(DEFINITION_EN_COURS); + log.warn("Unable to retrieve the date released of the selected ReleaseStatus {} {}.", selectStatus.getTypeObject().getName(), + selectStatus.getUid()); + return; + } + + // Retrieve informations about TcReleaseStatus in order to compare with revision article + report.mostRecentDateReleased = selectedDate; + report.statusName = selectStatus.get_name(); + + // Put date released's appropriate value for report + if (APPROVED_STATUS.isIncluded(report.statusName)) { + report.setDateReleased(getDateFormatDayMonthYear(selectedDate)); + } else { + if (CANCELLED_STATUS.isIncluded(report.statusName)) { + report.setDateReleased(DEFINITION_ANNULEE); + } else { + report.setDateReleased(DEFINITION_EN_COURS); + } + } + } + + private ReleaseStatus selectStatus(final TcSession session, final ItemRevision partItemRevision) { + return ObjectInfoHelper.getStatusWithMostRecentReleaseDate(session, partItemRevision, StatusEnum.J3A, StatusEnum.J3B, StatusEnum.EFFECTIVITY); + } + + /** + * Retrieve the Date Lancement and the MT property. + * + * @param revisionsSnecmaObject List<{@link ItemRevision}> - the list of revisions of the top Part + * @param revisionTopPart {@link String} - the revision of the top Part + * @param session {@link TcSession} - the tc session + * @param report - the execution report which provide all informations for the report + */ + public void retrieveDateLancementAndMT(final List revisionsSnecmaObject, + final String revisionTopPart, final TcSession session, final T report) { + // Date released of the part (may be the date system) + Calendar dateRefFormatcalendar = selectCalendar(report); + + // Find the previous ItemRevision (may not be the direct predecessor) and the previous Date + ItemRevision previousRev = null; + Calendar selectedDate = null; + for (ItemRevision itemRev : revisionsSnecmaObject) { + if (itemRev == null) { + continue; + } + String revision = itemRev.get_item_revision_id(); + if (revision == null) { + continue; + } + if (revision.compareTo(revisionTopPart) < 0) { + List listRsPrecedentRev = TcReleaseStatus.getChosenStatus(session, itemRev, StatusEnum.J3B); + if (listRsPrecedentRev.isEmpty()) { + continue; + } + for (ReleaseStatus status : listRsPrecedentRev) { + if (status == null) { + continue; + } + Calendar date = status.get_date_released(); + if (date != null && date.compareTo(dateRefFormatcalendar) < 0) { + if (selectedDate == null) { + previousRev = itemRev; + selectedDate = date; + } else if (selectedDate.compareTo(date) < 0) { + previousRev = itemRev; + selectedDate = date; + } + } + } + } + } + + // Put MT and previousDateReleased data + putPrecedentRevisionParameters(session, previousRev, selectedDate, report); + } + + private void putPrecedentRevisionParameters(final TcSession session, final ItemRevision previousRev, final Calendar selectedDate, + final T report) { + if (previousRev == null) { + report.varMt = ""; + report.previousReleaseDate = ""; + } else { + // Previous date released parameter for report + report.previousReleaseDate = getDateFormatDayMonthYear(selectedDate); + + // MT parameter for report + String previousId = previousRev.get_item_id(); + String previousRevisionId = previousRev.get_item_revision_id(); + List selectedPrecedentChange = + returnChangeItemWithSameDateReleased(selectedDate, previousId, previousRevisionId, session, StatusEnum.J3B.getIdentifier()); + if (selectedPrecedentChange.isEmpty() || selectedPrecedentChange.size() > 1) { + report.varMt = ""; + } else { + report.varMt = selectedPrecedentChange.get(0).get_item_id(); + } + } + } + + private Calendar selectCalendar(final T report) { + Calendar refCalendarForPrecedentRev; + if (DEFINITION_EN_COURS.equals(report.getDateReleased()) || DEFINITION_ANNULEE.equals(report.getDateReleased()) + || (report.mostRecentDateReleased == null)) { + refCalendarForPrecedentRev = Calendar.getInstance(); + } else { + refCalendarForPrecedentRev = report.mostRecentDateReleased; + } + return refCalendarForPrecedentRev; + } + + private ReleaseStatus[] getReleaseStatusList(final TcSession session, final ItemRevision itemRev) { + session.loadProperties(itemRev, "release_status_list"); + ReleaseStatus[] releaseStatuses = itemRev.get_release_status_list(); + session.loadProperties(releaseStatuses); + return releaseStatuses; + } + + @Override + public boolean isEmptyTable(final T report) { + return super.isEmptyTable(report) && report.getDocDrawingList().isEmpty() && report.getDocGeometryList().isEmpty(); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/AbstractExecutionR15R17.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/AbstractExecutionR15R17.java new file mode 100644 index 0000000..fb04a29 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/AbstractExecutionR15R17.java @@ -0,0 +1,76 @@ +package com.capgemini.reports.definition.r15r16r17reports.r15r17reports; + +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.definition.r15r16r17reports.AbstractExecutionR15R16R17; +import com.capgemini.reports.documentationobjects.DocDrawing; +import com.capgemini.reports.documentationobjects.DocGeometry; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.reports.parameters.checker.ObjectTypeChecker; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +/** + * Prepare the common data for report 15 and 17. + * + * @param Generic object for a report + */ +@Getter +@EqualsAndHashCode(callSuper = true) +public abstract class AbstractExecutionR15R17> extends AbstractExecutionR15R16R17 { + private static final long serialVersionUID = 1041606367467834895L; + + // Documents gathered + protected final List docGeometryList = new ArrayList<>(); + protected final List docDrawingList = new ArrayList<>(); + + // Data gathered + protected final String itemRevision; + protected ISnecmaObject snecmaObject; + protected String varMt = ""; + protected String previousReleaseDate = ""; + + // Configuration data + protected Calendar mostRecentDateReleased; + protected String statusName; + + /** + * Constructs some parameters requested for R15 and R17 reports execution. + * + * @param partId the ID of the part + * @param partRevision the revision f the Part + * @param language the selected language (French or English) + * @param priorityCode int - the priority code found in the reporting.properties file associated to a report + * @param revisionRule {@link String} - the revision rule for resolution structure + * @param launchType {@link ReportLaunchTypeEnum} - the launch type of the report + */ + public AbstractExecutionR15R17(final String partId, final String partRevision, final String language, final int priorityCode, + final String revisionRule, final ReportLaunchTypeEnum launchType) { + super(partId, language, priorityCode, revisionRule, launchType); + this.itemRevision = partRevision; + } + + @Override + public List getLaunchData() { + List theCriteria = new ArrayList<>(); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PART_ID, super.itemId)); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PART_REVISION, itemRevision)); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.LANGUAGE, super.frenchInput)); + return theCriteria; + } + + @Override + public List getQuickChecks() { + ArrayList quickChecks = new ArrayList<>(); + quickChecks.add(new ObjectTypeChecker(itemId, SnecmaObjectTypes.DET, SnecmaObjectTypes.PART_AERO, SnecmaObjectTypes.PART_ASSEMB, + SnecmaObjectTypes.PART_MAT, SnecmaObjectTypes.PART_NO_AERO, SnecmaObjectTypes.STANDARD)); + return quickChecks; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/AbstractR15R17Printer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/AbstractR15R17Printer.java new file mode 100644 index 0000000..576673f --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/AbstractR15R17Printer.java @@ -0,0 +1,94 @@ +package com.capgemini.reports.definition.r15r16r17reports.r15r17reports; + +import com.capgemini.reports.definition.r15r16r17reports.AbstractR15R16R17Printer; +import com.capgemini.reports.definition.r15r16r17reports.CommunR15R16R17ComponentVisitor; +import com.capgemini.reports.definition.r15r16r17reports.R15R16R17R24R25Keys; +import com.capgemini.reports.definition.r15r16r17reports.R15R16R17R24R25Keys.Page2; +import com.capgemini.reports.definition.r15r16r17reports.r15r17reports.r17report.ExecutionR17; +import com.capgemini.reports.documentationobjects.DocDrawing; +import com.capgemini.reports.documentationobjects.DocGeometry; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import lombok.EqualsAndHashCode; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +/** + * This class allows printing of several elements that are found in both the R17 and R15 reports. + * + * @param describes which report's {@link AbstractExecutionReport} this printer will print. Must be a subclass of {@link AbstractExecutionR15R17}. + */ +@EqualsAndHashCode(callSuper = true) +public abstract class AbstractR15R17Printer> extends AbstractR15R16R17Printer { + + private static final long serialVersionUID = 6353372020574746542L; + + @Override + protected List> addExtraDocLines(final T execution) { + List> dataTable = new ArrayList<>(); + boolean isFrench = execution.isFrench(); + for (DocGeometry geometry : execution.getDocGeometryList()) { + dataTable.add(getDocGeometryLine(geometry, isFrench)); + } + String itemId = execution.getItemId(); + for (DocDrawing drawing : execution.getDocDrawingList()) { + dataTable.add(getDocDrawingLine(drawing, isFrench, execution.getTypeProduit(), itemId)); + } + return dataTable; + } + + private Map getDocDrawingLine(final DocDrawing drawing, final boolean isFrench, final String typeProduit, final String itemID) { + String identifier; + if (isNotAuthorized(typeProduit)) { + identifier = itemID; + } else { + identifier = drawing.getDocId(); + } + Map line = new EnumMap<>(Page2.class); + line.put(Page2.DOC_NUMBER, identifier); + line.put(Page2.ISSUE, drawing.getIndicePlan()); + line.put(Page2.DOC_TYPE, isFrench ? "Représentation 2D" : "Drawing"); + line.put(Page2.DOC_TITLE, isFrench ? drawing.getName() : drawing.getDesignationEn()); + return line; + } + + private Map getDocGeometryLine(final DocGeometry geometry, final boolean isFrench) { + Map line = new EnumMap<>(Page2.class); + line.put(Page2.DOC_NUMBER, geometry.getDocId()); + line.put(Page2.ISSUE, geometry.getIndiceCartouche()); + line.put(Page2.DOC_TYPE, isFrench ? "Modèle 3D" : "3D Model"); + line.put(Page2.DOC_TITLE, geometry.getDesignationEN()); + return line; + } + + @Override + protected void addOptionalParameters(final T execution, final PrintParameters mainReport) { + // Add common parameters between R15 and R17 + Map params = new EnumMap<>(R15R16R17R24R25Keys.class); + params.put(R15R16R17R24R25Keys.MT_NUMBER, execution.getVarMt()); + params.put(R15R16R17R24R25Keys.PREVIOUS_RELEASE_DATE, execution.getPreviousReleaseDate()); + params.putAll(execution.getSnecmaObject().accept(getVisitor(execution.isFrench()))); + mainReport.addReportParameters(params); + + // Add specific parameters to each sub-report + addSpecificParameters(execution, mainReport); + } + + /** + * Adds parameters that are specific to each subclass and not common to R15-R17. In particular, R15Printer will want to add a few values. + * + * @param execution the data-bearing {@link ExecutionR17} + * @param mainReport the {@link PrintParameters} + */ + protected abstract void addSpecificParameters(final T execution, final PrintParameters mainReport); + + @Override + protected IComponentVisitor> getVisitor(final boolean isFrench) { + return new CommunR15R16R17ComponentVisitor(isFrench); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r15report/AttachDatasetR15Action.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r15report/AttachDatasetR15Action.java new file mode 100644 index 0000000..a343f09 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r15report/AttachDatasetR15Action.java @@ -0,0 +1,109 @@ +package com.capgemini.reports.definition.r15r16r17reports.r15r17reports.r15report; + +import com.capgemini.framework.common.FileHelper; +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemQuery; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.execution.actions.AbstractPostExecutionStep; +import com.capgemini.reports.execution.actions.ondataset.CreateDatasetAction; +import com.capgemini.reports.execution.actions.ondataset.DestroyRelationshipsAction; +import com.capgemini.reports.execution.actions.ondataset.LinkFicheArticleAction; +import com.capgemini.reports.execution.actions.ondataset.SetStatusAction; +import com.teamcenter.services.loose.core._2006_03.FileManagement.GetDatasetWriteTicketsInputData; +import com.teamcenter.soa.client.model.strong.Item; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.File; +import java.util.List; + +/** + * This action can be triggered upon report completion. Once triggered, it will: + *
    + *
  1. Rename the document
  2. + *
  3. Upload the created report to a dataset
  4. + *
  5. Attach the dataset to the Part
  6. + *
  7. Set a Frozen status on the dataset
  8. + *
+ */ +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class AttachDatasetR15Action extends AbstractPostExecutionStep { + private static final long serialVersionUID = 5891187265385234600L; + + private static final String OUTPUT_FOLDER = SettingsHelper.getReportLocation(); + private static final PolicyLocation POLICY_XML_DATASET = PolicyLocation.make("R15_policy_wkf", "/xml/policies/r15report/R15_policy_wkf.xml"); + + /** + * Creates an instance. + */ + public AttachDatasetR15Action() { + super(ExecutionR15.class); + } + + private static Item getItem(final TcSession session, String targetID) throws NotFoundException { + List results = new ItemQuery(session).searchID(targetID).findAll(); + + for(Item currentResult : results){ + if(SnecmaObjectTypes.isPart(currentResult.getTypeObject().getName())){ + return currentResult; + } + } + + if (results.isEmpty()) { + throw new NotFoundException("Could not find the original part " + targetID); + } else { + throw new NotFoundException(targetID + " part not found other type found instead"); + } + + } + + @Override + public Void performPostActionOnReport(final TcSession session, final ExecutionR15 report, final DbReport theExecutingReport, + final String fileNameWithExtension) throws KurtException { + session.setObjectPropPolicy(POLICY_XML_DATASET); + + // Prepare naming & Make a copy with the correct name + log.debug("Workflow launch: Beginning file copy"); + File fileCopy = copyFile(report.getDatasetFileNameWithExtension(), report.getOriginalDatasetFileNameWithExtension()); + + // Obtain the Part + String targetID = report.getItemId(); + Item target = getItem(session, targetID); + + // Detect & destroy conflicting datasets on the part, if any + String datasetName = report.getDatasetName(); + log.debug("Workflow launch: Destroying previous datasets..."); + DestroyRelationshipsAction.destroyConflictingDatasets(session, datasetName, targetID); + + // Create a new dataset + log.debug("Workflow launch: Creating dataset {}", datasetName); + GetDatasetWriteTicketsInputData dataset = CreateDatasetAction.createDataset(session, datasetName, fileCopy, report); + + // Link the part to the dataset (if it fails, it will cleanup the dataset as well) + log.debug("Workflow launch: Linking Part {} to newly created dataset {}", target.getUid(), dataset.dataset.getUid()); + LinkFicheArticleAction.linkDatasetToPart(session, target, dataset.dataset); + + // Set status on the dataset + log.debug("Workflow launch: Adding 'Frozen' status to the dataset {}", dataset.dataset.getUid()); + SetStatusAction.setStatus(session, dataset.dataset, StatusEnum.FROZEN.getIdentifier()); + + log.debug("Workflow launch has completed successfully for R15 on ", targetID); + + return null; + } + + private File copyFile(final String datasetFileNameWithExtension, String originalFileName) throws NotFoundException { + File copy = new File(OUTPUT_FOLDER + datasetFileNameWithExtension); + File original = new File(OUTPUT_FOLDER + originalFileName); + FileHelper.copy(original, copy); + return copy; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r15report/DataReportPreparatorR15.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r15report/DataReportPreparatorR15.java new file mode 100644 index 0000000..56b3894 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r15report/DataReportPreparatorR15.java @@ -0,0 +1,178 @@ +package com.capgemini.reports.definition.r15r16r17reports.r15r17reports.r15report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.SnecmaObjectProperties; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.definition.r15r16r17reports.r15r17reports.AbstractDataReportPreparatorR15R17; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.releasestatus.RevisionStatusAndDate; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.teamcenter.ObjectInfoHelper; +import com.google.common.base.Optional; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Form; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import org.slf4j.Logger; + +import java.util.*; + +import static com.capgemini.framework.teamcenter.TeamcenterObjectProperties.ASSEMBLY_BOM; +import static com.capgemini.framework.teamcenter.TeamcenterObjectProperties.RF_PART_BOM; +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.*; + + +/** + * This class will allow to prepare data and findAll back data for making report R15. + */ +public class DataReportPreparatorR15 extends AbstractDataReportPreparatorR15R17 { + private static final long serialVersionUID = -1615860676063048572L; + + private static final String NON_NO = "Non / No"; + private static final String OUI_YES = "Oui / Yes"; + private static final String DASH_STRING = "-"; + private static final Logger log = org.slf4j.LoggerFactory.getLogger(DataReportPreparatorR15.class); + + @Override + public String print(TcSession session, ExecutionR15 execution, IExecutionStrategy executionStrategy) throws KurtException { + PrintParameters printParameters = prepareData(session, execution); + executionStrategy.print(printParameters, execution); + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + } + + private PrintParameters prepareData(final TcSession session, final ExecutionR15 report) throws KurtException { + log.trace("PrepareData started on: " + report.getReportIdentifier().getReportTitle()); + long start = System.currentTimeMillis(); + + // Setup the policy + session.setObjectPropPolicy(report.getFullPolicy()); + + List revisionsSnecmaObject = new ItemRevisionQuery(session).searchID(report.getItemId()).findAll(); + if (revisionsSnecmaObject.isEmpty()) { + throw new InvalidUserInputException("Unabled to retrieve the list of revisons of the Part " + report.getItemId()); + } + + // Retrieve topItemRev + ItemRevision topItemRevision = retrieveTopItemRevision(report.getItemRevision(), revisionsSnecmaObject); + + // Retrieve all common data + doPrepareCommonDataForAllReports(session, topItemRevision, revisionsSnecmaObject, report); + + // Specificities of the report + filterDocTechnic(report); + if (PART_ASSEMB_REVISION.equals(report.getSnecmaObject().getType())) { + retrieveFrontiereAvionAndFrontiereCooperant(topItemRevision, RF_PART_ASSEMB_REVISION, ASSEMBLY_BOM, + session, report); + } else { + retrieveFrontiereAvionAndFrontiereCooperant(topItemRevision, RF_PART_REVISION, RF_PART_BOM, + session, report); + } + report.setProduitUnit(""); + + R15Printer printer = new R15Printer(); + PrintParameters printParameters = printer.makeMasterTemplate(report, report); + printer.constructDataMaps(session, printParameters, report); + + log.debug(EXECUTION_TIME_XXX_MS_FOR_YYY, System.currentTimeMillis() - start, "data gathering"); + return printParameters; + } + + private void retrieveFrontiereAvionAndFrontiereCooperant(final ItemRevision topItemRevision, final String typeTopItemRev, + final String propertyPseudoFolder, final TcSession session, final ExecutionR15 report) + throws KurtException { + List repereResults = session.whereUsed(topItemRevision, typeTopItemRev); + if (repereResults.isEmpty()) { + + report.setFrontiereAvion(DASH_STRING); + report.setFrontiereCooperant(DASH_STRING); + return; + } + Set selectedRfAdminList = new HashSet<>(); + for (ItemRevision rfPartAssemb : repereResults) { + List resultsPseudoFolder = + ObjectInfoHelper.getModelObjectsInPseudoFolderUnderItemRevision(session, rfPartAssemb, propertyPseudoFolder); + if (resultsPseudoFolder.isEmpty()) { + continue; + } + treatRfAdminInPseudofolder(session, selectedRfAdminList, resultsPseudoFolder); + } + putvaluesFrontiereCooperantAndAvion(session, selectedRfAdminList, report); + } + + private void treatRfAdminInPseudofolder(final TcSession session, final Set selectedRfAdminList, final List resultsPseudoFolder) { + for (ModelObject objectItem : resultsPseudoFolder) { + Item item = (Item) objectItem; + if (!RF_ADMIN.equals(item.getTypeObject().getName())) { + continue; + } + + session.loadProperties(item, "revision_list"); + ModelObject[] listRevision = item.get_revision_list(); + session.loadProperties(listRevision); + + // Convert List to List + List interList = new ArrayList<>(); + for (ModelObject object : listRevision) { + interList.add((ItemRevision) object); + } + + // Find the appropriate Admin for the current RF Part or RF Part Assemb + Optional selectedRfAdmin = retrieveAdminWithMostRecentDateRelease(session, interList); + + if (selectedRfAdmin.isPresent()) { + selectedRfAdminList.add(selectedRfAdmin.get()); + } + } + } + + private Optional retrieveAdminWithMostRecentDateRelease(final TcSession session, final List interList) { + return ObjectInfoHelper.getRevisionFromStatusWithMostRecentReleaseDateNotCancelled(session, interList, Calendar.getInstance()); + } + + private void putvaluesFrontiereCooperantAndAvion(final TcSession session, final Set selectedRfAdminList, + final ExecutionR15 report) { + if (selectedRfAdminList.isEmpty()) { + report.setFrontiereAvion(DASH_STRING); + report.setFrontiereCooperant(DASH_STRING); + + } else { + + report.setFrontiereAvion(getFrontiereAvionOrCooperantProperty(session, selectedRfAdminList, SnecmaObjectProperties.PV_FRONTIERE_AVION)); + report.setFrontiereCooperant(getFrontiereAvionOrCooperantProperty(session, selectedRfAdminList, SnecmaObjectProperties.PV_FRONTIERE_COOPERANT)); + + } + } + + private String getFrontiereAvionOrCooperantProperty(final TcSession session, final Set selectedRfAdminList, final String prop) { + boolean isYes = findValueOfPropertyInList(session, selectedRfAdminList, prop, OUI_YES); + + if (isYes) { + return OUI_YES; + } else { + boolean isNo = findValueOfPropertyInList(session, selectedRfAdminList, prop, NON_NO); + if (isNo) { + return NON_NO; + } else { + return DASH_STRING; + } + } + } + + private boolean findValueOfPropertyInList(final TcSession session, final Set selectedRfAdmins, final String property, final String wantedValue) { + for (ItemRevision rfAdmin : selectedRfAdmins) { + rfAdmin.get_item_id(); + Form form = rfAdmin.get_item_master_tag(); + if (form != null) { + session.loadProperties(form); + String valueProp = form.getPropertyObject(property).getStringValue(); + if (wantedValue.equals(valueProp)) { + return true; + } + } + } + return false; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r15report/ExecutionR15.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r15report/ExecutionR15.java new file mode 100644 index 0000000..90a42f4 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r15report/ExecutionR15.java @@ -0,0 +1,174 @@ +package com.capgemini.reports.definition.r15r16r17reports.r15r17reports.r15report; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.builder.R15Builder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.definition.r15r16r17reports.AbstractExecutionR15R16R17; +import com.capgemini.reports.definition.r15r16r17reports.r15r17reports.AbstractExecutionR15R17; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.reports.parameters.IChecker; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * This class controls the execution of a R15 report. + */ +@Getter +@Slf4j +@Setter(value = AccessLevel.PROTECTED) +public class ExecutionR15 extends AbstractExecutionR15R17 { + + private static final int TO_SECONDS = 1000; + + private static final String PDF_EXTENSION = ".pdf"; + + private static final String ENGLISH_DATASET = "_ENG"; + + private static final String FICHE_ARTICLE_REALISATION = "FA_Real"; + + private static final long serialVersionUID = -4306188095393629328L; + + private static final String FILE_SEPARATOR = "_"; + + // Policies + private static final PolicyLocation R15_POLICY_XML_FULL = PolicyLocation.make("R15_policy_full", "/xml/policies/r15report/R15_policy_full.xml"); + private static final PolicyLocation R15_POLICY_XML_LIGHT = + PolicyLocation.make("R15_policy_light", "/xml/policies/r15report/R15_policy_light.xml"); + // Priority parameter + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R15); + // Revision rule parameter + private static final String REPORT_REVISION_RULE = + SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R15", DEFAULT_REVISION_RULE); + // Launch type parameter + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R15"); + // Data gathered + private String frontiereAvion; + private String frontiereCooperant; + + /** + * Constructor. + * + * @param partId {@link String} - the ID of the Part + * @param partRevision {@link String} - the Revision of the Part + * @param language {@link String} - the language selected by the user + */ + public ExecutionR15(final String partId, final String partRevision, final String language) { + super(partId, partRevision, language, REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE); + } + + /** + * Constructor for R15 in French. + * + * @param partId {@link String} - the ID of the Part + * @param partRevision {@link String} - the Revision of the Part + */ + public ExecutionR15(final String partId, final String partRevision) { + super(partId, partRevision, AbstractExecutionR15R16R17.FRENCH_LANGUAGE, REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE); + } + + @Override + public String getTemplateLocation() { + return JasperTemplate.TEMPLATE_R15R16.getFilepath(); + } + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R15_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R15_POLICY_XML_FULL; + } + + @Override + public List getLongChecks() { + return new ArrayList<>(); + } + + @Override + public ReportEnum getReportIdentifier() { + return wkf ? ReportEnum.REPORT_W15 : ReportEnum.REPORT_R15; + } + + @Override + public String getSpecifiedFileName() { + StringBuilder filename = + new StringBuilder(itemId).append(FILE_SEPARATOR).append(itemRevision).append(FILE_SEPARATOR).append(FICHE_ARTICLE_REALISATION); + if (!isFrench()) { + filename.append(ENGLISH_DATASET); + } + return filename.toString(); + } + + @Override + public PrintFormat getPrintingFormat() { + return PrintFormat.PDF; + } + + @Override + public IDataReportPreparator getDataPreparator() { + return new DataReportPreparatorR15(); + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return new ExecutionR15(itemId, itemRevision, frenchInput); + } + + @Override + public Class getReportBuilderClass() { + return R15Builder.class; + } + + // ******************** Methods for Automatic Workflow execution ********************** + + /** + * The dataset name (if the the report is executed by a workflow). + * + * @return the dataset name + */ + String getDatasetName() { + return StringHelper.implode(FILE_SEPARATOR, getItemId(), getItemRevision(), FICHE_ARTICLE_REALISATION); + } + + /** + * The filename in the dataset (if the the report is executed by a workflow). + * + * @return the file name (with extension) + */ + String getDatasetFileNameWithExtension() { + Date startDate; + try { + startDate = new SimpleDateFormat(TeamcenterDateFormatter.DD_MM_YYYY_HH_MM_SS).parse(getStartTime()); + } catch (ParseException e) { + log.warn("Unable to parse stored start date, generating a date using NOW for W15 " + getReportTechnicalUid(), e); + startDate = new Date(); + } + String dateStr = new SimpleDateFormat(TeamcenterDateFormatter.YYYYMMDD).format(startDate); + long timestamp = startDate.getTime() / TO_SECONDS; + String timestampStr = String.valueOf(timestamp); + String bareFilename = StringHelper.implode(FILE_SEPARATOR, getItemId(), getItemRevision(), FICHE_ARTICLE_REALISATION, dateStr, timestampStr); + return bareFilename + PDF_EXTENSION; + } + + String getOriginalDatasetFileNameWithExtension() { + return getFileNameOnDisc() + PDF_EXTENSION; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r15report/R15Printer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r15report/R15Printer.java new file mode 100644 index 0000000..abd8db0 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r15report/R15Printer.java @@ -0,0 +1,48 @@ +package com.capgemini.reports.definition.r15r16r17reports.r15r17reports.r15report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.definition.r15r16r17reports.R15R16R17R24R25Keys.SpecificR15R16; +import com.capgemini.reports.definition.r15r16r17reports.r15r17reports.AbstractR15R17Printer; +import com.capgemini.reports.execution.mapconstructor.IMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import lombok.extern.slf4j.Slf4j; + +import java.util.EnumMap; +import java.util.Map; + +/** + * This class is able to put the data gathered by an {@link ExecutionR15} into some {@link PrintParameters} for printing. + */ +@Slf4j +public final class R15Printer extends AbstractR15R17Printer implements IMapConstructor { + + private static final long serialVersionUID = 4102259712529027708L; + + @Override + protected void addSpecificParameters(final ExecutionR15 execution, final PrintParameters mainReport) { + Map map = new EnumMap<>(SpecificR15R16.class); + boolean isFrench = execution.isFrench(); + String frontiereAvion = execution.getFrontiereAvion(); + map.put(SpecificR15R16.INSTALLATION_INTERFACE, isFrench ? french(frontiereAvion) : english(frontiereAvion)); + String frontiereCooperant = execution.getFrontiereCooperant(); + map.put(SpecificR15R16.PARTNER_INTERFACE, isFrench ? french(frontiereCooperant) : english(frontiereCooperant)); + map.put(SpecificR15R16.PRODUCT_UNIT, execution.getProduitUnit()); + map.put(SpecificR15R16.SUB_TITLE, + "Documents de définition et procédés et pratiques de réalisation\nDefinition and process documents and manufacturing practices"); + mainReport.addReportParameters(map); + mainReport.addReportParameter(SpecificR15R16.IS_PREVIOUS_DEF.toString(), true); + } + + @Override + protected String getTitle(final ExecutionR15 execution) { + return "Définition de réalisation de l'article\nPart Manufacturing definition"; + } + + @Override + public void constructDataMaps(TcSession session, final PrintParameters printParameters, final ExecutionR15 report) throws KurtException { + long start = System.currentTimeMillis(); + this.print(report, printParameters); + log.trace(EXECUTION_TIME_XXX_MS_FOR_YYY, System.currentTimeMillis() - start, "data filtering"); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r17report/DataReportPreparatorR17.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r17report/DataReportPreparatorR17.java new file mode 100644 index 0000000..f167d50 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r17report/DataReportPreparatorR17.java @@ -0,0 +1,53 @@ +package com.capgemini.reports.definition.r15r16r17reports.r15r17reports.r17report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.definition.r15r16r17reports.r15r17reports.AbstractDataReportPreparatorR15R17; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.printing.PrintParameters; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * Prepares the Data for the R17 report. + */ +public class DataReportPreparatorR17 extends AbstractDataReportPreparatorR15R17 { + private static final long serialVersionUID = -6169580009749438941L; + private static final Logger LOGGER = LoggerFactory.getLogger(DataReportPreparatorR17.class); + + @Override + public String print(TcSession session, ExecutionR17 execution, IExecutionStrategy executionStrategy) throws KurtException { + PrintParameters printParameters = prepareData(session, execution); + executionStrategy.print(printParameters, execution); + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + } + + private PrintParameters prepareData(final TcSession session, final ExecutionR17 report) throws KurtException { + LOGGER.debug("PrepareData started on: {}", report.getReportIdentifier().getReportTitle()); + + session.setObjectPropPolicy(report.getFullPolicy()); + + List revisionsSnecmaObject = new ItemRevisionQuery(session).searchID(report.getItemId()).findAll(); + if (revisionsSnecmaObject.isEmpty()) { + throw new InvalidUserInputException("Unabled to retrieve the list of revisons of the Part " + report.getItemId()); + } + + // Retrieve topItemRev + ItemRevision topItemRevision = retrieveTopItemRevision(report.getItemRevision(), revisionsSnecmaObject); + + // Retrieve all common data + doPrepareCommonDataForAllReports(session, topItemRevision, revisionsSnecmaObject, report); + + R17Printer printer = new R17Printer(); + PrintParameters printParameters = printer.makeMasterTemplate(report, report); + printer.constructDataMaps(session, printParameters, report); + + LOGGER.debug("PrepareData ended on: {}", report.getReportIdentifier().getReportTitle()); + return printParameters; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r17report/ExecutionR17.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r17report/ExecutionR17.java new file mode 100644 index 0000000..bd63572 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r17report/ExecutionR17.java @@ -0,0 +1,109 @@ +package com.capgemini.reports.definition.r15r16r17reports.r15r17reports.r17report; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.builder.R17Builder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.definition.r15r16r17reports.r15r17reports.AbstractExecutionR15R17; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.reports.parameters.IChecker; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class controls the execution of a R17 report. + */ +@Getter +@EqualsAndHashCode(callSuper = true) +public class ExecutionR17 extends AbstractExecutionR15R17 { + private static final long serialVersionUID = -7971226717525563715L; + + private static final String FILE_SEPARATOR = "_"; + + // Policies + private static final PolicyLocation R17_POLICY_XML_FULL = PolicyLocation.make("R17_policy_full", "/xml/policies/r17report/R17_policy_full.xml"); + private static final PolicyLocation R17_POLICY_XML_LIGHT = PolicyLocation.make("R17_policy_light", "/xml/policies/r17report/R17_policy_light.xml"); + + // Priority parameter + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R17); + + // Revision rule parameter + private static final String REPORT_REVISION_RULE = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R17", DEFAULT_REVISION_RULE); + + // Launch type parameter + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R17"); + + /** + * Constructor. + * + * @param partId {@link String} - the ID of the Part + * @param partRevision {@link String} - the Revision of the Part + * @param langue {@link String} - the language selected by the user + */ + public ExecutionR17(final String partId, final String partRevision, final String langue) { + super(partId, partRevision, langue, REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE); + } + + @Override + public String getTemplateLocation() { + return JasperTemplate.TEMPLATE_R17.getFilepath(); + } + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R17_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R17_POLICY_XML_FULL; + } + + @Override + public List getLongChecks() { + return new ArrayList<>(); + } + + @Override + public ReportEnum getReportIdentifier() { + return ReportEnum.REPORT_R17; + } + + @Override + public String getSpecifiedFileName() { + StringBuilder filename = + new StringBuilder(itemId).append(FILE_SEPARATOR).append(itemRevision).append(FILE_SEPARATOR).append("ListeDocRefart"); + if (!isFrench()) { + filename.append("_ENG"); + } + return filename.toString(); + } + + @Override + public PrintFormat getPrintingFormat() { + return PrintFormat.PDF; + } + + @Override + public IDataReportPreparator getDataPreparator() { + return new DataReportPreparatorR17(); + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return new ExecutionR17(itemId, itemRevision, frenchInput); + } + + @Override + public Class getReportBuilderClass() { + return R17Builder.class; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r17report/R17Printer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r17report/R17Printer.java new file mode 100644 index 0000000..66e7abe --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r15r17reports/r17report/R17Printer.java @@ -0,0 +1,36 @@ +package com.capgemini.reports.definition.r15r16r17reports.r15r17reports.r17report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.definition.r15r16r17reports.r15r17reports.AbstractR15R17Printer; +import com.capgemini.reports.execution.mapconstructor.IMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +/** + * This class is able to put the data gathered by an {@link ExecutionR17} into some {@link PrintParameters} for printing. + */ +@Slf4j +@EqualsAndHashCode(callSuper = true) +public final class R17Printer extends AbstractR15R17Printer implements IMapConstructor { + + private static final long serialVersionUID = -5917435254556072157L; + + @Override + protected void addSpecificParameters(final ExecutionR17 execution, final PrintParameters mainReport) { + // Nothing to add, all the job is performed by the AbstractR15R17Printer + } + + @Override + protected String getTitle(final ExecutionR17 execution) { + return "Définition technique de l'article et Définition de réalisation de l'article\nPart Definition and Part Manufacturing Definition"; + } + + @Override + public void constructDataMaps(TcSession session, final PrintParameters printParameters, final ExecutionR17 report) throws KurtException { + long start = System.currentTimeMillis(); + this.print(report, printParameters); + log.trace(EXECUTION_TIME_XXX_MS_FOR_YYY, System.currentTimeMillis() - start, "data filtering"); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r16report/DataReportPreparatorR16.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r16report/DataReportPreparatorR16.java new file mode 100644 index 0000000..e5db21e --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r16report/DataReportPreparatorR16.java @@ -0,0 +1,179 @@ +package com.capgemini.reports.definition.r15r16r17reports.r16report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObjectFactory; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRule; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRuleProperties; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.product.TcProduct; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindow; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindowConfiguration; +import com.capgemini.framework.teamcenter.object.runtime.TcRevisionRulesConfiguration; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.definition.r15r16r17reports.AbstractDataReportPreparatorR15R16R17; +import com.capgemini.reports.documentationobjects.DocTechnic; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericAssembRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.part.PartAeroRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.capgemini.reports.teamcenter.ObjectInfoHelper; +import com.capgemini.reports.teamcenter.ObjectInfoLoader; +import com.capgemini.reports.teamcenter.resolution.structureservice.SingleStructureServiceCaller; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Form; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + + +/** + * This class will allow to prepare data and findAll back data for making report R16. + */ +public class DataReportPreparatorR16 extends AbstractDataReportPreparatorR15R16R17 { + private static final long serialVersionUID = 3714231249482402544L; + private static final Logger LOGGER = LoggerFactory.getLogger(DataReportPreparatorR16.class); + private static final String EMPTY_STR = ""; + + @Override + public String print(TcSession session, ExecutionR16 execution, IExecutionStrategy executionStrategy) throws KurtException { + PrintParameters printParameters = prepareData(session, execution); + executionStrategy.print(printParameters, execution); + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + } + + private PrintParameters prepareData(final TcSession session, final ExecutionR16 report) throws KurtException { + LOGGER.debug("PrepareData started on: {}", report.getReportIdentifier().getReportTitle()); + // Retrieve the ProductRevision and the UnitRevision + // Note: a check performed earlier made sure that this list is NOT empty + session.setObjectPropPolicy(report.getFullPolicy()); + ItemRevision productRev = + new ItemRevisionQuery(session).searchID(report.getTheProduitUnitObject().getProductID()).findAll().get(0); + report.setTypeProduit(ObjectInfoLoader.getProductType(session, productRev)); + report.setClausePropriete(ObjectInfoLoader.getClausePropriete(report.getTypeProduit(), session)); + report.setProduitUnit(report.getTheProduitUnitObject().getProductID() + "-" + report.getTheProduitUnitObject().getUnitStr()); + + // All the checks are realised (Product-Unit-Generic) + // The appropriate revision is selected via the method getGenericItemRevision + ItemRevision generic = getGenericItemRevision(session, report); + String typeGeneric = generic.getTypeObject().getName(); + if (SnecmaObjectTypes.GENERIC_REVISION.equals(typeGeneric)) { + report.setGenericRev(new GenericRevision(session, generic)); + } else if (SnecmaObjectTypes.GENERIC_ASSEMB_REVISION.equals(typeGeneric)) { + report.setGenericRev(new GenericAssembRevision(session, generic)); + } else { + throw new KurtException("Object should be a Generic but is a: " + typeGeneric); + } + + TcBomObject topLineObject = new TcBomObjectFactory(session, generic).create(); + TcProduct productObject = new TcProduct(session, report.getTheProduitUnitObject().getProduct(session)); + int unit = report.getTheProduitUnitObject().getUnit(); + + TcRevisionRuleProperties revisionRuleProperties = new TcRevisionRuleProperties(productObject, unit); + + TcRevisionRule revisionRule = session.findRevRule(report.getRevisionRule()); + TcRevisionRulesConfiguration revRulesConfiguration = new TcRevisionRulesConfiguration(revisionRule, revisionRuleProperties); + + // Build the Generic and return the GenericBom + try (TcBomWindow bomWindow = session.createBomWindow(new TcBomWindowConfiguration(topLineObject, revRulesConfiguration))) { + session.setObjectPropPolicy(report.getFullPolicy()); + + BOMLineHolder rfGenericBom = new SingleStructureServiceCaller(session).resolve(bomWindow.topLine(), new R16BOMLineExplorer()); + List itemRevMaster = rfGenericBom.getAllItemRevMasters(); + session.loadProperties(itemRevMaster.toArray(new ModelObject[itemRevMaster.size()])); + + report.setArticleId(report.getGenericRev().getItemId()); + report.setArticleRevision(report.getGenericRev().getRevisionId()); + + // Treatment of the RFGenericBom + ItemRevision rfGeneric = rfGenericBom.getItemRevision(); + report.setRfGenericRev(new RFGenericRevision(session, rfGeneric)); + + List bomChildMap = rfGenericBom.getBomChilds(); + if (!bomChildMap.isEmpty()) { + for (BOMLineHolder currentChild : bomChildMap) { + ItemRevision itemRevChild = currentChild.getItemRevision(); + String childType = itemRevChild.getTypeObject().getName(); + if (SnecmaObjectTypes.PART_AERO_REVISION.equals(childType)) { + report.getPartNumberRevList().add(new PartAeroRevision(session, itemRevChild)); + } else if (SnecmaObjectTypes.DESCRIPTIF_REVISION.equals(childType)) { + retrieveDocNormAndDocNormStandardLists(session, itemRevChild, report); + retrieveDocTechnicList(session, itemRevChild, report); + } else if (SnecmaObjectTypes.RF_ADMIN_REVISION.equals(childType)) { + report.setRfAdminRev(new RFAdminRevision(session, itemRevChild)); + report.setFrontiereAvion(report.getRfAdminRev().getFrontiereAvion()); + report.setFrontiereCooperant(report.getRfAdminRev().getFrontiereCooperant()); + } else { + LOGGER.debug("The child {} have a type {} which has not selected", itemRevChild.getUid(), childType); + } + } + } else { + LOGGER.debug("No child has been found under the RF Generic Bom {}.", rfGenericBom.getUid()); + } + + // Specific treatment of DocTechnic + filterDocTechnic(report); + filterForDefinitionCertifiee(report); + + // Empty parameters + report.setRevisionArticle(EMPTY_STR); + report.setDateReleased(EMPTY_STR); + + R16Printer printer = new R16Printer(); + PrintParameters printParameters = printer.makeMasterTemplate(report, report); + printer.constructDataMaps(session, printParameters, report); + + LOGGER.debug("PrepareData ended on: {}", report.getReportIdentifier().getReportTitle()); + return printParameters; + } + } + + /** + * Get the appropriate Generic Revision. + * + * @param session {@link TcSession} - the tc session + * @param report - the execution report which provide all informations for the report + * @return the generic {@link ItemRevision} + * @throws InvalidUserInputException for the throwable exception + * @throws KurtException for the throwable exception + */ + ItemRevision getGenericItemRevision(final TcSession session, final ExecutionR16 report) throws KurtException { + List genericRevisions = new ItemRevisionQuery(session).searchID(report.getItemId()).findAll(); + + // Keep only the ItemRevision whose end item is the Product + List checkedGenerics = ObjectInfoHelper.getRevisionWithSameEndItem(session, genericRevisions, report.getTheProduitUnitObject().getProductID()); + genericRevisions.clear(); + + // Compare effectivities + List results = ObjectInfoHelper.getRevisionWithHighestRange(session, checkedGenerics, report.getTheProduitUnitObject().getUnitStr()); + checkedGenerics.clear(); + if (results.isEmpty()) { + // This error should not occur because it was already tested + throw new InvalidUserInputException("No generic found for item Id= " + report.getItemId()); + } + return results.get(0); + } + + private void filterForDefinitionCertifiee(final ExecutionR16 report) { + if (report.isDefCertifiee()) { + List transitList = new ArrayList<>(); + for (DocTechnic docTechnic : report.getDocTechnicList()) { + // These values are forbidden + if ("Définition / Design".equals(docTechnic.getTypeDocTechnic1())) { + transitList.add(docTechnic); + } + } + report.getDocTechnicList().clear(); + report.getDocTechnicList().addAll(transitList); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r16report/ExecutionR16.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r16report/ExecutionR16.java new file mode 100644 index 0000000..5d68bf4 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r16report/ExecutionR16.java @@ -0,0 +1,166 @@ +package com.capgemini.reports.definition.r15r16r17reports.r16report; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.builder.R16Builder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.definition.r15r16r17reports.AbstractExecutionR15R16R17; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.reports.parameters.checker.ObjectTypeChecker; +import com.capgemini.reports.reports.parameters.checker.ProductUnitGenericChecker; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.generic.AbstractGenericRevision; +import com.capgemini.reports.snecmaobjects.part.PartAeroRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class controls the execution of a R16 report. + */ +@Getter +@Setter(value = AccessLevel.PROTECTED) +@EqualsAndHashCode(callSuper = true) +public class ExecutionR16 extends AbstractExecutionR15R16R17 { + private static final long serialVersionUID = -3158586550831992551L; + + // Policies + private static final PolicyLocation R16_POLICY_XML_FULL = PolicyLocation.make("R16_policy_full", "/xml/policies/r16report/R16_policy_full.xml"); + private static final PolicyLocation R16_POLICY_XML_LIGHT = PolicyLocation.make("R16_policy_light", "/xml/policies/r16report/R16_policy_light.xml"); + // Priority parameter + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R16); + // Revision rule parameter + private static final String REPORT_REVISION_RULE = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R16", DEFAULT_REVISION_RULE); + // Launch type parameter + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R16"); + // Raw input parameters + protected final ProductUnit theProduitUnitObject; + // Internal working data + @Getter(value = AccessLevel.NONE) + protected final String typeImpression; + // Data gathered + protected final boolean isDefCertifiee; + @Getter(value = AccessLevel.NONE) + protected RFGenericRevision rfGenericRev; + protected String articleId; + protected AbstractGenericRevision genericRev; + protected List partNumberRevList = new ArrayList<>(); + protected RFAdminRevision rfAdminRev; + protected String frontiereAvion = ""; + protected String frontiereCooperant = ""; + @Getter(value = AccessLevel.NONE) + private String articleRevision; + + /** + * Constructor. + * + * @param produitUnit {@link ProductUnit} - the Product id and the Unit range. + * @param idTopGeneric {@link String} - the id of the top Generic. + * @param typeImpression {@link String} - the type of impression of the report + * @param langage {@link String} - the language selected by the user + */ + public ExecutionR16(final ProductUnit produitUnit, final String idTopGeneric, final String typeImpression, final String langage) { + super(idTopGeneric, langage, REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE); + this.theProduitUnitObject = produitUnit; + this.isDefCertifiee = "Def_certifiee".equals(typeImpression); + this.typeImpression = typeImpression; + } + + @Override + public List getLaunchData() { + List theCriteria = new ArrayList<>(); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PART_ID, itemId)); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PRODUCT, theProduitUnitObject.getProductID())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.UNIT, theProduitUnitObject.getUnitStr())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.TYPE_IMPRESSION, typeImpression)); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.LANGUAGE, frenchInput)); + return theCriteria; + } + + @Override + public List getQuickChecks() { + ArrayList quickChecks = new ArrayList<>(); + quickChecks.add(new ProductUnitGenericChecker(itemId, theProduitUnitObject)); + quickChecks.add(new ObjectTypeChecker(itemId, SnecmaObjectTypes.GENERIC)); + return quickChecks; + } + + @Override + public String getTemplateLocation() { + return JasperTemplate.TEMPLATE_R15R16.getFilepath(); + } + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R16_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R16_POLICY_XML_FULL; + } + + @Override + public List getLongChecks() { + return new ArrayList<>(); + } + + @Override + public ReportEnum getReportIdentifier() { + return ReportEnum.REPORT_R16; + } + + @Override + public String getSpecifiedFileName() { + String separator = "_"; + StringBuilder filename = new StringBuilder(articleId).append(separator).append(articleRevision).append(separator).append("FA_"); + + // Type impression + if (isDefCertifiee) { + filename.append("Certif"); + } else { + filename.append("Real"); + } + + // Language + if (!isFrench()) { + filename.append("_ENG"); + } + return filename.toString(); + } + + @Override + public PrintFormat getPrintingFormat() { + return PrintFormat.PDF; + } + + @Override + public IDataReportPreparator getDataPreparator() { + return new DataReportPreparatorR16(); + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return new ExecutionR16(theProduitUnitObject, articleId, typeImpression, frenchInput); + } + + @Override + public Class getReportBuilderClass() { + return R16Builder.class; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r16report/R16BOMLineExplorer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r16report/R16BOMLineExplorer.java new file mode 100644 index 0000000..41d7235 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r16report/R16BOMLineExplorer.java @@ -0,0 +1,35 @@ +package com.capgemini.reports.definition.r15r16r17reports.r16report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.resolution.filtering.ITcTypeFilter; +import com.capgemini.framework.teamcenter.resolution.filtering.TcTypeInclusionFilter; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderHelper; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.MalformedNomenclatureException; +import com.capgemini.reports.teamcenter.resolution.IBOMLineExplorer; +import com.capgemini.reports.teamcenter.resolution.structureservice.SingleStructureServiceCaller; +import com.capgemini.reports.teamcenter.resolution.structureservice.SingleStructureServiceCaller.SingleLevelExpander; + +/** + * Explorer of {@link BOMLineHolder}s used in {@link SingleStructureServiceCaller} for R16 report.
+ * Thanks to this class, the SINGLE resolution structure could carry on and the Part Number could be taken.
+ * The Rf Generic is returned, and its children PArt Aero / RF Admin and Descriptif are loaded + */ +public class R16BOMLineExplorer implements IBOMLineExplorer { + + private static final ITcTypeFilter FILTER_PART_ADMIN_DESCRIPTION = new TcTypeInclusionFilter(SnecmaObjectTypes.PART_AERO_REVISION, + SnecmaObjectTypes.RF_ADMIN_REVISION, SnecmaObjectTypes.DESCRIPTIF_REVISION); + private static final ITcTypeFilter FILTER_RF_GENERIC_REVISION = new TcTypeInclusionFilter(SnecmaObjectTypes.RF_GENERIC_REVISION); + + @Override + public BOMLineHolder explore(TcSession session, final SingleLevelExpander expander, final BOMLineHolder genericBom) throws EmptyNomenclatureException, + InvalidInputException, MalformedNomenclatureException { + BOMLineHolder expandedGenericBom = expander.expand(genericBom, FILTER_RF_GENERIC_REVISION); + BOMLineHolder rfGeneric = BOMLineHolderHelper.findRfGenericBL(expandedGenericBom); + return expander.expand(rfGeneric, FILTER_PART_ADMIN_DESCRIPTION); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r16report/R16Printer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r16report/R16Printer.java new file mode 100644 index 0000000..05f1579 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r15r16r17reports/r16report/R16Printer.java @@ -0,0 +1,105 @@ +package com.capgemini.reports.definition.r15r16r17reports.r16report; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.definition.r15r16r17reports.AbstractR15R16R17Printer; +import com.capgemini.reports.definition.r15r16r17reports.CommunR15R16R17ComponentVisitor; +import com.capgemini.reports.definition.r15r16r17reports.R15R16R17R24R25Keys; +import com.capgemini.reports.definition.r15r16r17reports.R15R16R17R24R25Keys.Page2; +import com.capgemini.reports.definition.r15r16r17reports.R15R16R17R24R25Keys.SpecificR15R16; +import com.capgemini.reports.execution.mapconstructor.IMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.snecmaobjects.part.PartAeroRevision; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +/** + * This class is able to put the data gathered by an {@link ExecutionR16} into some {@link PrintParameters} for printing. + */ +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class R16Printer extends AbstractR15R16R17Printer implements IMapConstructor { + + private static final long serialVersionUID = -7722864354275704498L; + + private static final String EMPTY_STRING = StringHelper.EMPTY; + private static final String UNKNOWN_STR = "???"; + private static final String SANS_OBJET = "Sans objet"; + private static final String NOT_APPLICABLE = "Not applicable "; + + @Override + protected List> addExtraDocLines(final ExecutionR16 execution) { + return new ArrayList<>(); + } + + @Override + protected void addOptionalParameters(final ExecutionR16 execution, final PrintParameters mainReport) { + Map params = new EnumMap<>(R15R16R17R24R25Keys.class); + List partNumberRevList = execution.getPartNumberRevList(); + if (partNumberRevList != null && !partNumberRevList.isEmpty()) { + Map map = new EnumMap<>(R15R16R17R24R25Keys.class); + if (partNumberRevList.size() == 1) { + map = partNumberRevList.get(0).accept(getVisitor(execution.isFrench())); + map.remove(R15R16R17R24R25Keys.PART_VERSION); + map.put(R15R16R17R24R25Keys.PART_VERSION, EMPTY_STRING); + } else { + map.put(R15R16R17R24R25Keys.ITEM_ID, UNKNOWN_STR); + map.put(R15R16R17R24R25Keys.PART_NUMBER, UNKNOWN_STR); + map.put(R15R16R17R24R25Keys.MANUFACTURER_CODE, UNKNOWN_STR); + map.put(R15R16R17R24R25Keys.PART_VERSION, EMPTY_STRING); + map.put(R15R16R17R24R25Keys.FRENCH_DESIGNATION, UNKNOWN_STR); + map.put(R15R16R17R24R25Keys.ENGLISH_DESIGNATION, UNKNOWN_STR); + map.put(R15R16R17R24R25Keys.OBTURATION, execution.isFrench() ? SANS_OBJET : NOT_APPLICABLE); + map.put(R15R16R17R24R25Keys.CLASSIFICATION, "-"); + map.put(R15R16R17R24R25Keys.FIELD_OPN_SERIALISATION, UNKNOWN_STR); + map.put(R15R16R17R24R25Keys.LOG_DOCUMENT, execution.isFrench() ? SANS_OBJET : NOT_APPLICABLE); + } + params.putAll(map); + } else { + params.putAll(execution.getGenericRev().accept(getVisitor(execution.isFrench()))); + } + params.put(R15R16R17R24R25Keys.MT_NUMBER, EMPTY_STRING); + params.put(R15R16R17R24R25Keys.PREVIOUS_RELEASE_DATE, EMPTY_STRING); + params.put(R15R16R17R24R25Keys.ITEM_ID, execution.getArticleId()); + mainReport.addReportParameters(params); + + Map map = new EnumMap<>(SpecificR15R16.class); + boolean isFrench = execution.isFrench(); + String frontiereAvion = execution.getFrontiereAvion(); + map.put(SpecificR15R16.INSTALLATION_INTERFACE, isFrench ? french(frontiereAvion) : english(frontiereAvion)); + String frontiereCooperant = execution.getFrontiereCooperant(); + map.put(SpecificR15R16.PARTNER_INTERFACE, isFrench ? french(frontiereCooperant) : english(frontiereCooperant)); + map.put(SpecificR15R16.PRODUCT_UNIT, execution.getProduitUnit()); + map.put(SpecificR15R16.SUB_TITLE, execution.isDefCertifiee() + ? "Documents de définition et procédés\nDefinition and process documents" + : "Documents de définition et procédés et pratiques de réalisation\nDefinition and process documents and manufacturing practices"); + mainReport.addReportParameters(map); + mainReport.addReportParameter(SpecificR15R16.IS_PREVIOUS_DEF.toString(), false); + } + + @Override + protected String getTitle(final ExecutionR16 execution) { + return execution.isDefCertifiee() + ? "Définition technique de l'article\nPart Definition" + : "Définition de réalisation de l'article\nPart Manufacturing definition"; + } + + @Override + protected IComponentVisitor> getVisitor(final boolean isFrench) { + return new CommunR15R16R17ComponentVisitor(isFrench); + } + + @Override + public void constructDataMaps(TcSession session, final PrintParameters printParameters, final ExecutionR16 data) throws KurtException { + long start = System.currentTimeMillis(); + this.print(data, printParameters); + log.trace("Execution time : {} ms for {}", System.currentTimeMillis() - start, "data filtering"); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/DataReportPreparatorR19.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/DataReportPreparatorR19.java new file mode 100644 index 0000000..080e5f9 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/DataReportPreparatorR19.java @@ -0,0 +1,251 @@ +package com.capgemini.reports.definition.r19report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.SnecmaObjectProperties; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.definition.r19report.ExecutionR19.ReportDataR19; +import com.capgemini.reports.documentationobjects.*; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.snecmaobjects.AbstractSnecmaObject; +import com.capgemini.reports.snecmaobjects.SnecmaObjectFactory; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import com.capgemini.reports.teamcenter.ObjectInfoHelper; +import com.capgemini.reports.teamcenter.queries.DirectQuery; +import com.capgemini.reports.teamcenter.queries.TypeQuery; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.RevisionRule; +import com.teamcenter.soa.client.model.strong.WorkspaceObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + + +/** + * This class will allow to prepare data and findAll back data for making report R19. + */ +public class DataReportPreparatorR19 implements IDataReportPreparator { + private static final long serialVersionUID = -7227615200390008230L; + private static final Logger LOGGER = LoggerFactory.getLogger(DataReportPreparatorR19.class); + + private static final String OBJECT_NOT_FOUND_PREFIX = "Object not found with UID '"; + private static final String OBJECT_NOT_FOUND_SUFFIX = "'"; + private static final int LEVEL = 1; + + /** + * Construct a map which contain folder use to extract parts referencing document. This function is specific for Report 19. + */ + static Map> buildMapRelationTypeFilter(final String documentType) throws KurtException { + Map> map = new HashMap<>(); + List relation = new ArrayList<>(); + + if (documentType.isEmpty()) { + throw new KurtException("Document type musn't be emtpy to construct map relation type and filter"); + } + + if (SnecmaObjectTypes.DOC_DRAWING_REVISION.equals(documentType)) { + relation.add(SnecmaObjectProperties.TC_IS_REPRESENTED_BY); + map.put(documentType, relation); + } else if (SnecmaObjectTypes.DOC_NORM.equals(documentType) || SnecmaObjectTypes.DOC_NORM_STANDARD.equals(documentType)) { + relation.add(SnecmaObjectTypes.FOLDER_REFERENCED_DOCS); + map.put(documentType, relation); + } else if (SnecmaObjectTypes.DOC_TECHNIC_REVISION.equals(documentType)) { + relation.add(SnecmaObjectProperties.FOLDER_PV_REACH_DOCS); + relation.add(SnecmaObjectProperties.FOLDER_PV_ITAR_DOCS); + relation.add(SnecmaObjectProperties.FOLDER_PV_DEFINITION_DOCS); + map.put(documentType, relation); + } + return map; + } + + /** + * Construct a list containing autorized part type for a given document type. + */ + static List getAuthorizedPartTypes(final String documentType) throws InvalidInputException { + List authorizedTpes = new ArrayList<>(); + if (documentType == null || documentType.isEmpty()) { + throw new InvalidInputException("Document type may not be emtpy to construct list authorized types"); + } + if (SnecmaObjectTypes.DOC_DRAWING_REVISION.equals(documentType)) { + authorizedTpes.add(SnecmaObjectTypes.DET_REVISION); + authorizedTpes.add(SnecmaObjectTypes.PART_AERO_REVISION); + authorizedTpes.add(SnecmaObjectTypes.PART_NO_AERO_REVISION); + } else if (SnecmaObjectTypes.DOC_NORM.equals(documentType)) { + authorizedTpes.add(SnecmaObjectTypes.DET_REVISION); + authorizedTpes.add(SnecmaObjectTypes.PART_AERO_REVISION); + authorizedTpes.add(SnecmaObjectTypes.PART_MAT_REVISION); + authorizedTpes.add(SnecmaObjectTypes.PART_NO_AERO_REVISION); + } else if (SnecmaObjectTypes.DOC_NORM_STANDARD.equals(documentType)) { + authorizedTpes.add(SnecmaObjectTypes.STANDARD_REVISION); + } else if (SnecmaObjectTypes.DOC_TECHNIC_REVISION.equals(documentType)) { + authorizedTpes.add(SnecmaObjectTypes.ALTERNATE_REVISION); + authorizedTpes.add(SnecmaObjectTypes.DET_REVISION); + authorizedTpes.add(SnecmaObjectTypes.PART_AERO_REVISION); + authorizedTpes.add(SnecmaObjectTypes.PART_NO_AERO_REVISION); + authorizedTpes.add(SnecmaObjectTypes.PART_MAT_REVISION); + authorizedTpes.add(SnecmaObjectTypes.STANDARD_REVISION); + } + return authorizedTpes; + } + + /** + * Construct a list containing descriptif revision type for document types DocNorm and DocTechnic only + */ + static List getAuthorizedDescriptifType(final String documentType) throws InvalidInputException { + List authorizedTypes = new ArrayList<>(); + if (documentType == null || documentType.isEmpty()) { + throw new InvalidInputException("Document type may not be emtpy to construct list authorized types"); + } + if (SnecmaObjectTypes.DOC_NORM.equals(documentType) || SnecmaObjectTypes.DOC_TECHNIC_REVISION.equals(documentType)) { + authorizedTypes.add(SnecmaObjectTypes.DESCRIPTIF_REVISION); + } + return authorizedTypes; + } + + @Override + public String print(TcSession session, ExecutionR19 execution, IExecutionStrategy executionStrategy) throws KurtException { + PrintParameters printParameters = prepareData(session, execution); + executionStrategy.print(printParameters, execution); + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + } + + private PrintParameters prepareData(final TcSession session, final ExecutionR19 report) throws KurtException { + LOGGER.info("PrepareData started for : " + report.getReportIdentifier().getReportCode()); + session.setObjectPropPolicy(report.getFullPolicy()); + + // STEP 1 : Obtain document + WorkspaceObject modelObject; + try { + modelObject = new DirectQuery(session).searchByUID(report.getDocumentUID()); + } catch (NotFoundException e) { + throw new InvalidUserInputException(OBJECT_NOT_FOUND_PREFIX + report.getDocumentUID() + OBJECT_NOT_FOUND_SUFFIX, e); + } + + // STEP 2 : Obtain the list of all ItemRevision where the document is referenced + // Build filter map and relation for current document + String documentType = modelObject.getTypeObject().getName(); + Map> relationAndTypesFilter = buildMapRelationTypeFilter(documentType); + List itemsRevisions = session.whereReferenced(modelObject, LEVEL, relationAndTypesFilter); + LOGGER.debug("List of item revision where the doc is referenced contains {} objects", itemsRevisions.size()); + + // STEP 3 : Filter only parts referencing the doc + List authorizedPartTypes = getAuthorizedPartTypes(documentType); + List partFilteringResult = ObjectInfoHelper.filteringObjectsReferencer(session, itemsRevisions, authorizedPartTypes); + LOGGER.debug("Number of parts filtered : {}", partFilteringResult.size()); + + // Convert ItemRevision corresponding to Parts to AbstractPart then sort it by item_id and revision_id + List abstractPartList = new ArrayList<>(); + for (ItemRevision itemRevision : partFilteringResult) { + AbstractPart theSnecmaObject = (AbstractPart) SnecmaObjectFactory.build(session, itemRevision); + abstractPartList.add(theSnecmaObject); + } + Collections.sort(abstractPartList, new PartIdRevComparator()); + + // STEP 4 : For DocNorm and DocTechnic only we use of a specific revision rule to ascend from Descriptif referencing the doc and find the Generic and Generic Assemb using it + // Filter Descriptif Revision referencing the doc + List authorizedDescriptifType = getAuthorizedDescriptifType(documentType); + List descriptifFilteringResult = filteringObjectsDescription(session, itemsRevisions, authorizedDescriptifType); + LOGGER.debug("Number Descriptif filtered : {}", descriptifFilteringResult.size()); + + // Get the R19 specific revision rule to get Generic and Generic Assemb using the Descriptif as input + List revisionRuleList = TypeQuery.getRevisionRule(session, report.getRevisionRule()); + List generics = new ArrayList<>(); + if (revisionRuleList == null || revisionRuleList.size() == 0) { + LOGGER.warn("The revision rules \"{}\" has not been found in Teamcenter! The Generic and GenericAssemb object will not be managed.", report.getRevisionRule()); + } else { + LOGGER.debug("The revision rules \"{}\" will be used.", report.getRevisionRule()); + RevisionRule reportRevisionRule = revisionRuleList.get(0); + + for (ItemRevision descriptifRevision : descriptifFilteringResult) { + // With level 2 whereUsed we get RF Generic Revision, Generic Revision and Generic Assemb Revision objects + List genericList = session.whereUsed(descriptifRevision, 2, reportRevisionRule); + if (genericList != null && genericList.size() != 0) { + List idList = new ArrayList<>(); + // We keep only one revision by Generic or Generic Assemb. RF Generic Revision are ignored. + for (ItemRevision generic : genericList) { + session.loadProperties(generic, "item_id", "object_name", "object_type"); + String objectType = generic.get_object_type(); + String itemId = generic.get_item_id(); + LOGGER.debug("Object item_id : {}, object_name : {}, object_type : {}", itemId, generic.get_object_name(), generic.get_object_type()); + if ("Generic Revision".equals(objectType) || "Generic Assemb Revision".equals(objectType)) { + if (!idList.contains(itemId)) { + idList.add(itemId); + generics.add(generic); + LOGGER.debug("Object item_id : {} selected.", itemId); + } + } + } + } + } + LOGGER.debug("Total number of Generic/Generic Assemb found : {}", generics.size()); + } + + // STEP 5 : Prepare data for ReportDataR19 and R19Printer + // Convert ItemRevision corresponding to Generic and Generic Assemb to AbstractSnecmaObject + List abstractGenericRevisionList = new ArrayList<>(); + for (ItemRevision itemRevision : generics) { + AbstractSnecmaObject abstractGenericRevision = SnecmaObjectFactory.build(session, itemRevision); + abstractGenericRevisionList.add(abstractGenericRevision); + } + + // Document + AbstractDoc theDoc = buildDocument(session, modelObject); + + // Convert all objects (Parts and Generic/GenericAssemb to a list of AbstractSnecmaObject to include in ReportDataR19 + List abstractSnecmaObjectList = new ArrayList<>(); + abstractSnecmaObjectList.addAll(abstractPartList); + abstractSnecmaObjectList.addAll(abstractGenericRevisionList); + + ReportDataR19 dataR19 = new ReportDataR19(theDoc, abstractSnecmaObjectList); + + R19Printer printer = new R19Printer(); + PrintParameters printParameters = printer.makeMasterTemplate(report, dataR19); + printer.constructDataMaps(session, printParameters, dataR19); + + LOGGER.debug("PrepareData ended on: {}", report.getReportIdentifier().getReportTitle()); + + return printParameters; + } + + private AbstractDoc buildDocument(final TcSession session, final ModelObject modelObject) { + AbstractDoc doc = null; + if (SnecmaObjectTypes.DOC_DRAWING_REVISION.equals(modelObject.getTypeObject().getName())) { + doc = new DocDrawing(session, (ItemRevision) modelObject); + } else if (SnecmaObjectTypes.DOC_NORM.equals(modelObject.getTypeObject().getName())) { + doc = new DocNorm(session, (Item) modelObject); + } else if (SnecmaObjectTypes.DOC_NORM_STANDARD.equals(modelObject.getTypeObject().getName())) { + doc = new DocNormStandard(session, (Item) modelObject); + } else if (SnecmaObjectTypes.DOC_TECHNIC_REVISION.equals(modelObject.getTypeObject().getName())) { + doc = new DocTechnic(session, (ItemRevision) modelObject); + } + return doc; + } + + /** + * Returns a list of object referencer answering to the specification
+ * Has statuts Def Approved And is the the highest sequence between object have the same item_id and revision_id .
+ * You must give a list objects referencing a document, a list object revision authorized and a list status authorized + */ + + public static List filteringObjectsDescription(final TcSession session, final List objectsToFilter, final List authorizedTypes) { + List results = new ArrayList<>(); + // getAuthorized types + for (ItemRevision object : objectsToFilter) { + LOGGER.debug("Object description type={} item_id={}", object.getTypeObject().getName(), object.get_item_id()); + if (authorizedTypes.contains(object.getTypeObject().getName())) { + results.add(object); + } else { + LOGGER.info("Object description Rejected unauthorized type={} item_id={}", object.getTypeObject().getName(), object.get_item_id()); + } + } + return results; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/ExecutionR19.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/ExecutionR19.java new file mode 100644 index 0000000..cd8217c --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/ExecutionR19.java @@ -0,0 +1,151 @@ +package com.capgemini.reports.definition.r19report; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.builder.R19Builder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.definition.r19report.ExecutionR19.ReportDataR19; +import com.capgemini.reports.documentationobjects.AbstractDoc; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.reports.parameters.checker.ModelObjectChecker; +import com.capgemini.reports.snecmaobjects.AbstractSnecmaObject; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class controls the execution of an R19 report. + */ +@Getter +public class ExecutionR19 extends AbstractExecutionReport { + + private static final long serialVersionUID = 4050093665599652815L; + + // Policies parameters + private static final PolicyLocation R19_POLICY_XML_FULL = PolicyLocation.make("R19_policy_full", "/xml/policies/r19report/R19_policy_full.xml"); + private static final PolicyLocation R19_POLICY_XML_LIGHT = PolicyLocation.make("R19_policy_light", "/xml/policies/r19report/R19_policy_light.xml"); + + // Configuration + private static final String FILE_SEPARATOR = "_"; + // Launch type parameter + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R19"); + // Revision rule parameter + private static final String REPORT_REVISION_RULE = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R19", DEFAULT_REVISION_RULE); + // Priority parameter + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R19); + private final String documentId; + private final String documentRev; + private final String documentType; + private final String documentUID; + + /** + * Executes the Report R19. + * + * @param documentId the ID of the document + * @param documentRev the revision of the Document + * @param documentType the Type of the document + * @param documentUID the UID of the document + */ + public ExecutionR19(final String documentId, final String documentRev, final String documentType, final String documentUID) { + super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE); + this.documentId = documentId; + this.documentRev = documentRev; + this.documentType = documentType; + this.documentUID = documentUID; + } + + + @Override + public List getQuickChecks() { + List quickChecks = new ArrayList<>(); + quickChecks.add(new ModelObjectChecker(documentUID, SnecmaObjectTypes.DOC_NORM, SnecmaObjectTypes.DOC_NORM_STANDARD, + SnecmaObjectTypes.DOC_DRAWING_REVISION, SnecmaObjectTypes.DOC_TECHNIC_REVISION)); + return quickChecks; + } + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R19_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R19_POLICY_XML_FULL; + } + + @Override + public List getLongChecks() { + return new ArrayList<>(); + } + + @Override + public String getTemplateLocation() { + return JasperTemplate.TEMPLATE_R19.getFilepath(); + } + + @Override + public ReportEnum getReportIdentifier() { + return ReportEnum.REPORT_R19; + } + + + @Override + public PrintFormat getPrintingFormat() { + return PrintFormat.XLSX; + } + + @Override + public List getLaunchData() { + List theCriteria = new ArrayList<>(); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.DOCUMENT_ID, documentId)); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.DOCUMENT_REVISION, documentRev)); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.TYPE_OBJET, documentType)); + return theCriteria; + } + + + @Override + public String getSpecifiedFileName() { + if (documentRev.isEmpty()) { + return "R19_" + documentId; + } else { + return "R19_" + documentId + FILE_SEPARATOR + documentRev; + } + } + + @Override + public IDataReportPreparator getDataPreparator() { + return new DataReportPreparatorR19(); + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return new ExecutionR19(documentId, documentRev, documentType, documentUID); + } + + @Override + public Class getReportBuilderClass() { + return R19Builder.class; + } + + /** + * POJO container of all data required for this report. + */ + @AllArgsConstructor + @Getter + static class ReportDataR19 { + private final AbstractDoc document; + private final List objectsWhereReferenced; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/PartIdRevComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/PartIdRevComparator.java new file mode 100644 index 0000000..7bc3eb9 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/PartIdRevComparator.java @@ -0,0 +1,28 @@ +package com.capgemini.reports.definition.r19report; + +import com.capgemini.reports.snecmaobjects.part.AbstractPart; + +import java.io.Serializable; +import java.util.Comparator; + +/** + * {@link AbstractPart} {@link Comparator}. Compares the Item ID, then the Revision ID. If both are equal, parts are considered equal. + */ +public class PartIdRevComparator implements Comparator, Serializable { + private static final long serialVersionUID = 618467339673492686L; + + /** + * Compare two Abstract by their item_id and revision_id. + * + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + @Override + public int compare(final AbstractPart part1, final AbstractPart part2) { + int comparatorValue = part1.getItemId().compareTo(part2.getItemId()); + if (comparatorValue == 0) { + comparatorValue = part1.getRevisionId().compareTo(part2.getRevisionId()); + } + return comparatorValue; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/R19Keys.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/R19Keys.java new file mode 100644 index 0000000..a9a210f --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/R19Keys.java @@ -0,0 +1,30 @@ +package com.capgemini.reports.definition.r19report; + +/** + * Enumeration of all the keys to the R19 report fields column. + */ +public enum R19Keys { + REFERENCE_DOCUMENT, + REVISION_DOCUMENT, + TYPE_DOCUMENT, + INDICE_DOCUMENT, + NOM_DOCUMENT, + DESIGNATION_ANGLAISE_DOCUMENT, + OBJET, + REFERENCE, + REVISION_REFERENCE, + NOM_REFERENCE, + TYPE_REFERENCE, + DESIGNATION_ENG, + RESPONSABLE_CONCEPTION, + PRODUIT, + CLASSEMENT, + SUIVI_UTILISATION, + DOCUMENT_DE_CONTROLE, + OBTURATION, + SUIVI_DUREE_VIE, + DUREE_VIE, + UNITE_DUREE_VIE, + DMD, + DMF +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/R19Printer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/R19Printer.java new file mode 100644 index 0000000..0db50ff --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/R19Printer.java @@ -0,0 +1,169 @@ +package com.capgemini.reports.definition.r19report; + +import com.capgemini.framework.common.LanguageHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.definition.r19report.ExecutionR19.ReportDataR19; +import com.capgemini.reports.definition.r19report.snecmaobject.R19ComponentVisitor; +import com.capgemini.reports.documentationobjects.*; +import com.capgemini.reports.execution.mapconstructor.AbstractStaticTemplateMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.snecmaobjects.AbstractSnecmaObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +/** + * Printer R19 Report construct a final list of datas for jasper. + */ +public class R19Printer extends AbstractStaticTemplateMapConstructor { + private static final long serialVersionUID = 5734951633170674016L; + + private static final String NORME_POUR_ARTICLES_STANDARDS = "Norme pour articles standards"; + private static final String REPRESENTATION_2D_DRAWING = "Représentation 2D"; + private static final String EMPTY = ""; + private static final Logger LOGGER = LoggerFactory.getLogger(R19Printer.class); + + private final R19ComponentVisitor componentBehaviour = new R19ComponentVisitor(); + + private static String check(final Object anInput) { + return anInput == null ? EMPTY : anInput.toString(); + } + + /* Extracts left side of a string of the form "French text / English text". */ + /* Separator slash may have *any* number (0+) of white spaces around them. */ + private static String french(final String string) { + return LanguageHelper.french(string); + } + + @Override + public void constructDataMaps(TcSession session, final PrintParameters printParameters, final ReportDataR19 data) throws KurtException { + // Retrieve parts properties + boolean isDocumentDataPrint = false; + AbstractDoc abstractDoc = data.getDocument(); + + List> lstMapData = new ArrayList<>(); + // If no object give an empty list with document + if (data.getObjectsWhereReferenced().isEmpty()) { + lstMapData.add(giveDocumentData(abstractDoc)); + lstMapData.add(giveEmptyPart()); + } else { + for (AbstractSnecmaObject elem : data.getObjectsWhereReferenced()) { + Map component = elem.accept(componentBehaviour); + + // Retrieve other properties + if (!isDocumentDataPrint) { + component.putAll(giveDocumentData(abstractDoc)); + isDocumentDataPrint = true; + } else { + component.putAll(giveEmptyDocument()); + } + + // Add to list + lstMapData.add(component); + } + } + // Give the list to jasper + printParameters.addReportData(translate(lstMapData)); + } + + private Map giveDocumentData(final AbstractDoc abstractDoc) { + String refDoc = ""; + String revDoc = ""; + String typeDoc = ""; + String indiceDoc = ""; + String nomDoc = ""; + String designationAnglaise = ""; + + if (SnecmaObjectTypes.DOC_DRAWING_REVISION.equals(abstractDoc.getType())) { + DocDrawing docDrawing = (DocDrawing) abstractDoc; + refDoc = docDrawing.getDocId(); + revDoc = docDrawing.getRevision(); + typeDoc = REPRESENTATION_2D_DRAWING; + indiceDoc = docDrawing.getIndicePlan(); + nomDoc = docDrawing.getName(); + designationAnglaise = docDrawing.getDesignationEn(); + } else if (SnecmaObjectTypes.DOC_NORM.equals(abstractDoc.getType())) { + DocNorm docNorm = (DocNorm) abstractDoc; + refDoc = docNorm.getDocId(); + revDoc = ""; + typeDoc = ""; + indiceDoc = ""; + nomDoc = docNorm.getItemName(); + designationAnglaise = ""; + } else if (SnecmaObjectTypes.DOC_NORM_STANDARD.equals(abstractDoc.getType())) { + DocNormStandard docNormStandard = (DocNormStandard) abstractDoc; + refDoc = docNormStandard.getDocId(); + revDoc = ""; + typeDoc = NORME_POUR_ARTICLES_STANDARDS; + indiceDoc = ""; + nomDoc = docNormStandard.getItemName(); + designationAnglaise = ""; + } else if (SnecmaObjectTypes.DOC_TECHNIC_REVISION.equals(abstractDoc.getType())) { + DocTechnic docTechnic = (DocTechnic) abstractDoc; + refDoc = docTechnic.getDocId(); + revDoc = docTechnic.getRevision(); + typeDoc = french(docTechnic.getTypeDocTechnic1()) + " / " + french(docTechnic.getTypeDocTechnic2()); + indiceDoc = docTechnic.getIndice(); + nomDoc = docTechnic.getName(); + designationAnglaise = docTechnic.getDesignationEn(); + } + + Map theMap = new EnumMap<>(R19Keys.class); + theMap.put(R19Keys.REFERENCE_DOCUMENT, refDoc); + theMap.put(R19Keys.REVISION_DOCUMENT, revDoc); + theMap.put(R19Keys.TYPE_DOCUMENT, typeDoc); + theMap.put(R19Keys.INDICE_DOCUMENT, indiceDoc); + theMap.put(R19Keys.NOM_DOCUMENT, nomDoc); + theMap.put(R19Keys.DESIGNATION_ANGLAISE_DOCUMENT, designationAnglaise); + return theMap; + } + + private Map giveEmptyDocument() { + Map theMap = new EnumMap<>(R19Keys.class); + theMap.put(R19Keys.REFERENCE_DOCUMENT, EMPTY); + theMap.put(R19Keys.REVISION_DOCUMENT, EMPTY); + theMap.put(R19Keys.TYPE_DOCUMENT, EMPTY); + theMap.put(R19Keys.INDICE_DOCUMENT, EMPTY); + theMap.put(R19Keys.NOM_DOCUMENT, EMPTY); + theMap.put(R19Keys.DESIGNATION_ANGLAISE_DOCUMENT, EMPTY); + return theMap; + } + + private Map giveEmptyPart() { + Map theMap = new EnumMap<>(R19Keys.class); + theMap.put(R19Keys.OBJET, EMPTY); + theMap.put(R19Keys.REFERENCE, EMPTY); + theMap.put(R19Keys.REVISION_REFERENCE, EMPTY); + theMap.put(R19Keys.NOM_REFERENCE, EMPTY); + theMap.put(R19Keys.TYPE_REFERENCE, EMPTY); + theMap.put(R19Keys.DESIGNATION_ENG, EMPTY); + theMap.put(R19Keys.RESPONSABLE_CONCEPTION, EMPTY); + theMap.put(R19Keys.PRODUIT, EMPTY); + theMap.put(R19Keys.CLASSEMENT, EMPTY); + theMap.put(R19Keys.DOCUMENT_DE_CONTROLE, EMPTY); + theMap.put(R19Keys.OBTURATION, EMPTY); + theMap.put(R19Keys.SUIVI_DUREE_VIE, EMPTY); + theMap.put(R19Keys.DUREE_VIE, EMPTY); + theMap.put(R19Keys.UNITE_DUREE_VIE, EMPTY); + theMap.put(R19Keys.DMD, EMPTY); + theMap.put(R19Keys.DMF, EMPTY); + return theMap; + } + + private List> translate(final List> visitorMaps) { + // Construct the map list expected by the printer + List> printerMaps = new ArrayList<>(); + for (Map visitorMap : visitorMaps) { + Map printerMap = new HashMap<>(); + for (R19Keys key : R19Keys.values()) { + printerMap.put(key.toString(), check(visitorMap.get(key))); + } + printerMaps.add(printerMap); + } + LOGGER.debug("Translate map " + printerMaps); + return printerMaps; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/snecmaobject/AbstractR19ComponentVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/snecmaobject/AbstractR19ComponentVisitor.java new file mode 100644 index 0000000..3f43db1 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/snecmaobject/AbstractR19ComponentVisitor.java @@ -0,0 +1,95 @@ +package com.capgemini.reports.definition.r19report.snecmaobject; + +import com.capgemini.reports.definition.r19report.R19Keys; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAGRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericAssembRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.mockup.MockupRevision; +import com.capgemini.reports.snecmaobjects.part.PartAssembRevision; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartAssembRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartRevision; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; + +import java.util.EnumMap; +import java.util.Map; + + +/** + * Abstract Visitor for Components of the r19 report. + */ +public abstract class AbstractR19ComponentVisitor implements IComponentVisitor> { + private static final long serialVersionUID = 1002247758669375790L; + + @Override + public Map visitComponent(ProductRevision aProductRev) { + // Not use + return new EnumMap<>(R19Keys.class); + } + + @Override + public Map visitComponent(PartAssembRevision aPartAssembRev) { + // Not use + return new EnumMap<>(R19Keys.class); + } + + @Override + public Map visitComponent(RFGenericRevision aRfGenericRev) { + // Not use + return new EnumMap<>(R19Keys.class); + } + + @Override + public Map visitComponent(RFPartAssembRevision aRfPartAssembRev) { + // Not use + return new EnumMap<>(R19Keys.class); + } + + @Override + public Map visitComponent(RFPartRevision aRfPartRev) { + // Not use + return new EnumMap<>(R19Keys.class); + } + + @Override + public Map visitComponent(RFAdminRevision aRfAdminRev) { + // Not use + return new EnumMap<>(R19Keys.class); + } + + @Override + public Map visitComponent(RFAdminARevision aRfAdminARev) { + // Not use + return new EnumMap<>(R19Keys.class); + } + + @Override + public Map visitComponent(RFAdminAPRevision aRfAdminAPRev) { + // Not use + return new EnumMap<>(R19Keys.class); + } + + @Override + public Map visitComponent(RFAdminAGRevision aRfAdminAGRev) { + // Not use + return new EnumMap<>(R19Keys.class); + } + + @Override + public Map visitComponent(MockupRevision aMockupRev) { + // Not use + return new EnumMap<>(R19Keys.class); + } + + @Override + public Map visitComponent(DescriptifRevision aDescriptifRev) { + // Not use + return new EnumMap<>(R19Keys.class); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/snecmaobject/R19ComponentVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/snecmaobject/R19ComponentVisitor.java new file mode 100644 index 0000000..9e8a637 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r19report/snecmaobject/R19ComponentVisitor.java @@ -0,0 +1,203 @@ +package com.capgemini.reports.definition.r19report.snecmaobject; + +import com.capgemini.framework.common.LanguageHelper; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.reports.definition.r19report.R19Keys; +import com.capgemini.reports.snecmaobjects.AbstractSnecmaObject; +import com.capgemini.reports.snecmaobjects.generic.AbstractGenericRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericAssembRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.part.*; +import com.capgemini.reports.snecmaobjects.supermodel.SuperModelRevision; + +import java.util.EnumMap; +import java.util.Map; + + +/** + * Visitor for component objects for the R19. + */ +public class R19ComponentVisitor extends AbstractR19ComponentVisitor { + private static final long serialVersionUID = 6744199471997128399L; + + private static final String SUFFIXE_REVISION = " Revision"; + private static final String EMPTY_STRING = StringHelper.EMPTY; + private static final String MATIERE = "matière"; + private static final String SANS_OBJET = "Sans objet"; + private static final String PART_NO_AERO = "Part No Aero"; + private static final String TRANSLATE_TO_PARTNONAERO_FR = "PartNonAéro"; + + /** + * Extracts left side of a string of the form "French text / English text".
+ * Separator slash may have *any* number (0+) of white spaces around them. + */ + private static String french(final String string) { + return LanguageHelper.french(string); + } + + @Override + public Map visitComponent(final DETRevision aDetRev) { + Map theMap = getAbstractSnecmaObjectProperties(aDetRev); + theMap.putAll(getAbstractPartProperties(aDetRev)); + theMap.put(R19Keys.TYPE_REFERENCE, french(aDetRev.getTypeDet1()) + " / " + french(aDetRev.getTypeDet2())); + theMap.put(R19Keys.OBTURATION, french(aDetRev.getObturation())); + theMap.put(R19Keys.SUIVI_DUREE_VIE, aDetRev.getSuiviDureeVie()); + theMap.put(R19Keys.DUREE_VIE, String.valueOf(aDetRev.getDureeVie())); + theMap.put(R19Keys.UNITE_DUREE_VIE, aDetRev.getUniteDureeVie()); + theMap.put(R19Keys.DMD, aDetRev.getDMD()); + theMap.put(R19Keys.DMF, aDetRev.getDMF()); + return theMap; + } + + @Override + public Map visitComponent(final PartAeroRevision aPartAeroRev) { + Map theMap = getAbstractSnecmaObjectProperties(aPartAeroRev); + theMap.putAll(getAbstractPartProperties(aPartAeroRev)); + theMap.put(R19Keys.TYPE_REFERENCE, french(aPartAeroRev.getTypeAero1()) + " / " + french(aPartAeroRev.getTypeAero2()) + " / " + + french(aPartAeroRev.getTypeAero3())); + theMap.put(R19Keys.OBTURATION, french(aPartAeroRev.getObturation())); + theMap.put(R19Keys.SUIVI_DUREE_VIE, aPartAeroRev.getSuiviDureeVie()); + theMap.put(R19Keys.DUREE_VIE, String.valueOf(aPartAeroRev.getDureeVie())); + theMap.put(R19Keys.UNITE_DUREE_VIE, aPartAeroRev.getUniteDureeVie()); + theMap.put(R19Keys.DMD, aPartAeroRev.getDMD()); + theMap.put(R19Keys.DMF, aPartAeroRev.getDMF()); + return theMap; + } + + @Override + public Map visitComponent(final PartNoAeroRevision aPartNoAeroRev) { + Map theMap = getAbstractSnecmaObjectProperties(aPartNoAeroRev); + theMap.putAll(getAbstractPartProperties(aPartNoAeroRev)); + theMap.put(R19Keys.TYPE_REFERENCE, french(aPartNoAeroRev.getTypeNoAero())); + theMap.put(R19Keys.OBTURATION, SANS_OBJET); + theMap.put(R19Keys.SUIVI_DUREE_VIE, aPartNoAeroRev.getSuiviDureeVie()); + theMap.put(R19Keys.DUREE_VIE, String.valueOf(aPartNoAeroRev.getDureeVie())); + theMap.put(R19Keys.UNITE_DUREE_VIE, aPartNoAeroRev.getUniteDureeVie()); + theMap.put(R19Keys.DMD, aPartNoAeroRev.getDMD()); + theMap.put(R19Keys.DMF, aPartNoAeroRev.getDMF()); + return theMap; + } + + @Override + public Map visitComponent(final PartMatRevision aPartMatRev) { + Map theMap = getAbstractSnecmaObjectProperties(aPartMatRev); + theMap.putAll(getAbstractPartProperties(aPartMatRev)); + theMap.put(R19Keys.TYPE_REFERENCE, MATIERE); + theMap.put(R19Keys.CLASSEMENT, aPartMatRev.getClassementMat()); + theMap.put(R19Keys.SUIVI_UTILISATION, SANS_OBJET); + theMap.put(R19Keys.DOCUMENT_DE_CONTROLE, SANS_OBJET); + theMap.put(R19Keys.OBTURATION, SANS_OBJET); + theMap.put(R19Keys.SUIVI_DUREE_VIE, SANS_OBJET); + theMap.put(R19Keys.DUREE_VIE, SANS_OBJET); + theMap.put(R19Keys.UNITE_DUREE_VIE, SANS_OBJET); + theMap.put(R19Keys.DMD, aPartMatRev.getDMD()); + theMap.put(R19Keys.DMF, aPartMatRev.getDMF()); + return theMap; + } + + @Override + public Map visitComponent(final StandardRevision aStandardRev) { + Map theMap = getAbstractSnecmaObjectProperties(aStandardRev); + theMap.putAll(getAbstractPartProperties(aStandardRev)); + theMap.put(R19Keys.TYPE_REFERENCE, french(aStandardRev.getTypeStandard())); + theMap.put(R19Keys.OBTURATION, SANS_OBJET); + theMap.put(R19Keys.SUIVI_DUREE_VIE, aStandardRev.getSuiviDureeVie()); + theMap.put(R19Keys.DUREE_VIE,String.valueOf(aStandardRev.getDureeVie())); + theMap.put(R19Keys.UNITE_DUREE_VIE, aStandardRev.getUniteDureeVie()); + theMap.put(R19Keys.DMD, aStandardRev.getDMD()); + theMap.put(R19Keys.DMF, aStandardRev.getDMF()); + return theMap; + } + + @Override + public Map visitComponent(SuperModelRevision aSuperModelRev) { + return null; + } + + @Override + public Map visitComponent(final AlternateRevision aAlternateRev) { + Map theMap = getAbstractSnecmaObjectProperties(aAlternateRev); + theMap.putAll(getAbstractPartProperties(aAlternateRev)); + theMap.put(R19Keys.TYPE_REFERENCE, french(aAlternateRev.getTypeAlt1()) + " / " + french(aAlternateRev.getTypeAlt2())); + theMap.put(R19Keys.OBTURATION, french(aAlternateRev.getObturation())); + theMap.put(R19Keys.SUIVI_DUREE_VIE, aAlternateRev.getSuiviDureeVie()); + theMap.put(R19Keys.DUREE_VIE, String.valueOf(aAlternateRev.getDureeVie())); + theMap.put(R19Keys.UNITE_DUREE_VIE, aAlternateRev.getUniteDureeVie()); + theMap.put(R19Keys.DMD, aAlternateRev.getDMD()); + theMap.put(R19Keys.DMF, aAlternateRev.getDMF()); + return theMap; + } + + @Override + public Map visitComponent(final GenericRevision aGenericRev) { + Map theMap = getAbstractGenericRevisionProperties(aGenericRev); + return theMap; + } + + @Override + public Map visitComponent(final GenericAssembRevision aGenericAssembRev) { + Map theMap = getAbstractGenericRevisionProperties(aGenericAssembRev); + return theMap; + } + + private Map getAbstractPartProperties(final AbstractPart anAbstractPart) { + Map theMap = new EnumMap<>(R19Keys.class); + theMap.put(R19Keys.DESIGNATION_ENG, anAbstractPart.getDesignationEN()); + theMap.put(R19Keys.RESPONSABLE_CONCEPTION, anAbstractPart.getResponsableConception()); + theMap.put(R19Keys.PRODUIT, anAbstractPart.getTypeProduit()); + theMap.put(R19Keys.CLASSEMENT, anAbstractPart.getClassement()); + theMap.put(R19Keys.SUIVI_UTILISATION, french(anAbstractPart.getSuiviUtilisation())); + theMap.put(R19Keys.DOCUMENT_DE_CONTROLE, french(anAbstractPart.getDocumentControle())); + return theMap; + } + + private Map getAbstractSnecmaObjectProperties(final AbstractSnecmaObject anAbstractSnecmaObject) { + Map theMap = new EnumMap<>(R19Keys.class); + + String valueForKeyObject = removeSuffixeRevision(anAbstractSnecmaObject.getType()); + if (valueForKeyObject.equals(PART_NO_AERO)) { + valueForKeyObject = translateToPartNonAero(valueForKeyObject); + } + + theMap.put(R19Keys.OBJET, valueForKeyObject); + theMap.put(R19Keys.REFERENCE, anAbstractSnecmaObject.getItemId()); + theMap.put(R19Keys.REVISION_REFERENCE, anAbstractSnecmaObject.getRevisionId()); + theMap.put(R19Keys.NOM_REFERENCE, anAbstractSnecmaObject.getName()); + return theMap; + } + + private Map getAbstractGenericRevisionProperties(final AbstractGenericRevision anAbstractGenericRevision) { + Map theMap = new EnumMap<>(R19Keys.class); + + String valueForKeyObject = removeSuffixeRevision(anAbstractGenericRevision.getType()); + + theMap.put(R19Keys.OBJET, valueForKeyObject); + theMap.put(R19Keys.REFERENCE, anAbstractGenericRevision.getItemId()); + theMap.put(R19Keys.REVISION_REFERENCE, SANS_OBJET); + theMap.put(R19Keys.NOM_REFERENCE, anAbstractGenericRevision.getName()); + theMap.put(R19Keys.TYPE_REFERENCE, SANS_OBJET); + theMap.put(R19Keys.DESIGNATION_ENG, anAbstractGenericRevision.getDesignationEN()); + theMap.put(R19Keys.RESPONSABLE_CONCEPTION, anAbstractGenericRevision.getResponsableConception()); + theMap.put(R19Keys.PRODUIT, SANS_OBJET); + theMap.put(R19Keys.CLASSEMENT, SANS_OBJET); + theMap.put(R19Keys.SUIVI_UTILISATION, SANS_OBJET); + theMap.put(R19Keys.DOCUMENT_DE_CONTROLE, SANS_OBJET); + theMap.put(R19Keys.OBTURATION, SANS_OBJET); + theMap.put(R19Keys.SUIVI_DUREE_VIE, SANS_OBJET); + theMap.put(R19Keys.DUREE_VIE, SANS_OBJET); + theMap.put(R19Keys.UNITE_DUREE_VIE, SANS_OBJET); + theMap.put(R19Keys.DMD, SANS_OBJET); + theMap.put(R19Keys.DMF, SANS_OBJET); + return theMap; + } + + /* Remove suffix Revision from an Part ex: Part Revision become Part */ + private String removeSuffixeRevision(final String part) { + return part.replace(SUFFIXE_REVISION, EMPTY_STRING).trim(); + } + + private String translateToPartNonAero(final String partNoAero) { + return partNoAero.replace(partNoAero, TRANSLATE_TO_PARTNONAERO_FR); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/Classe.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/Classe.java new file mode 100644 index 0000000..8ae11ca --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/Classe.java @@ -0,0 +1,51 @@ +package com.capgemini.reports.definition.r20report; + +import lombok.extern.slf4j.Slf4j; + +/** + * Enumeration of the Classe field's possible values. + */ +@Slf4j +public enum Classe { + /** + * The value 1. + */ + CLASSE_1 { + @Override + public String toString() { + return "1"; + } + }, + /** + * The value 2. + */ + CLASSE_2 { + @Override + public String toString() { + return "2"; + } + }; + + /** + * Parses the input {@link String} and returns the corresponding enum instance.
+ * Default value: Classe 1 + * + * @param classeStr the input string + * @return the enum instance + */ + public static Classe parse(final String classeStr) { + try { + int intValue = Integer.parseInt(classeStr); + if (intValue == 1) { + return CLASSE_1; + } else if (intValue == 2) { + return CLASSE_2; + } else { + log.warn("Could not decide between Classe 1 and Classe 2 for input '{}', defaulting to Classe 1", classeStr); + } + } catch (NumberFormatException e) { + log.info("Bad user input: not a number", e); + } + return CLASSE_2; // Default value + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/ConjointUnique.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/ConjointUnique.java new file mode 100644 index 0000000..ac0090f --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/ConjointUnique.java @@ -0,0 +1,51 @@ +package com.capgemini.reports.definition.r20report; + +import lombok.extern.slf4j.Slf4j; + +import java.util.Locale; + +/** + * Enumeration of the ConjointUnique's values. + */ +@Slf4j +public enum ConjointUnique { + /** + * The value Conjoint. + */ + CONJOINT { + @Override + public String toString() { + return "Conjoint"; + } + }, + /** + * The value Unique. + */ + UNIQUE { + @Override + public String toString() { + return "Unique"; + } + }; + + /** + * Parses an input {@link String} and returns the corresponding enum instance.
+ * Default value: Conjoint + * + * @param conjointUniqueStr the input string + * @return the instance + */ + public static ConjointUnique parse(final String conjointUniqueStr) { + String conjointUniqueLC = conjointUniqueStr.toLowerCase(Locale.FRENCH); + if ("conjoint".equals(conjointUniqueLC)) { + return CONJOINT; + } else { + if ("unique".equals(conjointUniqueLC)) { + return UNIQUE; + } else { + log.warn("Could not decide between Conjoint and Unique for input '{}', defaulting to Conjoint", conjointUniqueLC); + return CONJOINT; + } + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/DataReportPreparatorR20.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/DataReportPreparatorR20.java new file mode 100644 index 0000000..ddc7cfb --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/DataReportPreparatorR20.java @@ -0,0 +1,439 @@ +package com.capgemini.reports.definition.r20report; + +import com.capgemini.framework.common.HashMapComparingStringIDs; +import com.capgemini.framework.common.HashMapComparingStringIDs.IdMaker; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoSuchBomViewException; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObjectFactory; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRule; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRuleProperties; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.product.TcProduct; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindow; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindowConfiguration; +import com.capgemini.framework.teamcenter.object.runtime.TcRevisionRulesConfiguration; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderFactory; +import com.capgemini.reports.changeobjects.UnitRevision; +import com.capgemini.reports.changeobjects.change.TcChangeNoticeRevision; +import com.capgemini.reports.changeobjects.change.TcChangeRequestRevision; +import com.capgemini.reports.definition.r20report.ExecutionR20.ReportDataR20; +import com.capgemini.reports.definition.r20report.comparator.ChangeComparator; +import com.capgemini.reports.definition.r20report.comparator.GenericComparator; +import com.capgemini.reports.definition.r20report.printing.R20Printer; +import com.capgemini.reports.exceptions.MalformedNomenclatureException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.filter.AllIsGoodFilter; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.reports.parameters.Generics; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.snecmaobjects.generic.AbstractGeneric; +import com.capgemini.reports.snecmaobjects.generic.Generic; +import com.capgemini.reports.snecmaobjects.generic.GenericAssemb; +import com.capgemini.reports.snecmaobjects.part.PartAeroRevision; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.teamcenter.queries.saved.ChangeRequestQuery; +import com.capgemini.reports.teamcenter.resolution.structureservice.SingleStructureServiceCaller; +import com.capgemini.reports.teamcenter.resolution.structureservice.explorer.PartNumberFinder; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.GENERIC; + + +/** + * This class will allow to prepare data and findAll back data for making report R20. + */ +public class DataReportPreparatorR20 implements IDataReportPreparator { + private static final long serialVersionUID = -2545511620931881872L; + private static final Logger LOGGER = LoggerFactory.getLogger(DataReportPreparatorR20.class); + + + /** + * Comparator used by all the {@link Set}s of {@link TcChangeRequestRevision}, which only uses Item IDs to compare and no revision, so that two revisions of a same Item are recognised as equal. + */ + private static final Comparator CHANGE_COMPARATOR = new ChangeComparator(); + + /** + * Comparator used by all the Sets, which only uses Item IDs to compare, so that two revisions of a same Item are recognized as equal. + */ + private static final Comparator GENERIC_COMPARATOR = new GenericComparator(); + + /** + * Class of a {@link Set} of {@link TcChangeRequestRevision}. + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + private static final Class> CLASS_LIST_CHANGE = (Class) Set.class; + + // Sets of generics + /** + * This IdMaker uses only the Generic's ID to make an identifier, not his Revision. + */ + private static final IdMaker GENERIC_ID_MAKER = new IdMaker() { + private static final long serialVersionUID = 5794106087600351583L; + + @Override + public String makeId(final AbstractGeneric gen) { + return gen.getItemId(); + } + }; + // Unit After + /** + * {@link SortedSet} of all the Generics. + */ + private final SortedSet totalGenerics = new TreeSet<>(GENERIC_COMPARATOR); + /** + * {@link Map} of all the Generics under the Unit After. Points to the (maybe empty) list of {@link TcChangeRequestRevision} that made a change to key generic. + */ + private final Map> totalGenericsAfter = + new HashMapComparingStringIDs<>(GENERIC_ID_MAKER, AbstractGeneric.class, CLASS_LIST_CHANGE); + /** + * {@link Set} of all the Generics under the Unit After, which do not have any changes from previous unit. + */ + private final Set totalGenericsAfterNoMod = new TreeSet<>(GENERIC_COMPARATOR); + /** + * {@link Map} of all the Generics under the Unit After, which undergo a rupture of interchangeability. Points to the non-empty list of {@link TcChangeRequestRevision} that made a change to key generic. + */ + private final Map> totalGenericsAfterWithRupture = + new HashMapComparingStringIDs<>(GENERIC_ID_MAKER, AbstractGeneric.class, CLASS_LIST_CHANGE); + // Unit Before + /** + * {@link Map} of all the Generics under the Unit After, which do not have a rupture of interchangeability.Points to the non-empty list of {@link TcChangeRequestRevision} that made a change to key generic. + */ + private final Map> totalGenericsAfterWithoutRupture = + new HashMapComparingStringIDs<>(GENERIC_ID_MAKER, AbstractGeneric.class, CLASS_LIST_CHANGE); + /** + * {@link Map} of all the Generics under the Unit Before. Points to the (maybe empty) list of {@link TcChangeRequestRevision} that made a change to key generic. + */ + private final Map> totalGenericsBefore = + new HashMapComparingStringIDs<>(GENERIC_ID_MAKER, AbstractGeneric.class, CLASS_LIST_CHANGE); + /** + * {@link Set} of all the Generics under the Unit Before, which do not have any changes made to them in the unit after. + */ + private final Set totalGenericsBeforeNoMod = new TreeSet<>(GENERIC_COMPARATOR); + /** + * {@link Map} of all the Generics mentioned by a Removed Modification (LMR). Points to the non-empty list of {@link TcChangeRequestRevision} Points to the non-empty list of {@link TcChangeRequestRevision} from the LMR that mentionned this key generic. + */ + private final Map> totalGenericsBeforeLMR = + new HashMapComparingStringIDs<>(GENERIC_ID_MAKER, AbstractGeneric.class, CLASS_LIST_CHANGE); + /** + * {@link Map} of all the Generics under the Unit Before, which undergo a removed modification with rupture. Points to the non-empty {@link Set} of {@link TcChangeRequestRevision} from the LMR that mentionned this key generic. + */ + private final Map> totalGenericsBeforeLMRWithRupture = + new HashMapComparingStringIDs<>(GENERIC_ID_MAKER, AbstractGeneric.class, CLASS_LIST_CHANGE); + + // Sets of Change Requests + /** + * {@link Map} of all the Generics under the Unit Before, which undergo a removed modification without rupture (from the LMR that mentionned this key generic). + */ + private final Map> totalGenericsBeforeLMRWithoutRupture = + new HashMapComparingStringIDs<>(GENERIC_ID_MAKER, AbstractGeneric.class, CLASS_LIST_CHANGE); + /** + * The List of Removed Modifications objects, LMR or not. + */ + private final Set totalChangeRequest = new TreeSet<>(CHANGE_COMPARATOR); + /** + * The List of Removed Modifications objects found in the unit After. + */ + private final Set totalChangeRequestNotLMR = new TreeSet<>(CHANGE_COMPARATOR); + /** + * The List of Removed Modifications objects that the user requested as LMR. + */ + private final Set totalChangeRequestLMR = new TreeSet<>(CHANGE_COMPARATOR); + + /** + * Retrieve the PartNumbers of the generics using a Nomenclature Explosion, and associate them in a map. + */ + private static Map retrieveGenericsAndPartNumbers(final TcSession session, + ExecutionR20 report, final Set setOfGenerics, final ProductUnit productUnit) throws KurtException { + + Map genericsAndPartNumber = + new HashMapComparingStringIDs<>(GENERIC_ID_MAKER, AbstractGeneric.class, PartAeroRevision.class); + + for (AbstractGeneric generic : setOfGenerics) { + // Setup parameters + Generics generics; + if (generic instanceof Generic) { + generics = new Generics(productUnit, generic.getItemId(), null); + } else if (generic instanceof GenericAssemb) { + generics = new Generics(productUnit, null, generic.getItemId()); + } else { + LOGGER.warn("Object should be a Generic but is a: {}", generic.getType()); + continue; + } + + TcBomObject topLineObject = new TcBomObjectFactory(session, generics.getItem(session)).create(); + TcProduct productObject = new TcProduct(session, productUnit.getProduct(session)); + int unit = productUnit.getUnit(); + + TcRevisionRuleProperties revisionRuleProperties = new TcRevisionRuleProperties(productObject, unit); + + TcRevisionRule revisionRule = session.findRevRule(report.getRevisionRule()); + TcRevisionRulesConfiguration revRulesConfiguration = new TcRevisionRulesConfiguration(revisionRule, revisionRuleProperties); + + // Perform the job + SingleStructureServiceCaller theStructCaller = new SingleStructureServiceCaller(session); + try (TcBomWindow bomWindow = session.createBomWindow(new TcBomWindowConfiguration(topLineObject, revRulesConfiguration))) { + BOMLineHolder unbuiltPartAeroHolder = theStructCaller.resolve(bomWindow.topLine(), new PartNumberFinder()); + if (unbuiltPartAeroHolder == null) { + LOGGER.warn("Nomenclature explosion failed to obtain a Part Number for Generic={}, product={} and Unit={}", generic.getItemId(), + productUnit.getProductID(), productUnit.getUnit()); + continue; + } + + // Build Part number + BOMLineHolder partAeroHolder = BOMLineHolderFactory.buildTopBom(session, unbuiltPartAeroHolder, new AllIsGoodFilter()); + unbuiltPartAeroHolder.freeze(); + + // Put the PartNumber in the Map + genericsAndPartNumber.put(generic, (PartAeroRevision) partAeroHolder.getSnecmaObject()); + } catch (EmptyNomenclatureException e) { + String msg = String.format("Nomenclature explosion failed to obtain the GenericBom for Generic=%s, product=%s and Unit=%d", + generic.getItemId(), productUnit.getProductID(), productUnit.getUnit()); + LOGGER.error(msg, e); + } catch (NoSuchBomViewException e) { + LOGGER.error("Unable to find the GenericBom of the Generic: " + generic.getItemId(), e); + } catch (MalformedNomenclatureException e) { + LOGGER.error("Unable to find the Part Number of the Generic: " + generic.getItemId(), e); + } + } + return genericsAndPartNumber; + } + + @Override + public String print(TcSession session, ExecutionR20 execution, IExecutionStrategy executionStrategy) throws KurtException { + PrintParameters printParameters = prepareData(session, execution); + executionStrategy.print(printParameters, execution); + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + } + + private PrintParameters prepareData(final TcSession session, final ExecutionR20 report) throws KurtException { + LOGGER.debug("PrepareData started on: {}", report.getReportIdentifier().getReportTitle()); + + session.setObjectPropPolicy(report.getFullPolicy()); + + // Config ProduitUnits + report.getProductUnitBefore().parseUserUnit(); + report.getProductUnitAfter().parseUserUnit(); + + // Retrieve the Items of the provided LMR + retrieveLMR(session, report); + + // Build ProductRevision and UnitRevision before and after + ProductRevision product = retrieveProductRevisionBefore(session, report); + UnitRevision unitBefore = retrieveUnitBefore(report, product); + UnitRevision unitAfter = retrieveUnitAfter(report, product); + ReportDataR20 data = new ReportDataR20(product, unitBefore, unitAfter, report.getMatriculeMoteur(), report.getClasse(), + report.getMajorMinor(), report.getConjointUnique()); + + // Build ChangeRequests and generics + retrieveChangeRequests(unitAfter); + retrieveAllGenerics(unitBefore, unitAfter); + + // Put all retrieved data in the ReportData object + data.setGenericsAndPartNumbersAfter(retrieveGenericsAndPartNumbers(session, report, totalGenericsAfter.keySet(), report.getProductUnitAfter())); + data.setGenericsAndPartNumbersBefore(retrieveGenericsAndPartNumbers(session, report, totalGenericsBefore.keySet(), report.getProductUnitBefore())); + data.setTotalChangeRequest(totalChangeRequest); + data.setTotalChangeRequestLMR(totalChangeRequestLMR); + data.setTotalChangeRequestNotLMR(totalChangeRequestNotLMR); + data.setTotalGenerics(totalGenerics); + data.setTotalGenericsAfterWithoutRupture(totalGenericsAfterWithoutRupture); + data.setTotalGenericsAfterWithRupture(totalGenericsAfterWithRupture); + data.setTotalGenericsBeforeLMRWithoutRupture(totalGenericsBeforeLMRWithoutRupture); + data.setTotalGenericsBeforeLMRWithRupture(totalGenericsBeforeLMRWithRupture); + + R20Printer printer = new R20Printer(); + PrintParameters printParameters = printer.makeMasterTemplate(report, data); + printer.constructDataMaps(session, printParameters, data); + + LOGGER.debug("PrepareData ended on: {}", report.getReportIdentifier().getReportTitle()); + + return printParameters; + } + + UnitRevision retrieveUnitAfter(final ExecutionR20 report, final ProductRevision product) { + return UnitRevision.chooseRevisionOfUnitFromRange(report.getProductUnitAfter().getUnitStr(), product.getUnits(), + ExecutionR20.R20_STATUS_AFTER); + } + + private UnitRevision retrieveUnitBefore(final ExecutionR20 report, final ProductRevision product) { + return UnitRevision.chooseRevisionOfUnitFromRange(report.getProductUnitBefore().getUnitStr(), product.getUnits(), + ExecutionR20.R20_STATUS_BEFORE); + } + + /** + * This method uses the lmrString list of Modification IDs to produce a {@link List} of {@link TcChangeRequestRevision}.
+ * these {@link TcChangeRequestRevision} are built using TC objects queried from the input IDs. + * + * @param session the session to connect to TC + * @param report will provide the informations of the report which is executing + */ + private void retrieveLMR(final TcSession session, final ExecutionR20 report) { + for (String changeID : report.getLmrList()) { + List list = new ChangeRequestQuery(session).searchID(changeID).findAll(); + for (ItemRevision itemRev : list) { + totalChangeRequestLMR.add(new TcChangeRequestRevision(session, itemRev)); + } + } + } + + /** + * Retrieve the ProductRevision for the R20 report. + * + * @param session an active teamcenter session + * @param report will provide the informations of the report which is executing + * @return the built Product Revision + * @throws NotFoundException if no revisions of the product Before could be found + */ + ProductRevision retrieveProductRevisionBefore(final TcSession session, final ExecutionR20 report) throws NotFoundException { + ItemRevisionQuery queryProductBefore = new ItemRevisionQuery(session); + queryProductBefore.searchID(report.getProductUnitBefore().getProductID()); + List revisionsProductBefore = queryProductBefore.findAll(); + if (revisionsProductBefore.isEmpty()) { + throw new NotFoundException("Could not find the requested product before"); + } + return new ProductRevision(session, revisionsProductBefore.get(0)); + } + + private void retrieveChangeRequests(final UnitRevision unitAfter) { + for (TcChangeRequestRevision change : unitAfter.getChangeRequestsList()) { + if (change.isCadOrDCadOrMace()) { // filter: only CAD , DCAD or MACE + totalChangeRequestNotLMR.add(change); + } + } + totalChangeRequest.addAll(totalChangeRequestLMR); + totalChangeRequest.addAll(totalChangeRequestNotLMR); + } + + /** + * Retrieve the list of all the Generics in the pseudo folders of each ChangeNotice of each Removed Modification. + * + * @param unitBefore the unit before + * @param unitAfter the unit after + */ + private void retrieveAllGenerics(final UnitRevision unitBefore, final UnitRevision unitAfter) { + // FIRST GENERICS BEFORE ********************************************************************************** + // Gather all generics before, make them point to an empty list of mods, which will be enriched later as needed with LMR + for (AbstractGeneric generic : unitBefore.getGenerics()) { + if (GENERIC.equals(generic.getType())) { // Technical view only + totalGenericsBefore.put(generic, new TreeSet<>(CHANGE_COMPARATOR)); + } + } + totalGenericsBeforeNoMod.addAll(totalGenericsBefore.keySet()); // Preventively add them all the generics here, when we see they undergo a change, remove them from here + + // Retrieve the list of all the generics in the pseudo folders of each ChangeNotices of the Unit Before. + retrieveGenericsOfUnitBefore(); + + // NOW GENERICS AFTER ********************************************************************************** + + // Gather all generics after, make them point to an empty list of mods, which will be enriched later as needed with some Changes after + for (AbstractGeneric generic : unitAfter.getGenerics()) { + if (GENERIC.equals(generic.getType())) { // Technical view only + totalGenericsAfter.put(generic, new TreeSet<>(CHANGE_COMPARATOR)); + } + } + totalGenericsAfterNoMod.addAll(totalGenericsAfter.keySet()); // Preventively add them all, when we see they undergo a change, remove them from here + + // Retrieve the list of all the generics in the pseudo folders of each ChangeNotices of the Unit After. + retrieveGenericsOfUnitAfter(); + + // Gather all generics ever encountered *********************************************************** + totalGenerics.addAll(totalGenericsBefore.keySet()); + totalGenerics.addAll(totalGenericsAfter.keySet()); + } + + private void retrieveGenericsOfUnitBefore() { + for (TcChangeRequestRevision changeRequest : totalChangeRequestLMR) { + if (changeRequest.isCadOrDCadOrMace()) { + for (TcChangeNoticeRevision changeNotice : changeRequest.getChangeNoticesList()) { + if (changeNotice.isEtude()) { // Only keep change Notice "ETUDE" ! + extractGenericsFromChangeNotice(changeRequest, changeNotice); + } + } + } + } + totalGenericsBeforeLMR.putAll(totalGenericsBeforeLMRWithRupture); + totalGenericsBeforeLMR.putAll(totalGenericsBeforeLMRWithoutRupture); + } + + /** + * Retrieve the generic for the report R20. + */ + private void retrieveGenericsOfUnitAfter() { + for (TcChangeRequestRevision changeRequest : totalChangeRequestNotLMR) { + for (TcChangeNoticeRevision changeNotice : changeRequest.getChangeNoticesList()) { + for (AbstractGeneric genericWithRupture : changeNotice.getListOfGenericRevWithRupture()) { + if (GENERIC.equals(genericWithRupture.getType())) { // Technical view only + Set setOfModWithRupture = totalGenericsAfterWithRupture.get(genericWithRupture); + if (setOfModWithRupture == null) { + setOfModWithRupture = new TreeSet<>(CHANGE_COMPARATOR); + totalGenericsAfterWithRupture.put(genericWithRupture, setOfModWithRupture); + } + setOfModWithRupture.add(changeRequest); + totalGenericsAfterNoMod.remove(genericWithRupture); + } + } + for (AbstractGeneric genericWithoutRupture : changeNotice.getListOfGenericRevWithoutRupture()) { + if (GENERIC.equals(genericWithoutRupture.getType())) { // Technical view only + Set setOfModWithoutRupture = totalGenericsAfterWithoutRupture.get(genericWithoutRupture); + if (setOfModWithoutRupture == null) { + setOfModWithoutRupture = new TreeSet<>(CHANGE_COMPARATOR); + totalGenericsAfterWithoutRupture.put(genericWithoutRupture, setOfModWithoutRupture); + } + setOfModWithoutRupture.add(changeRequest); + totalGenericsAfterNoMod.remove(genericWithoutRupture); + } + } + } + } + } + + /** + * Adds the provided Change Notice's Generics with and withour rupture to the list of Generics LMR (IF they also are mentionned in the unit Before).
+ * By the end og this method: + *
    + *
  • {@code totalGenericsBeforeLMRWithRupture} will contain, for each GenericBefore concerned with this LMR, a link to the CR
  • + *
  • + *
  • + *
  • + *
+ */ + private void extractGenericsFromChangeNotice(final TcChangeRequestRevision changeRequest, final TcChangeNoticeRevision changeNotice) { + + for (AbstractGeneric genericWithOrWithoutRupture : changeNotice.getListOfGenericRevWithOrWithoutRupture()) { + + // A change notice 'Etude' may still contain Generic Assembs, we don't want them + // also, a Generic contained in an LMR than has nothing to do with the Unit Before, must be ignored + if (GENERIC.equals(genericWithOrWithoutRupture.getType()) && totalGenericsBefore.containsKey(genericWithOrWithoutRupture)) { + Set setOfModWithRupture = totalGenericsBeforeLMRWithRupture.get(genericWithOrWithoutRupture); + if (setOfModWithRupture == null) { + setOfModWithRupture = new TreeSet<>(CHANGE_COMPARATOR); + totalGenericsBeforeLMRWithRupture.put(genericWithOrWithoutRupture, setOfModWithRupture); + } + setOfModWithRupture.add(changeRequest); + totalGenericsBeforeNoMod.remove(genericWithOrWithoutRupture); + } + } + for (AbstractGeneric genericWithoutRupture : changeNotice.getListOfGenericRevWithoutRupture()) { + // A change notice 'Etude' may still contain Generic Assembs, we don't want them + // also, a Generic contained in an LMR than has nothing to do with the Unit Before, must be ignored + if (GENERIC.equals(genericWithoutRupture.getType()) && totalGenericsBefore.containsKey(genericWithoutRupture)) { + Set setOfModWithoutRupture = totalGenericsBeforeLMRWithoutRupture.get(genericWithoutRupture); + if (setOfModWithoutRupture == null) { + setOfModWithoutRupture = new TreeSet<>(CHANGE_COMPARATOR); + totalGenericsBeforeLMRWithRupture.put(genericWithoutRupture, setOfModWithoutRupture); + } + setOfModWithoutRupture.add(changeRequest); + totalGenericsBeforeNoMod.remove(genericWithoutRupture); + } + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/ExecutionR20.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/ExecutionR20.java new file mode 100644 index 0000000..be6397e --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/ExecutionR20.java @@ -0,0 +1,261 @@ +package com.capgemini.reports.definition.r20report; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.builder.R20Builder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.changeobjects.UnitRevision; +import com.capgemini.reports.changeobjects.change.TcChangeRequestRevision; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.definition.r20report.ExecutionR20.ReportDataR20; +import com.capgemini.reports.definition.r20report.checker.R20LMRChecker; +import com.capgemini.reports.definition.r20report.checker.R20UnitRevisionChecker; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.reports.parameters.checker.ProductChecker; +import com.capgemini.reports.snecmaobjects.generic.AbstractGeneric; +import com.capgemini.reports.snecmaobjects.part.PartAeroRevision; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Executes a R20 report. + */ +@Getter +@Setter(value = AccessLevel.PROTECTED) +@EqualsAndHashCode(callSuper = true) +public class ExecutionR20 extends AbstractExecutionReport { + + /** + * The authorized status for unit before. + */ + public static final StatusEnum[] R20_STATUS_BEFORE = + {StatusEnum.OPENING_IN_PROCESS, StatusEnum.OPEN, StatusEnum.J3A, StatusEnum.J3B, StatusEnum.FROZEN_IN_PROCESS, StatusEnum.FROZEN}; + /** + * The authorized status for units after. + */ + public static final StatusEnum[] R20_STATUS_AFTER = + {StatusEnum.OPENING_IN_PROCESS, StatusEnum.OPEN, StatusEnum.J3A, StatusEnum.J3B, StatusEnum.FROZEN_IN_PROCESS}; + // Revision rule parameter + static final String REPORT_REVISION_RULE = + SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R20", DEFAULT_REVISION_RULE); + private static final long serialVersionUID = -1700414458622831247L; + // Policies + private static final PolicyLocation R20_POLICY_XML_LIGHT = + PolicyLocation.make("R20_policy_light", "/xml/policies/r20report/R20_policy_light.xml"); + private static final PolicyLocation R20_POLICY_XML_FULL = PolicyLocation.make("R20_policy_full", "/xml/policies/r20report/R20_policy_full.xml"); + // Priority parameter + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R20); + // Launch type parameter + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R20"); + // Report parameters + private final ProductUnit productUnitBefore; + private final ProductUnit productUnitAfter; + private final String matriculeMoteur; + private final Classe classe; + private final MajorMinor majorMinor; + private final ConjointUnique conjointUnique; + + /** + * The List of Removed Modifications IDs. + */ + private final List lmrList; + + + /** + * Constructor of an Execution for R20. + * + * @param aProductUnitBefore {@link ProductUnit} before + * @param aProductUnitAfter {@link ProductUnit} after + * @param aMatricule String + * @param lmr {@link List} of String + * @param aClasse enum {@link Classe} + * @param aMajorMinor enum {@link MajorMinor} + * @param aConjointUnique enum {@link ConjointUnique} + */ + public ExecutionR20(final ProductUnit aProductUnitBefore, final ProductUnit aProductUnitAfter, final String aMatricule, final List lmr, + final Classe aClasse, final MajorMinor aMajorMinor, final ConjointUnique aConjointUnique) { + super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE); + productUnitBefore = aProductUnitBefore; + productUnitAfter = aProductUnitAfter; + matriculeMoteur = aMatricule; + lmrList = lmr; + classe = aClasse; + majorMinor = aMajorMinor; + conjointUnique = aConjointUnique; + } + + @Override + public List getLaunchData() { + List theCriteria = new ArrayList<>(); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.UNIT_BEFORE, productUnitBefore.getUnitStr())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PRODUCT_BEFORE, productUnitBefore.getProductID())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.UNIT_AFTER, productUnitAfter.getUnitStr())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PRODUCT_AFTER, productUnitAfter.getProductID())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.MATRICULE, matriculeMoteur)); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.LMR, R20Builder.packLMR(lmrList))); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.CLASSE, classe.toString())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.MAJOR_MINOR, majorMinor.toString())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.CONJOINT_UNIQUE, conjointUnique.toString())); + return theCriteria; + } + + @Override + public String getSpecifiedFileName() { + return "R20_" + productUnitAfter.getProductID() + "_" + productUnitAfter.getUnitStr() + "_" + productUnitBefore.getUnitStr(); + } + + @Override + public PrintFormat getPrintingFormat() { + return PrintFormat.PDF; + } + + @Override + public ReportEnum getReportIdentifier() { + return ReportEnum.REPORT_R20; + } + + @Override + public List getQuickChecks() { + List quickChecks = new ArrayList<>(); + ProductChecker productChecker = new ProductChecker(productUnitAfter.getProductID()); + quickChecks.add(productChecker); + quickChecks.add(new R20UnitRevisionChecker(productUnitAfter, true)); + quickChecks.add(new R20UnitRevisionChecker(productUnitBefore, false)); + if (!lmrList.isEmpty()) { + quickChecks.add(new R20LMRChecker(lmrList, productUnitBefore, productChecker)); + } + return quickChecks; + } + + @Override + public List getLongChecks() { + return new ArrayList<>(); + } + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R20_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R20_POLICY_XML_FULL; + } + + @Override + public String getTemplateLocation() { + return "/Jasper/template/report_r20/report_r20_master.jrxml"; + } + + @Override + public IDataReportPreparator getDataPreparator() { + return new DataReportPreparatorR20(); + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return new ExecutionR20(productUnitBefore, productUnitAfter, matriculeMoteur, lmrList, classe, majorMinor, conjointUnique); + } + + @Override + public Class getReportBuilderClass() { + return R20Builder.class; + } + + /** + * POJO container for all data used in R20 report. + */ + @Getter + @Setter(value = AccessLevel.PROTECTED) + public static class ReportDataR20 { + // From TC datas + private final ProductRevision product; + private final UnitRevision unitBefore; + private final UnitRevision unitAfter; + // Report parameters + private final String matriculeMoteur; + private final Classe classe; + private final MajorMinor majorMinor; + private final ConjointUnique conjointUnique; + + /** + * The List of Removed Modifications objects found in the unit After. + */ + private Set totalChangeRequestNotLMR; + /** + * The List of Removed Modifications objects that the user requested as LMR. + */ + private Set totalChangeRequestLMR; + /** + * {@link Map} of all the Generics under the Unit Before, which undergo a removed modification with rupture. Points to the non-empty {@link Set} of {@link TcChangeRequestRevision} from the LMR that mentionned this key generic. + */ + private Map> totalGenericsBeforeLMRWithRupture; + /** + * {@link Map} of all the Generics under the Unit After, which do not have a rupture of interchangeability.Points to the non-empty list of {@link TcChangeRequestRevision} that made a change to key generic. + */ + private Map> totalGenericsBeforeLMRWithoutRupture; + /** + * {@link Map} of all the Generics under the Unit After, which undergo a rupture of interchangeability. Points to the non-empty list of {@link TcChangeRequestRevision} that made a change to key generic. + */ + private Map> totalGenericsAfterWithRupture; + /** + * {@link Map} of all the Generics under the Unit After, which do not have a rupture of interchangeability.Points to the non-empty list of {@link TcChangeRequestRevision} that made a change to key generic. + */ + private Map> totalGenericsAfterWithoutRupture; + /** + * The List of Removed Modifications objects, LMR or not. + */ + private Set totalChangeRequest; + /** + * Maps each Generic with its PartAeroRevision, using the Unit Before. + */ + private Map genericsAndPartNumbersBefore; + /** + * Maps each Generic with its PartAeroRevision, using the Unit After. + */ + private Map genericsAndPartNumbersAfter; + /** + * {@link Set} of all the Generics. + */ + private Set totalGenerics; + + /** + * Simple constructor. + * + * @param product the product + * @param unitBefore the unit before + * @param unitAfter the unit after + * @param matriculeMoteur the 'matricule moteur' parameter + * @param classe the 'classe' parameter + * @param majorMinor the 'Major / minor' parameter + * @param conjointUnique the 'Conjoint/unique' parameter + */ + ReportDataR20(final ProductRevision product, final UnitRevision unitBefore, final UnitRevision unitAfter, final String matriculeMoteur, + final Classe classe, final MajorMinor majorMinor, final ConjointUnique conjointUnique) { + super(); + this.product = product; + this.unitBefore = unitBefore; + this.unitAfter = unitAfter; + this.matriculeMoteur = matriculeMoteur; + this.classe = classe; + this.majorMinor = majorMinor; + this.conjointUnique = conjointUnique; + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/MajorMinor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/MajorMinor.java new file mode 100644 index 0000000..5018a49 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/MajorMinor.java @@ -0,0 +1,51 @@ +package com.capgemini.reports.definition.r20report; + +import lombok.extern.slf4j.Slf4j; + +import java.util.Locale; + +/** + * Enumeration of the MajorMinor field's possible values. + */ +@Slf4j +public enum MajorMinor { + /** + * The value Major. + */ + MAJOR { + @Override + public String toString() { + return "Majeur"; + } + }, + /** + * The value Minor. + */ + MINOR { + @Override + public String toString() { + return "Mineur"; + } + }; + + /** + * Parses an input {@link String} and returns the corresponding enum instance.
+ * Default value: Major + * + * @param majorMinorStr the input string + * @return the instance + */ + public static MajorMinor parse(final String majorMinorStr) { + String majorMinorLC = majorMinorStr.toLowerCase(Locale.FRENCH); + if ("majeur".equals(majorMinorLC)) { + return MAJOR; + } else { + if ("mineur".equals(majorMinorLC)) { + return MINOR; + } else { + log.warn("Could not decide between major and Minor for input '{}', defaulting to Major", majorMinorLC); + return MAJOR; + } + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/checker/R20LMRChecker.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/checker/R20LMRChecker.java new file mode 100644 index 0000000..aed96d4 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/checker/R20LMRChecker.java @@ -0,0 +1,233 @@ +package com.capgemini.reports.definition.r20report.checker; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum.AbstractStatusFilter; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.changeobjects.UnitRevision; +import com.capgemini.reports.definition.r20report.ExecutionR20; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.releasestatus.RevisionStatusAndDate; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.reports.parameters.checker.ProductChecker; +import com.capgemini.reports.teamcenter.ObjectInfoHelper; +import com.capgemini.reports.teamcenter.queries.saved.ChangeRequestQuery; +import com.capgemini.reports.teamcenter.queries.saved.UnitFromChangeRequestQuery; +import com.google.common.base.Optional; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Form; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +import static com.capgemini.framework.teamcenter.TeamcenterObjectProperties.REVISION_LIST; +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.*; + +/** + * This class checks if a given "Liste de Modifications Retirées" is valid for a R20 report. + */ +@Getter +@Slf4j +public class R20LMRChecker implements IChecker { + + private static final Pattern YES_CHECKER = Pattern.compile(".*(Oui|Yes).*"); + + private static final String MACE = SnecmaObjectTypes.PV4_MACE_REVISION; + private static final String DCAD = SnecmaObjectTypes.PV4_DCAD_REVISION; + private static final String CAD_ACR = SnecmaObjectTypes.PV4_CAD_ACR_REVISION; + + private final List lmrList; + private final String productId; + private final ProductChecker productChecker; // Will provide the pruduct Item + private final String unitBeforeEffectivity; + + /** + * Simple constructor. + * + * @param lmrList List the list of modifications that need to be checked. + * @param productUnitBefore ProductUnit + * @param productChecker this productChecker is supposed to have been executed prior to this check, so that its produc titem will be available for this test + */ + public R20LMRChecker(final List lmrList, final ProductUnit productUnitBefore, final ProductChecker productChecker) { + this.lmrList = lmrList; + this.productId = productUnitBefore.getProductID(); + this.unitBeforeEffectivity = productUnitBefore.getUnitStr(); + this.productChecker = productChecker; + } + + private static boolean isUnitExceptionnel(final ItemRevision unitBefore) { + Form form = unitBefore.get_item_master_tag(); + if (form != null) { + String result = form.getPropertyObject(PV_UNIT_EXCEPTIONNEL).getStringValue(); + return YES_CHECKER.matcher(result).matches(); + } else { + return false; + } + } + + @Override + public void check(final TcSession session) throws InvalidUserInputException { + // Retrieve the list of Units for the used Product + List unitListOfProduct = retrieveListOfUnitsOfProduct(session); + ItemRevision unitBefore = choseRevision(session, unitListOfProduct); + List totalChangeRequestLMR = new ArrayList<>(); + for (String changeID : lmrList) { + // retrieve the ChangeRequest + ItemRevision changeRequestLmr = retrieveChangeRequest(session, changeID); + totalChangeRequestLMR.add(changeRequestLmr); + + // Test unit exceptionnel + boolean exceptionnel = isUnitExceptionnel(unitBefore); + if (exceptionnel) { + List listOfChangeOfUnitBefore = retrieveChangeRequestsOfUnit(session, unitBefore); + + int occurrencesInUnitBefore = occurrencesInListOfChangeOfUnit(changeID, listOfChangeOfUnitBefore); + // No change found in the Unit Before + if (occurrencesInUnitBefore == 0) { + throw new InvalidUserInputException(UserInputErrorEnum.REMOVED_CHANGE_REQUEST_IS_NOT_COMPATIBLE_WITH_BEFORE_EFFECTIVITY, + changeID); + } + // More than one revision found in the Unit Before + else if (occurrencesInUnitBefore > 1) { + throw new InvalidUserInputException( + UserInputErrorEnum.SEVERAL_REVISIONS_OF_RETRIEVED_CHANGE_REQUEST_ARE_COMPATIBLE_WITH_BEFORE_EFFECTIVITY, changeID); + } + } else { + // Retrieve the associated Units thanks to the pseudofolders + List listUnitRevFromCR = new UnitFromChangeRequestQuery(session).searchID(changeID).findAll(); + if (listUnitRevFromCR.isEmpty()) { + throw new InvalidUserInputException(UserInputErrorEnum.REMOVED_CHANGE_REQUEST_IS_NOT_COMPATIBLE_WITH_BEFORE_EFFECTIVITY, + changeID); + } + + // Find an appropriate Unit (contained in the list of units of the Product) + ItemRevision selectedUnit = findAppropriateUnitInProductListOfUnits(session, unitListOfProduct, listUnitRevFromCR); + if (selectedUnit == null) { + throw new InvalidUserInputException(UserInputErrorEnum.REMOVED_CHANGE_REQUEST_IS_NOT_COMPATIBLE_WITH_BEFORE_EFFECTIVITY, + changeID); + } + + List listOfChangeOfSelectedUnit = retrieveChangeRequestsOfUnit(session, selectedUnit); + int occurrencesInUnitBefore = occurrencesInListOfChangeOfUnit(changeID, listOfChangeOfSelectedUnit); + if (occurrencesInUnitBefore > 1) { + throw new InvalidUserInputException( + UserInputErrorEnum.SEVERAL_REVISIONS_OF_RETRIEVED_CHANGE_REQUEST_ARE_COMPATIBLE_WITH_BEFORE_EFFECTIVITY, changeID); + } + } + } + } + + private ItemRevision findAppropriateUnitInProductListOfUnits(final TcSession session, final List unitListOfProduct, final List listUnitRevFromCR) { + ItemRevision selectedUnit = null; + String selectedRange = ""; + for (ItemRevision unit : listUnitRevFromCR) { + String unitRange = UnitRevision.getRangeOfItemRevision(session, unit); + if (unitRange == null) { + continue; + } + if (unitListOfProduct.contains(unit) && Integer.parseInt(unitRange) <= Integer.parseInt(unitBeforeEffectivity)) { + if (selectedUnit == null) { + selectedUnit = unit; + selectedRange = unitRange; + } + // Choose the revision + if (Integer.parseInt(selectedRange) < Integer.parseInt(unitRange)) { + selectedUnit = unit; + selectedRange = unitRange; + } + } + } + return selectedUnit; + } + + private int occurrencesInListOfChangeOfUnit(final String changeID, final List listOfChangeOfUnitBefore) { + int indicatorIsinUnit = 0; + for (ItemRevision changeOfUnitBefore : listOfChangeOfUnitBefore) { + if (changeID.equals(changeOfUnitBefore.get_item_id())) { + indicatorIsinUnit++; + } + } + return indicatorIsinUnit; + } + + private ItemRevision retrieveChangeRequest(final TcSession session, final String changeID) throws InvalidUserInputException { + List listChangeRev = new ChangeRequestQuery(session).searchID(changeID).findAll(); + if (listChangeRev.isEmpty()) { + throw new InvalidUserInputException(UserInputErrorEnum.UNKNOWN_CHANGE_REQUEST, changeID); + } + // ChangeRequest only have one revision + ItemRevision theChange = listChangeRev.get(0); + if (SnecmaObjectTypes.PV4_CR_DEPREC_REVISION.equals(theChange.getTypeObject().getName())) { + throw new InvalidUserInputException(UserInputErrorEnum.REMOVED_CHANGE_REQUEST_IS_DEPRECATED, changeID); + } + return theChange; + } + + private List retrieveChangeRequestsOfUnit(final TcSession session, final ItemRevision referenceUnit) { + List changeRequestOfUnitBefore = new ArrayList<>(); + session.loadProperties(referenceUnit, PV_CHANGE_LIST); + ModelObject[] changes = referenceUnit.getPropertyObject(PV_CHANGE_LIST).getModelObjectArrayValue(); + session.loadProperties(changes); + for (ModelObject currentChange : changes) { + if (currentChange == null) { + log.warn("A Null ChangeRequest was obtained from the pseudo-folder 'PV_change_list' of a UnitRevision."); + continue; + } + ItemRevision currentItemRev = (ItemRevision) currentChange; + String objectTypeStr = currentItemRev.getTypeObject().getName(); + if (CAD_ACR.equals(objectTypeStr) || DCAD.equals(objectTypeStr) || MACE.equals(objectTypeStr)) { + changeRequestOfUnitBefore.add(currentItemRev); + } + } + return changeRequestOfUnitBefore; + } + + private List retrieveListOfUnitsOfProduct(final TcSession session) { + List unitListOfProduct = new ArrayList<>(); + Item product = productChecker.getProduct(); + session.loadProperties(product, REVISION_LIST); + ModelObject[] productRevs = product.getPropertyObject(REVISION_LIST).getModelObjectArrayValue(); + session.loadProperties(productRevs); + ItemRevision productRev = (ItemRevision) productRevs[0]; + + session.loadProperties(productRev, PV_UNIT); + ModelObject[] listOfUnitsBelowProduct = productRev.getPropertyObject(PV_UNIT).getModelObjectArrayValue(); + session.loadProperties(listOfUnitsBelowProduct); + for (ModelObject unit : listOfUnitsBelowProduct) { + if (unit != null) { + unitListOfProduct.add((ItemRevision) unit); + } + } + return unitListOfProduct; + } + + private ItemRevision choseRevision(final TcSession session, final List unitListOfProduct) throws InvalidUserInputException { + // Choose the revision of the Unit + // Obtain the list of all the UnitRevision with same range + List resultUnits = UnitRevision.getItemRevisionWithSameRange(session, unitBeforeEffectivity, unitListOfProduct); + + // Select the latest maturity unit + Optional potentialLatestUnitBefore = ObjectInfoHelper.getRevisionAndStatusWithMostRecentReleaseDate(session, resultUnits, null, StatusEnum.UNIT_MATURITY); + + if (!potentialLatestUnitBefore.isPresent()) { + throw new InvalidUserInputException(UserInputErrorEnum.PRODUCT_AND_UNIT_DOES_NOT_EXIST); + } else { + RevisionStatusAndDate latestUnitBefore = potentialLatestUnitBefore.get(); + AbstractStatusFilter filter = StatusEnum.allow(ExecutionR20.R20_STATUS_BEFORE); + + // Verify the status of the latest maturity status + if (filter.isIncluded(latestUnitBefore.getReleaseStatus().get_name())) { + return latestUnitBefore.getItemRevision(); + } else { + throw new InvalidUserInputException(UserInputErrorEnum.PRODUCT_AND_UNIT_DOES_NOT_EXIST); + } + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/checker/R20UnitRevisionChecker.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/checker/R20UnitRevisionChecker.java new file mode 100644 index 0000000..12b139a --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/checker/R20UnitRevisionChecker.java @@ -0,0 +1,92 @@ +package com.capgemini.reports.definition.r20report.checker; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.reports.definition.r20report.ExecutionR20; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.releasestatus.RevisionStatusAndDate; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.reports.parameters.checker.ProductUnitChecker; +import com.capgemini.reports.reports.parameters.checker.UnitRevisionChecker; +import com.capgemini.reports.teamcenter.ObjectInfoHelper; +import com.google.common.base.Optional; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class checks if a given UnitRevision is valid for a R20 report.
+ * It assumes that the Product and the unit exist (using a {@link ProductUnitChecker}.
+ * It fails if the unit does not have an effectivity matching the product ID. + */ +public class R20UnitRevisionChecker extends UnitRevisionChecker { + + private final BeforeOrAfter beforeOrAfter; + + /** + * Constructor for R20 report. + * + * @param productUnit the {@link ProductUnit Product and the Unit} that need to be checked. + * @param isAfter boolean Take true if this ProductUnit is an "After". Take false if it is a "Before". + */ + public R20UnitRevisionChecker(final ProductUnit productUnit, final boolean isAfter) { + super(productUnit); + if (isAfter) { + this.beforeOrAfter = BeforeOrAfter.AFTER; + } else { + this.beforeOrAfter = BeforeOrAfter.BEFORE; + } + } + + @Override + protected List checkUnits(final TcSession session) throws InvalidUserInputException { + List unitsOfProductInRange = super.checkUnits(session); + StatusEnum[] allowedStatuses = beforeOrAfter == BeforeOrAfter.BEFORE ? ExecutionR20.R20_STATUS_BEFORE : ExecutionR20.R20_STATUS_AFTER; + // Obtain the latest maturity status overall + RevisionStatusAndDate latest; + Optional maybeLatestUnit = + ObjectInfoHelper.getRevisionAndStatusWithMostRecentReleaseDate(session, unitsOfProductInRange, null, StatusEnum.UNIT_MATURITY); + if (!maybeLatestUnit.isPresent()) { + throw latestUnitDoesNotHaveTheCorrectMaturity(); // Actually, it doesn't have a maturity status at all :O + } else { + latest = maybeLatestUnit.get(); + } + + // Verify the latest maturity status is of an allowed type + if (StatusEnum.allow(allowedStatuses).isExcluded(latest.getReleaseStatus())) { + throw latestUnitDoesNotHaveTheCorrectMaturity(); // Maturity is excluded! + } + List result = new ArrayList<>(); + result.add(latest.getItemRevision()); + return result; + } + + /** + * Just adapting this error message for R20. + * + * @return the custom exception + */ + @Override + protected InvalidUserInputException unitNotAssociatedToProduct() { + if (this.beforeOrAfter.equals(BeforeOrAfter.AFTER)) { + return new InvalidUserInputException(UserInputErrorEnum.THE_UNIT_AFTER_IS_NOT_ASSOCIATED_TO_THE_PRODUCT_AFTER); + } else { + return new InvalidUserInputException(UserInputErrorEnum.THE_UNIT_BEFORE_IS_NOT_ASSOCIATED_TO_THE_PRODUCT_BEFORE); + } + } + + private InvalidUserInputException latestUnitDoesNotHaveTheCorrectMaturity() { + if (this.beforeOrAfter.equals(BeforeOrAfter.AFTER)) { + return new InvalidUserInputException(UserInputErrorEnum.THE_LATEST_UNIT_AFTER_DOES_NOT_HAVE_THE_APPROPRIATE_MATURITY); + } else { + return new InvalidUserInputException(UserInputErrorEnum.THE_LATEST_UNIT_BEFORE_DOES_NOT_HAVE_THE_APPROPRIATE_MATURITY); + } + } + + private enum BeforeOrAfter { + BEFORE, + AFTER + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/comparator/ChangeComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/comparator/ChangeComparator.java new file mode 100644 index 0000000..eeea4fd --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/comparator/ChangeComparator.java @@ -0,0 +1,22 @@ +package com.capgemini.reports.definition.r20report.comparator; + +import com.capgemini.reports.changeobjects.change.TcChangeRequestRevision; + +import java.io.Serializable; +import java.util.Comparator; + +/** + * This class will allow to compare two changes. + */ +public class ChangeComparator implements Comparator, Serializable { + private static final long serialVersionUID = -2191199657528201566L; + + /** + * @param obj1 first change to compare + * @param obj2 second change to compare + */ + @Override + public int compare(final TcChangeRequestRevision obj1, final TcChangeRequestRevision obj2) { + return obj1.getItemId().compareTo(obj2.getItemId()); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/comparator/GenericComparator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/comparator/GenericComparator.java new file mode 100644 index 0000000..7aaae2e --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/comparator/GenericComparator.java @@ -0,0 +1,15 @@ +package com.capgemini.reports.definition.r20report.comparator; + +import com.capgemini.reports.snecmaobjects.generic.AbstractGeneric; + +import java.io.Serializable; +import java.util.Comparator; + +public class GenericComparator implements Comparator, Serializable { + private static final long serialVersionUID = -2723597994389438L; + + @Override + public int compare(final AbstractGeneric obj1, final AbstractGeneric obj2) { + return obj1.getItemId().compareTo(obj2.getItemId()); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/printing/Page3TemplateGenerator.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/printing/Page3TemplateGenerator.java new file mode 100644 index 0000000..0b0d3cc --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/printing/Page3TemplateGenerator.java @@ -0,0 +1,342 @@ +package com.capgemini.reports.definition.r20report.printing; + +import com.capgemini.framework.common.FileTemplate; +import com.capgemini.framework.common.HashMapComparingStringIDs; +import com.capgemini.framework.common.HashMapComparingStringIDs.IdMaker; +import com.capgemini.framework.common.ResourceHelper; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.reports.changeobjects.change.TcChangeRequestRevision; +import com.capgemini.reports.definition.r20report.ExecutionR20.ReportDataR20; +import com.capgemini.reports.exceptions.FileLoadingException; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.ReportPrintException; +import com.capgemini.reports.jasper.compilers.JasperCompiler; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.snecmaobjects.generic.AbstractGeneric; +import com.capgemini.reports.templates.Alignment; +import com.capgemini.reports.templates.CellFormat; +import com.capgemini.reports.templates.DynamicGridTemplateBuilder; +import lombok.extern.slf4j.Slf4j; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperReport; + +import java.util.*; +import java.util.Map.Entry; + +/** + * Generates a template for the page 3 of the R20 report.
+ * Adds a number of Dynamic tables as sub-reports to this page. + */ +@Slf4j +public class Page3TemplateGenerator extends FileTemplate { + + private static final String NO_GENERIC_FOUND = "(Aucun générique n'a pu être trouvé)"; + + private static final String KEY_COLUMN = "COL"; + private static final String ROW_HEADER_KEY = "ROW_HEADER"; + + private static final String TEMPLATE_PAGE3 = "/Jasper/template/report_r20/page3/report_r20_p3.jrxml"; + private static final String LINE1 = "\n "; + private static final String LINE2 = "\n "; + private static final String LINE3 = "\n >)$P{CROSS_TABLE}.get(\"DATA_"; + private static final String LINE3_P2 = "\"))]]>"; + private static final String LINE4 = "\n "; + private static final String LINE5 = "\n "; + + private static final String DATA_KEY_PREFIX = "DATA_SUBREPORT"; + private static final String TEMPLATE_KEY_PREFIX = "TEMPLATE_SUBREPORT"; + private static final String CROSS_TABLE = "CROSS_TABLE"; + + private static final int ONE_LINE_HEIGHT_PX = 13; + private static final int TWO_LINE_HEIGHT_PX = 28; + private static final int COLUMN_WIDTH_PX = 80; // 60 + private static final int FIRST_COLUMN_WIDTH_PX = 160; // 200 + + private static final String GREY_BACKGROUND = "#E3E3E3"; + private static final int COLUMNS_PER_PAGE = 8; // 10 + private static final int HEIGHT = 20; + /** + * Vertical spacing between consecutive tables. + */ + private static final int SPACING = 10; + + private static final String SANS = "Sans"; + private static final String AVEC = "Avec"; + private static final String EMPTY_STRING = ""; + /** + * This idMaker says two generics are equal if they have the same ID (it igniores their revisions). + */ + private static final IdMaker GENERIC_ID_MAKER = new IdMaker() { + private static final long serialVersionUID = 6329281427084937878L; + + @Override + public String makeId(final AbstractGeneric gen) { + return gen.getItemId(); + } + }; + @SuppressWarnings({"unchecked", "rawtypes"}) + private static final Class> CLASS_MAP_CHANGE_TO_STRING = (Class) Map.class; + /** + * Number of 'Data' columns to generate. + */ + private final int totalColumnNumber; + /** + * Number of lines (show the generic objects). + */ + private final int totalLines; + /** + * Number of tables to generate . + */ + private final int numSubGrid; + private final String page3RawTemplateAsString; + private final String ligneProduitApres; + private final List modNames; + private final List contentKeys; + private final List lineNames; + /** + * Columns, then line: gridData[col][line]. + */ + private final String[][] gridData; + + /** + * Creates a template Generator.
+ * A table may only contain 1 header column, an no more than 10 data columns. Everytime a column is added beyond, a new table is created for it. + * + * @param data will allow to prepare data for the report + * @throws FileLoadingException if unable yo load page 3 template + */ + Page3TemplateGenerator(final ReportDataR20 data) throws FileLoadingException { + super(); + this.totalColumnNumber = data.getTotalChangeRequest().size(); // At least 1 column, otherwise we'd findAll nullpointers + this.totalLines = data.getTotalGenerics().size(); + this.numSubGrid = 1 + totalColumnNumber / COLUMNS_PER_PAGE; + this.page3RawTemplateAsString = ResourceHelper.getResourceContent(TEMPLATE_PAGE3); + this.ligneProduitApres = data.getProduct().getProductLine(); + this.contentKeys = setupContentKeys(totalColumnNumber); + this.modNames = setupModNames(data); + this.lineNames = setupLineNames(data.getTotalGenerics()); + this.gridData = setupGridData(data, this.modNames); + } + + private static List setupContentKeys(final int numCol) { + List list = new ArrayList<>(); + for (int num = 0; num < numCol; num++) { + list.add(KEY_COLUMN + num); + } + return list; + } + + /** + * This methods sets up the name of the columns (the name of the generics). + * + * @param allGenerics all the generics that will be in the table + * @return a List of strings + */ + private static List setupLineNames(final Set allGenerics) { + List list = new ArrayList<>(); + for (AbstractGeneric generic : allGenerics) { + list.add(generic.getName()); + } + return list; + } + + /** + * creates a list of all the Modification names.
+ */ + private static List setupModNames(final ReportDataR20 data) { + List list = new ArrayList<>(); + for (TcChangeRequestRevision changeLMR : data.getTotalChangeRequestLMR()) { + list.add("Non Application
" + changeLMR.getItemId()); + } + for (TcChangeRequestRevision changeNotLMR : data.getTotalChangeRequestNotLMR()) { + list.add("Application
" + changeNotLMR.getItemId()); + } + return list; + } + + /** + * Columns BEFORE lines!. + */ + private static String[][] setupGridData(final ReportDataR20 data, final List modNames) { + int numCol = data.getTotalChangeRequest().size(); + int numLine = data.getTotalGenerics().size(); + + // Initialize the array + String[][] grid = new String[numCol][numLine]; + + if (!modNames.isEmpty()) { + Map> dataMap = + new HashMapComparingStringIDs<>(GENERIC_ID_MAKER, AbstractGeneric.class, + CLASS_MAP_CHANGE_TO_STRING); + // Put the generics in + putGenericsInDataMap(dataMap, data.getTotalGenericsAfterWithRupture(), AVEC); + putGenericsInDataMap(dataMap, data.getTotalGenericsBeforeLMRWithRupture(), AVEC); + putGenericsInDataMap(dataMap, data.getTotalGenericsAfterWithoutRupture(), SANS); + putGenericsInDataMap(dataMap, data.getTotalGenericsBeforeLMRWithoutRupture(), SANS); + + // Use the map to buid the array + int line = 0; + for (AbstractGeneric gen : data.getTotalGenerics()) { + int col = 0; + for (TcChangeRequestRevision mod : data.getTotalChangeRequest()) { + if (dataMap.containsKey(gen)) { + if (dataMap.get(gen).containsKey(mod)) { + grid[col][line] = dataMap.get(gen).get(mod); + } else { + grid[col][line] = EMPTY_STRING; + } + } else { + grid[col][line] = EMPTY_STRING; + } + col++; + } + line++; + } + } + return grid; + } + + private static void putGenericsInDataMap(final Map> data, + final Map> map, final String withOrWithout) { + for (Entry> genEntry : map.entrySet()) { + if (!data.containsKey(genEntry.getKey())) { + data.put(genEntry.getKey(), new HashMap()); + } + for (TcChangeRequestRevision changeRequest : genEntry.getValue()) { + data.get(genEntry.getKey()).put(changeRequest, withOrWithout); + } + } + } + + static String subReportGrid(final int positionX, final int positionY, final String subReportKey) { + return StringHelper.concatToString(LINE1, LINE2, String.valueOf(positionX), LINE2_P3, String.valueOf(positionY), LINE2_P4, LINE3, + subReportKey, LINE3_P2, LINE4, subReportKey, LINE4_P2, LINE5); + } + + /** + * Generates the page's {@link PrintParameters}. + * + * @return the printing instructions, as a {@link PrintParameters} object + * @throws FileLoadingException if a template could not be loaded + * @throws ReportPrintException if a template could not be compiled + * @throws InvalidInputException if the table cannot be constructed properly in the template (invalid columns/rows count) + */ + PrintParameters generatePrintParameters() throws ReportPrintException, FileLoadingException, InvalidInputException { + PrintParameters page3 = PrintParameters.createSubReport(this.generateCode()); + + // For each Table... + Map crossTable = new HashMap<>(); + for (int tableNum = 0; tableNum < numSubGrid; tableNum++) { + int columnsDone = tableNum * COLUMNS_PER_PAGE; + int columnsLeft = totalColumnNumber - columnsDone; + int numColInThisTable = Math.min(columnsLeft, COLUMNS_PER_PAGE); // Total number of columns in this table, max is COLUMNS_PER_PAGE + String dataKey = DATA_KEY_PREFIX + tableNum; + String templateKey = TEMPLATE_KEY_PREFIX + tableNum; + String templateString = setupGridTemplate(columnsDone, columnsDone + numColInThisTable); + JasperReport compiledTemplate; + try { + compiledTemplate = JasperCompiler.compile(templateString); + } catch (JRException e) { + throw new ReportPrintException("Could not compile the sub-table template", e); + } + + // Copy all the lines... + List> tableData = new ArrayList<>(); + if (gridData.length > 0) { + for (int lineNum = 0; lineNum < gridData[0].length; lineNum++) { + Map line = new HashMap<>(); + line.put(ROW_HEADER_KEY, lineNames.get(lineNum)); + // ... of each columns of THIS sub-table + for (int tableColNum = 0; tableColNum < numColInThisTable; tableColNum++) { // Index of the working column in the sub-table + int gridColNum = tableColNum + columnsDone; // Index of the working column in the main data grid + String contentKey = contentKeys.get(gridColNum); + String contentVal = gridData[gridColNum][lineNum]; + line.put(contentKey, contentVal); + } + tableData.add(line); // One full line is generated + } + } + // If there was nothing in the table, put a fake line to make it show up anyway + if (tableData.isEmpty()) { + // If there was some lines (Generic objects to show) + if (totalLines > 0) { + for (int lineNum = 0; lineNum < totalLines; lineNum++) { + Map line = new HashMap<>(); + line.put(ROW_HEADER_KEY, lineNames.get(lineNum)); + tableData.add(line); // One full line is generated + } + } + // Otherwise + else { + Map line = new HashMap<>(); + line.put(ROW_HEADER_KEY, NO_GENERIC_FOUND); + tableData.add(line); // One full line is generated + } + } + crossTable.put(templateKey, compiledTemplate); + crossTable.put(dataKey, tableData); + } + page3.addReportParameter(CROSS_TABLE, crossTable); + page3.addReportData(setupEmptyData()); + return page3; + } + + private String setupGridTemplate(final int startcol, final int endCol) throws FileLoadingException, InvalidInputException { + // Setup each column's properties: width, headers and content keys (first column is different) + List widths = new ArrayList<>(); + List keys = new ArrayList<>(); + List headers = new ArrayList<>(); + List firstLine = new ArrayList<>(); + List nothingIsDynamic = new ArrayList<>(); + List headerFormats = new ArrayList<>(); + List contentsformats = new ArrayList<>(); + List allIsStretchingwithOverflow = new ArrayList<>(); + widths.add(FIRST_COLUMN_WIDTH_PX); + keys.add(ROW_HEADER_KEY); + headers.add("Modifications Techniques"); + firstLine.add(ligneProduitApres); + nothingIsDynamic.add(false); + headerFormats.add(new CellFormat().setColor(GREY_BACKGROUND)); // Keep default alignment (left) + contentsformats.add(new CellFormat()); // Keep default alignment (left) + allIsStretchingwithOverflow.add(true); + for (int col = startcol; col < endCol; col++) { + widths.add(COLUMN_WIDTH_PX); + keys.add(contentKeys.get(col)); + headers.add(modNames.get(col)); + firstLine.add(EMPTY_STRING); // Empty because only first column has data: "Modifications Techniques" + nothingIsDynamic.add(false); + headerFormats.add(new CellFormat().setColor(GREY_BACKGROUND).setAlignment(Alignment.CENTER)); + contentsformats.add(new CellFormat().setAlignment(Alignment.CENTER)); + allIsStretchingwithOverflow.add(true); + } + DynamicGridTemplateBuilder template = + new DynamicGridTemplateBuilder(widths, keys, contentsformats, allIsStretchingwithOverflow, ONE_LINE_HEIGHT_PX); + template.addHeaderLine(ONE_LINE_HEIGHT_PX, firstLine, nothingIsDynamic, headerFormats, allIsStretchingwithOverflow); + template.addHeaderLine(TWO_LINE_HEIGHT_PX, headers, nothingIsDynamic, headerFormats, allIsStretchingwithOverflow); + String generatedTemplate = template.generateCode(); + log.trace(generatedTemplate); + return generatedTemplate; + } + + private List> setupEmptyData() { + List> list = new ArrayList<>(); + list.add(new HashMap()); + return list; + } + + @Override + public String generateCode() { + // Generates the template, containing a number of grid sub-tables + this.setTemplateContent(page3RawTemplateAsString); + this.setTagValue("BAND_HEIGHT", String.valueOf(numSubGrid * HEIGHT + SPACING * (numSubGrid - 1))); + StringBuilder subTables = new StringBuilder(); + for (int num = 0; num < numSubGrid; num++) { + subTables.append(subReportGrid(0, num * (HEIGHT + SPACING), "SUBREPORT" + num)); + } + this.setTagValue("SUBTABLES", subTables.toString()); + return super.generateCode(); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/printing/R20Printer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/printing/R20Printer.java new file mode 100644 index 0000000..45677bf --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/printing/R20Printer.java @@ -0,0 +1,416 @@ +package com.capgemini.reports.definition.r20report.printing; + +import com.capgemini.framework.common.LanguageHelper; +import com.capgemini.framework.common.ResourceHelper; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.changeobjects.UnitRevision; +import com.capgemini.reports.changeobjects.change.TcChangeRequestRevision; +import com.capgemini.reports.definition.r20report.ExecutionR20; +import com.capgemini.reports.definition.r20report.ExecutionR20.ReportDataR20; +import com.capgemini.reports.definition.r20report.visitors.R20Keys; +import com.capgemini.reports.definition.r20report.visitors.R20Keys.Page1; +import com.capgemini.reports.definition.r20report.visitors.R20Keys.Page4; +import com.capgemini.reports.documentationobjects.DocTechnic; +import com.capgemini.reports.exceptions.FileLoadingException; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.ReportPrintException; +import com.capgemini.reports.execution.mapconstructor.AbstractStaticTemplateMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.snecmaobjects.generic.AbstractGeneric; +import com.capgemini.reports.snecmaobjects.part.PartAeroRevision; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.users.SnecmaUser; +import com.capgemini.reports.workflows.Task; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.InputStream; +import java.util.*; +import java.util.Map.Entry; + +/** + * Printer of the R20 report. + */ +@Slf4j +@EqualsAndHashCode(callSuper = true) +public final class R20Printer extends AbstractStaticTemplateMapConstructor { + + private static final long serialVersionUID = -5470510531792553291L; + private static final String NONE = "(Aucun)"; + private static final String NO_GENERIC_FOUND = "(Aucun générique n'a pu être trouvé)"; + private static final String NOT_APPLICABLE = "(N/A)"; + private static final String WKF_VALIDATION_SO_UNIT = "Validation SO UNIT"; + private static final String COMMA_DELIMITER = ", "; + + private static final String SANS = "Sans"; + private static final String AVEC = "Avec"; + private static final String EMPTY_STRING = ""; + private static final String EXCEPTIONNEL = "Exceptionnel"; + private static final String NON_APPLICATION = "Non Application "; + private static final String APPLICATION = "Application "; + + private static final String SUBREPORT_NOIMPACTS = "SUBREPORT_NOIMPACTS"; + private static final String SUBREPORT_IMPACTS = "SUBREPORT_IMPACTS"; + private static final String SUBREPORT_GENERIC = "SUBREPORT_GENERIC"; + private static final String SUBREPORT_P1 = "SUBREPORT_P1"; + private static final String SUBREPORT_P2 = "SUBREPORT_P2"; + private static final String SUBREPORT_P3 = "SUBREPORT_P3"; + private static final String SUBREPORT_P4 = "SUBREPORT_P4"; + + private static final String JASPER_TEMPLATE_PAGE1 = "/Jasper/template/report_r20/report_r20_p1.jrxml"; + private static final String JASPER_TEMPLATE_PAGE2 = "/Jasper/template/report_r20/report_r20_p2.jrxml"; + private static final String JASPER_TEMPLATE_PAGE4 = "/Jasper/template/report_r20/report_r20_p4.jrxml"; + private static final String JASPER_TEMPLATE_PAGE2_GENERIC = "/Jasper/template/report_r20/page2/r20_p2_generics.jrxml"; + private static final String JASPER_TEMPLATE_PAGE2_IMPACTS = "/Jasper/template/report_r20/page2/r20_p2_impacts.jrxml"; + private static final String JASPER_TEMPLATE_PAGE2_NOIMPACTS = "/Jasper/template/report_r20/page2/r20_p2_noimpacts.jrxml"; + + /** + * Print the R20 report. + * + * @param mainReport the {@link PrintParameters} of the main report, to which the data and the sub-reports will be added + * @param data will allow to prepare data for the report + * @throws ReportPrintException if unable to setup the report's page templates + * @throws FileLoadingException if unable to read the report's page templates + * @throws InvalidInputException if date could not be printed properly (page 3) + */ + public static void print(final ReportDataR20 data, final PrintParameters mainReport) + throws ReportPrintException, FileLoadingException, InvalidInputException { + setupPage1(data, mainReport); + setupPage2(data, mainReport); + setupPage3(data, mainReport); + setupPage4(data, mainReport); + + // Setup main report + mainReport.addReportData(setupEmptyData()); + mainReport.addReportParameters(setupMainParameters(data)); + mainReport.addReportParameter(R20Keys.IS_CR_LIST_EMPTY, data.getTotalChangeRequest().isEmpty()); + mainReport.setReportTitle("Titre rapport principal"); + } + + private static void setupPage1(final ReportDataR20 data, final PrintParameters mainReport) throws FileLoadingException, ReportPrintException { + // Setup page 1 + try (InputStream page1Stream = ResourceHelper.getResourceAsStream(JASPER_TEMPLATE_PAGE1)) { + Collection> page1Data = setupPage1Data(data); + Map page1Params = new EnumMap<>(R20Keys.Page1.class); + mainReport.addSubReport(SUBREPORT_P1, page1Stream, page1Data, page1Params); + } catch (IOException e) { + log.error("Unable to close template for Page 1 of the R20 report", e); + } + + } + + private static void setupPage2(final ReportDataR20 data, final PrintParameters mainReport) throws ReportPrintException, FileLoadingException { + // Setup template streams + try (InputStream page2stream = ResourceHelper.getResourceAsStream(JASPER_TEMPLATE_PAGE2); + InputStream page2GenericStream = ResourceHelper.getResourceAsStream(JASPER_TEMPLATE_PAGE2_GENERIC); + InputStream page2ImpactStream = ResourceHelper.getResourceAsStream(JASPER_TEMPLATE_PAGE2_IMPACTS); + InputStream pageNoImactStream = ResourceHelper.getResourceAsStream(JASPER_TEMPLATE_PAGE2_NOIMPACTS)) { + // Setup print parameters + PrintParameters page2 = PrintParameters.createSubReport(page2stream); + page2.addSubReport(SUBREPORT_GENERIC, page2GenericStream, setupPage2GenericData(data), new EnumMap<>(R20Keys.Page2.Generics.class)); + page2.addSubReport(SUBREPORT_IMPACTS, page2ImpactStream, setupPage2ImpactsData(data), new EnumMap<>(R20Keys.Page2.Generics.class)); + page2.addSubReport(SUBREPORT_NOIMPACTS, pageNoImactStream, setupPage2NoImpactsData(data), new EnumMap<>(R20Keys.Page2.NoImpacts.class)); + page2.addReportData(setupEmptyData()); + page2.addReportParameters(new EnumMap<>(R20Keys.Page2.class)); + mainReport.addSubReport(SUBREPORT_P2, page2); + } catch (IOException e) { + log.warn("Exception encountered while closing input stream for R20 report", e); + } + } + + private static void setupPage3(final ReportDataR20 data, final PrintParameters mainReport) + throws FileLoadingException, ReportPrintException, InvalidInputException { + Page3TemplateGenerator page3TemplateGenerator = new Page3TemplateGenerator(data); + PrintParameters page3 = page3TemplateGenerator.generatePrintParameters(); + mainReport.addSubReport(SUBREPORT_P3, page3); + } + + private static void setupPage4(final ReportDataR20 data, final PrintParameters mainReport) throws FileLoadingException, ReportPrintException { + List> page4Data = setPage4Data(data); + Map page4Params = new EnumMap<>(R20Keys.Page4.class); + try (InputStream page4Stream = ResourceHelper.getResourceAsStream(JASPER_TEMPLATE_PAGE4)) { + mainReport.addSubReport(SUBREPORT_P4, page4Stream, page4Data, page4Params); + } catch (IOException e) { + log.warn("Unable to close template for Page 4 of the R20 report", e); + } + } + + private static List> setupEmptyData() { + List> list = new ArrayList<>(); + list.add(new HashMap()); + return list; + } + + private static Map setupMainParameters(final ReportDataR20 data) throws FileLoadingException { + Map parametersMap = new EnumMap<>(R20Keys.class); + BufferedImage image = ResourceHelper.loadImage("/Jasper/images/Snecma_logo.png"); + ProductRevision product = data.getProduct(); + UnitRevision unitBefore = data.getUnitBefore(); + UnitRevision unitAfter = data.getUnitAfter(); + String productLine = product.getProductLine(); + String productdomain = LanguageHelper.french(product.getDomain()); + + printDocGelData(parametersMap, unitAfter); + + printWorkflowData(parametersMap, unitAfter); + + // Put it all in the map + parametersMap.put(R20Keys.SNECMA_LOGO, image); + parametersMap.put(R20Keys.PRODUIT, product.getName()); + parametersMap.put(R20Keys.UNIT_AVANT, unitBefore.getName()); + parametersMap.put(R20Keys.UNIT_APRES, unitAfter.getName()); + parametersMap.put(R20Keys.EXCEPTIONNEL_AVANT, unitBefore.isExceptionnel() ? EXCEPTIONNEL : EMPTY_STRING); + parametersMap.put(R20Keys.EXCEPTIONNEL_APRES, unitAfter.isExceptionnel() ? EXCEPTIONNEL : EMPTY_STRING); + parametersMap.put(R20Keys.DOMAINE_PRODUIT_AVANT, productdomain); + parametersMap.put(R20Keys.DOMAINE_PRODUIT_APRES, productdomain); + parametersMap.put(R20Keys.LIGNE_PRODUIT_AVANT, productLine); + parametersMap.put(R20Keys.LIGNE_PRODUIT_APRES, productLine); + parametersMap.put(R20Keys.MATRICULE_MOTEUR, data.getMatriculeMoteur()); + parametersMap.put(R20Keys.CLASSE, data.getClasse().toString()); + parametersMap.put(R20Keys.MAJEUR_MINEUR, data.getMajorMinor().toString()); + parametersMap.put(R20Keys.CONJOINT_UNIQUE, data.getConjointUnique().toString()); + + return parametersMap; + } + + private static void printDocGelData(final Map parametersMap, final UnitRevision unitAfter) { + // Obtain data from Doc Gel + String docGelReference; + String docGelIndice; + DocTechnic docGel = unitAfter.getTechnicalDocGel(); + if (docGel != null && docGel.getTypeDocTechnic1() != null && docGel.getTypeDocTechnic1().contains("Document de gel")) { + docGelReference = docGel.getReference(); + docGelIndice = docGel.getIndice(); + } else { + docGelReference = NONE; + docGelIndice = NONE; + } + parametersMap.put(R20Keys.IDENTIFIANT_DOC_GEL_UNIT_APRES, docGelReference); + parametersMap.put(R20Keys.INDICE_DOCUMENT_GEL_UNIT_APRES, docGelIndice); + } + + private static void printWorkflowData(final Map parametersMap, final UnitRevision unitAfter) { + // Obtain data from workflow + String wkfOwner = ""; + Calendar wkfCreationDate = null; + String wkfApprobator = ""; + Calendar wkfValidationDate = null; + if (!unitAfter.getWorkflowsValidationUnitParSO().isEmpty()) { + Task validationUnit = unitAfter.getWorkflowsValidationUnitParSO().get(0); + wkfOwner = makeNameAndId(validationUnit.getOwningUser()); + wkfCreationDate = validationUnit.getCreationDate(); + for (Task childTask : validationUnit.getCompletedChildTasks()) { + if (WKF_VALIDATION_SO_UNIT.equals(childTask.getName())) { + wkfApprobator = makeNameAndId(childTask.getLastModUser()); + wkfValidationDate = childTask.getLastModDate(); + break; + } + } + } + // Handle null wkf (none found) + String wkfcreationDateStr = wkfCreationDate == null ? "" : TeamcenterDateFormatter.formatCalendarToFrench(wkfCreationDate); + String wkfValidationDateStr = wkfValidationDate == null ? "" : TeamcenterDateFormatter.formatCalendarToFrench(wkfValidationDate); + + parametersMap.put(R20Keys.DATE_CREATION, wkfcreationDateStr); + parametersMap.put(R20Keys.DATE_VALIDATION, wkfValidationDateStr); + parametersMap.put(R20Keys.NOM_CREATEUR_WORKFLOW, wkfOwner); + parametersMap.put(R20Keys.NOM_APPROBATEUR_TACHE, wkfApprobator); + } + + private static String makeNameAndId(final SnecmaUser owner) { + return owner.getName() + " (" + owner.getUserId() + ")"; + } + + /** + * Sets up the a table containing all the Modifications applied to form the unit After.
+ * The table is fist sorted by Application (LMR before regular mods) then by Change ID + */ + private static List> setupPage1Data(final ReportDataR20 data) { + List> changeRequestList = new ArrayList<>(); + for (TcChangeRequestRevision changeRequest : data.getTotalChangeRequestLMR()) { + String approbationSO = changeRequest.getApprobationSO(); + if (approbationSO == null) { + approbationSO = EMPTY_STRING; + } + Map lmrMap = new EnumMap<>(R20Keys.Page1.class); + lmrMap.put(R20Keys.Page1.CHANGE_REQUEST_APPLI, NON_APPLICATION); + lmrMap.put(R20Keys.Page1.CHANGE_REQUEST_ID, changeRequest.getItemId()); + lmrMap.put(R20Keys.Page1.CHANGE_REQUEST_NOM, changeRequest.getChangeName()); + lmrMap.put(R20Keys.Page1.CHANGE_REQUEST_NO_APPRO_SO, approbationSO); + changeRequestList.add(lmrMap); + } + for (TcChangeRequestRevision changeRequest : data.getTotalChangeRequestNotLMR()) { + String approbationSO = changeRequest.getApprobationSO(); + if (approbationSO == null) { + approbationSO = EMPTY_STRING; + } + Map lmrMap = new EnumMap<>(R20Keys.Page1.class); + lmrMap.put(R20Keys.Page1.CHANGE_REQUEST_APPLI, APPLICATION); + lmrMap.put(R20Keys.Page1.CHANGE_REQUEST_ID, changeRequest.getItemId()); + lmrMap.put(R20Keys.Page1.CHANGE_REQUEST_NOM, changeRequest.getChangeName()); + lmrMap.put(R20Keys.Page1.CHANGE_REQUEST_NO_APPRO_SO, approbationSO); + changeRequestList.add(lmrMap); + } + if (changeRequestList.isEmpty()) { + changeRequestList.add(new EnumMap(R20Keys.Page1.class)); + } + return changeRequestList; + } + + /** + * Sets up the a table containing all the generics taking part of a Modification with rupture (from unit After or LMR) with their PartAero Before (if any) and After (if any). + * + * @param data the executionR20 to findAll the data + * @return the table data as a List of Map + */ + private static List> setupPage2GenericData(final ReportDataR20 data) { + List> tableContent = new ArrayList<>(); + for (AbstractGeneric generic : data.getTotalGenericsBeforeLMRWithRupture().keySet()) { + putOneLineInPage2GenericsData(data, tableContent, generic); + } + for (AbstractGeneric generic : data.getTotalGenericsAfterWithRupture().keySet()) { + putOneLineInPage2GenericsData(data, tableContent, generic); + } + return tableContent; + } + + private static void putOneLineInPage2GenericsData(final ReportDataR20 data, final List> tableContent, + final AbstractGeneric generic) { + PartAeroRevision partBefore = data.getGenericsAndPartNumbersBefore().get(generic); + PartAeroRevision partAfter = data.getGenericsAndPartNumbersAfter().get(generic); + String idPartAvant = partBefore == null ? EMPTY_STRING : partBefore.getItemId(); + String idPartApres = partAfter == null ? EMPTY_STRING : partAfter.getItemId(); + Map line = new EnumMap<>(R20Keys.Page2.Generics.class); + line.put(R20Keys.Page2.Generics.GENERIC_AVEC_RUPTURE, generic.getName()); + line.put(R20Keys.Page2.Generics.ID_PART_AVANT, idPartAvant); + line.put(R20Keys.Page2.Generics.ID_PART_APRES, idPartApres); + tableContent.add(line); + } + + /** + * Sets up the a table containing all the generics which take part in at least one Modification with Rupture (from unit After or LMR), regardless of if they also take part in a modif without rupture. + * + * @param data the executionR20 to findAll the data + * @return the table data as a List of Map + */ + private static List> setupPage2ImpactsData(final ReportDataR20 data) { + List> tableContent = new ArrayList<>(); + for (Entry> genericEntry : data.getTotalGenericsBeforeLMRWithRupture().entrySet()) { + List listOfModifs = new ArrayList<>(); + for (TcChangeRequestRevision changeRequest : genericEntry.getValue()) { + listOfModifs.add(changeRequest.getItemId()); + if (changeRequest.getApprobationSO() != null) { + listOfModifs.add(changeRequest.getApprobationSO()); + } + } + Map line = new EnumMap<>(R20Keys.Page2.Impacts.class); + line.put(R20Keys.Page2.Impacts.NOM_GENERIC, genericEntry.getKey().getName()); + line.put(R20Keys.Page2.Impacts.LIST_MODIFICATIONS_GENERIC, StringHelper.implodeList(COMMA_DELIMITER, listOfModifs)); + tableContent.add(line); + } + for (Entry> genericEntry : data.getTotalGenericsAfterWithRupture().entrySet()) { + List listOfModifs = new ArrayList<>(); + for (TcChangeRequestRevision changeRequest : genericEntry.getValue()) { + listOfModifs.add(changeRequest.getItemId()); + if (changeRequest.getApprobationSO() != null) { + listOfModifs.add(changeRequest.getApprobationSO()); + } + } + Map line = new EnumMap<>(R20Keys.Page2.Impacts.class); + line.put(R20Keys.Page2.Impacts.NOM_GENERIC, genericEntry.getKey().getName()); + line.put(R20Keys.Page2.Impacts.LIST_MODIFICATIONS_GENERIC, StringHelper.implodeList(COMMA_DELIMITER, listOfModifs)); + tableContent.add(line); + } + return tableContent; + } + + /** + * Sets up the a table containing all the generics which take part in at least one Modification without Rupture (from unit After or LMR), regardless of if they also take part in a modif with rupture. + * + * @param data the executionR20 to findAll the data + * @return the table data as a List of Map + */ + private static List> setupPage2NoImpactsData(final ReportDataR20 data) { + List> tableContent = new ArrayList<>(); + for (Entry> genericEntry : data.getTotalGenericsBeforeLMRWithoutRupture().entrySet()) { + List listOfModifs = new ArrayList<>(); + for (TcChangeRequestRevision changeRequest : genericEntry.getValue()) { + listOfModifs.add(changeRequest.getItemId()); + if (changeRequest.getApprobationSO() != null) { + listOfModifs.add(changeRequest.getApprobationSO()); + } + } + Map line = new EnumMap<>(R20Keys.Page2.NoImpacts.class); + line.put(R20Keys.Page2.NoImpacts.NOM_GENERIC, genericEntry.getKey().getName()); + line.put(R20Keys.Page2.NoImpacts.LIST_MODIFICATIONS_GENERIC, StringHelper.implodeList(COMMA_DELIMITER, listOfModifs)); + tableContent.add(line); + } + for (Entry> genericEntry : data.getTotalGenericsAfterWithoutRupture().entrySet()) { + List listOfModifs = new ArrayList<>(); + for (TcChangeRequestRevision changeRequest : genericEntry.getValue()) { + listOfModifs.add(changeRequest.getItemId()); + if (changeRequest.getApprobationSO() != null) { + listOfModifs.add(changeRequest.getApprobationSO()); + } + } + Map line = new EnumMap<>(R20Keys.Page2.NoImpacts.class); + line.put(R20Keys.Page2.NoImpacts.NOM_GENERIC, genericEntry.getKey().getName()); + line.put(R20Keys.Page2.NoImpacts.LIST_MODIFICATIONS_GENERIC, StringHelper.implodeList(COMMA_DELIMITER, listOfModifs)); + tableContent.add(line); + } + return tableContent; + } + + private static List> setPage4Data(final ReportDataR20 data) { + List> tableContent = new ArrayList<>(); + for (AbstractGeneric generic : data.getTotalGenerics()) { + Map lmrMap = new EnumMap<>(R20Keys.Page4.class); + PartAeroRevision partBefore = data.getGenericsAndPartNumbersBefore().get(generic); + PartAeroRevision partAfter = data.getGenericsAndPartNumbersAfter().get(generic); + String idPartAvant = partBefore == null ? EMPTY_STRING : partBefore.getItemId(); + String idPartApres = partAfter == null ? EMPTY_STRING : partAfter.getItemId(); + String impact = evaluateImpact(data, generic); + + // Put the data in the table + lmrMap.put(R20Keys.Page4.NOM_GENERIQUE, generic.getName()); + lmrMap.put(R20Keys.Page4.IMPACT_PN, impact); + lmrMap.put(R20Keys.Page4.ID_PART_AVANT, idPartAvant); + lmrMap.put(R20Keys.Page4.ID_PART_APRES, idPartApres); + tableContent.add(lmrMap); + } + if (tableContent.isEmpty()) { + Map line = new EnumMap<>(R20Keys.Page4.class); + line.put(R20Keys.Page4.NOM_GENERIQUE, NO_GENERIC_FOUND); + line.put(R20Keys.Page4.IMPACT_PN, NOT_APPLICABLE); + line.put(R20Keys.Page4.ID_PART_AVANT, NOT_APPLICABLE); + line.put(R20Keys.Page4.ID_PART_APRES, NOT_APPLICABLE); + tableContent.add(line); + } + return tableContent; + } + + private static String evaluateImpact(final ReportDataR20 data, final AbstractGeneric generic) { + String impact; + if (data.getTotalGenericsAfterWithRupture().containsKey(generic) || data.getTotalGenericsBeforeLMRWithRupture().containsKey(generic)) { + impact = AVEC; + } else if (data.getTotalGenericsAfterWithoutRupture().containsKey(generic) + || data.getTotalGenericsBeforeLMRWithoutRupture().containsKey(generic)) { + impact = SANS; + } else { + impact = EMPTY_STRING; + } + return impact; + } + + @Override + public void constructDataMaps(TcSession session, final PrintParameters printParameters, final ReportDataR20 data) throws KurtException { + long start = System.currentTimeMillis(); + print(data, printParameters); + log.trace(EXECUTION_TIME_XXX_MS_FOR_YYY, System.currentTimeMillis() - start, "data filtering"); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/visitors/R20Keys.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/visitors/R20Keys.java new file mode 100644 index 0000000..124ed99 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r20report/visitors/R20Keys.java @@ -0,0 +1,84 @@ +package com.capgemini.reports.definition.r20report.visitors; + +/** + * Keys for R20 report. + */ +public enum R20Keys { + SUBREPORT_P1, + SUBREPORT_P2, + SNECMA_LOGO, + PRODUIT, + UNIT_AVANT, + UNIT_APRES, + EXCEPTIONNEL_AVANT, + EXCEPTIONNEL_APRES, + DOMAINE_PRODUIT_AVANT, + DOMAINE_PRODUIT_APRES, + LIGNE_PRODUIT_AVANT, + LIGNE_PRODUIT_APRES, + MATRICULE_MOTEUR, + IDENTIFIANT_DOC_GEL_UNIT_APRES, + INDICE_DOCUMENT_GEL_UNIT_APRES, + CLASSE, + MAJEUR_MINEUR, + CONJOINT_UNIQUE, + NOM_CREATEUR_WORKFLOW, + NOM_APPROBATEUR_TACHE, + DATE_CREATION, + DATE_VALIDATION, + IS_CR_LIST_EMPTY; + + /** + * Keys for the Page1 of the R20 report. + */ + public enum Page1 { + CHANGE_REQUEST_APPLI, + CHANGE_REQUEST_ID, + CHANGE_REQUEST_NOM, + CHANGE_REQUEST_NO_APPRO_SO + } + + /** + * Keys for the Page2 of the R20 report. + */ + public enum Page2 { + SUBREPORT_NOIMPACTS, + SUBREPORT_IMPACTS, + SUBREPORT_GENERIC; + + /** + * Keys for the Generics-Part relationship, in the Page2 of the R20 report. + */ + public enum Generics { + GENERIC_AVEC_RUPTURE, + ID_PART_AVANT, + ID_PART_APRES + } + + /** + * Keys for the Generics with Rupture, in the Page2 of the R20 report. + */ + public enum Impacts { + NOM_GENERIC, + LIST_MODIFICATIONS_GENERIC + } + + /** + * Keys for the Generics without rupture, in the Page2 of the R20 report. + */ + public enum NoImpacts { + NOM_GENERIC, + LIST_MODIFICATIONS_GENERIC + } + } + + /** + * Keys for the Page4 of the R20 report. + */ + public enum Page4 { + NOM_GENERIQUE, + IMPACT_PN, + ID_PART_AVANT, + ID_PART_APRES + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/DataReportPreparatorR21.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/DataReportPreparatorR21.java new file mode 100644 index 0000000..2c43f12 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/DataReportPreparatorR21.java @@ -0,0 +1,117 @@ +package com.capgemini.reports.definition.r21report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObjectFactory; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRule; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRuleProperties; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.product.TcProduct; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindow; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindowConfiguration; +import com.capgemini.framework.teamcenter.object.runtime.TcRevisionRulesConfiguration; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderFactory; +import com.capgemini.reports.definition.r21report.ExecutionR21.ReportDataR21; +import com.capgemini.reports.definition.r21report.visitors.R21Visitor; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.filter.AllIsGoodFilter; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.reports.parameters.Generics; +import com.capgemini.reports.teamcenter.resolution.structureservice.MultiStructureServiceCaller; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Form; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * This class will allow to prepare data and findAll back data for making report R21. + */ +public class DataReportPreparatorR21 implements IDataReportPreparator { + private static final long serialVersionUID = -5941160681518152189L; + private static final Logger LOGGER = LoggerFactory.getLogger(DataReportPreparatorR21.class); + private static final AllIsGoodFilter ACCEPT_ALL = new AllIsGoodFilter(); + + @Override + public String print(TcSession session, ExecutionR21 execution, IExecutionStrategy executionStrategy) throws KurtException { + PrintParameters printParameters = prepareData(session, execution); + executionStrategy.print(printParameters, execution); + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + } + + private PrintParameters prepareData(final TcSession session, final ExecutionR21 report) throws KurtException { + LOGGER.debug("PrepareData started on: {}", report.getReportIdentifier().getReportTitle()); + + BOMLineHolder topLineAssembly = prepareAssemblyOrTechnicalBOM(session, report.getDualGeneric().asGenericAssemb(), report); + BOMLineHolder topLineTechnical = prepareAssemblyOrTechnicalBOM(session, report.getDualGeneric().asGeneric(), report); + + ReportDataR21 dataR21 = new ReportDataR21(topLineAssembly, topLineTechnical); + + R21Visitor visitor = new R21Visitor(report.getProductUnit(), report.getEffectivity()); + PrintParameters printParameters = visitor.makeMasterTemplate(report, dataR21); + visitor.constructDataMaps(session, printParameters, dataR21); + + LOGGER.debug("PrepareData ended on: {}", report.getReportIdentifier().getReportTitle()); + + return printParameters; + } + + private BOMLineHolder prepareAssemblyOrTechnicalBOM(final TcSession session, final Generics generics, final ExecutionR21 report) + throws KurtException { + String stringType; + switch (generics.getType()) { + case GENERIC: + stringType = "Technical view"; + break; + case GENERIC_ASSEMB: + stringType = "Assembly view"; + break; + default: + stringType = "Undefined view"; + break; + } + + TcBomObject topLineObject = new TcBomObjectFactory(session, generics.getItem(session)).create(); + TcProduct productObject = new TcProduct(session, report.getProductUnit().getProduct(session)); + int unit = report.getProductUnit().getUnit(); + EffectivityDate effectivityDate = report.getEffectivity(); + + TcRevisionRuleProperties revisionRuleProperties = new TcRevisionRuleProperties(productObject, unit, effectivityDate.isNow() ? null : effectivityDate.getDateTime()); + + TcRevisionRule revisionRule = session.findRevRule(report.getRevisionRule()); + TcRevisionRulesConfiguration revRulesConfiguration = new TcRevisionRulesConfiguration(revisionRule, revisionRuleProperties); + + // Perform the job + LOGGER.info("Data configured for the {}, now starting nomenclature resolution", stringType); + try (TcBomWindow bomWindow = session.createBomWindow(new TcBomWindowConfiguration(topLineObject, revRulesConfiguration))) { + session.setObjectPropPolicy(report.getFullPolicy()); + + BOMLineHolder unbuiltTopLine = new MultiStructureServiceCaller(session).resolve(bomWindow.topLine(), ACCEPT_ALL); + + List itemRevMaster = unbuiltTopLine.getAllItemRevMasters(); + session.loadProperties(itemRevMaster.toArray(new ModelObject[0])); + + BOMLineHolderFactory.buildTopBom(session, unbuiltTopLine, ACCEPT_ALL); + unbuiltTopLine.freeze(); + + return unbuiltTopLine; + } + catch (EmptyNomenclatureException e) { + switch (generics.getType()) { + case GENERIC: + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_PRODUCT_AND_UNIT, e); + case GENERIC_ASSEMB: + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_ASSEMB_PRODUCT_AND_UNIT, e); + default: + throw new KurtException("The TC Nomenclature Resolution returned null", e); + } + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/ExecutionR21.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/ExecutionR21.java new file mode 100644 index 0000000..98613fe --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/ExecutionR21.java @@ -0,0 +1,148 @@ +package com.capgemini.reports.definition.r21report; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.builder.R21Builder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.definition.r21report.ExecutionR21.ReportDataR21; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.reports.parameters.DualGenerics; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.reports.parameters.checker.*; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +public class ExecutionR21 extends AbstractExecutionReport { + private static final long serialVersionUID = -2930624274965581115L; + + private static final PolicyLocation R21_POLICY_XML_LIGHT = PolicyLocation.make("R21_policy_light", "/xml/policies/r21report/R21_policy_light.xml"); + private static final PolicyLocation R21_POLICY_XML_FULL = PolicyLocation.make("R21_policy_full", "/xml/policies/r21report/R21_policy_full.xml"); + private static final String REPORT_REVISION_RULE = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R21", DEFAULT_REVISION_RULE); + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R21); + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R21"); + + private final ProductUnit productUnit; + private final EffectivityDate effectivity; + private final DualGenerics dualGeneric; + + public ExecutionR21(final ProductUnit aProductUnit, final DualGenerics aDualGeneric, final EffectivityDate anEffectivity) { + super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE); + productUnit = aProductUnit; + dualGeneric = aDualGeneric; + effectivity = anEffectivity; + } + + @Override + public List getLaunchData() { + List theCriteria = new ArrayList<>(); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PRODUCT, productUnit.getProductID())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.UNIT, productUnit.getUnitStr())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC, dualGeneric.asGeneric().getID())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC_ASSEMB, dualGeneric.asGenericAssemb().getID())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.EFFECTIVITY_DATE, effectivity.formatAsInputCriteria())); + return theCriteria; + } + + @Override + public List getQuickChecks() { + // Sort the quick checks + List quickChecks = new ArrayList<>(); + quickChecks.add(new GenericExistenceChecker(dualGeneric.asGeneric())); + quickChecks.add(new GenericExistenceChecker(dualGeneric.asGenericAssemb())); + quickChecks.add(new ProductChecker(productUnit.getProductID())); + quickChecks.add(new ProductUnitChecker(productUnit)); + quickChecks.add(new EffectivityChecker(effectivity)); + return quickChecks; + } + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R21_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R21_POLICY_XML_FULL; + } + + @Override + public List getLongChecks() { + // Sort the Long checks + List longChecks = new ArrayList<>(); + longChecks.add(new GenericConditionR21Checker(productUnit, dualGeneric)); + return longChecks; + } + + @Override + public ReportEnum getReportIdentifier() { + return ReportEnum.REPORT_R21; + } + + @Override + public String getSpecifiedFileName() { + String separator = "-"; + return "R21-" + dualGeneric.asGeneric().getID() + separator + dualGeneric.asGenericAssemb().getID() + + separator + productUnit.getProductID() + separator + productUnit.getUnit() + separator + + effectivity.formatAsInputCriteria(); + } + + @Override + public PrintFormat getPrintingFormat() { + return PrintFormat.XLSX; + } + + @Override + public String getTemplateLocation() { + return JasperTemplate.TEMPLATE_R21.getFilepath(); + } + + @Override + public IDataReportPreparator getDataPreparator() { + return new DataReportPreparatorR21(); + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return new ExecutionR21(productUnit, dualGeneric, effectivity); + } + + @Override + public Class getReportBuilderClass() { + return R21Builder.class; + } + + public DualGenerics getDualGeneric() { + return dualGeneric; + } + + public ProductUnit getProductUnit() { + return productUnit; + } + + public EffectivityDate getEffectivity() { + return effectivity; + } + + /** + * POJO container of all data required for this report. + */ + @AllArgsConstructor + @Getter + public static class ReportDataR21 { + private final BOMLineHolder topLineAssembly; + private final BOMLineHolder topLineTechnical; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/R21ReportKeys.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/R21ReportKeys.java new file mode 100644 index 0000000..6f58f0f --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/R21ReportKeys.java @@ -0,0 +1,38 @@ +package com.capgemini.reports.definition.r21report; + +/** + * Enumeration of the keys of a R21 report. + */ +public enum R21ReportKeys { + EFFECTIVITE, + ETUDE_REPERE_FONCTIONNEL_RECEPTEUR, + ETUDE_REVISION_REPERE_FONCTIONNEL_RECEPTEUR, + ETUDE_IDENTIFIANT_RECEPTEUR, + ETUDE_REVISION_RECEPTEUR, + ETUDE_NOM_RECEPTEUR, + ETUDE_REPERE_FONCTIONNEL_COMPOSANT, + ETUDE_REVISION_REPERE_FONCTIONNEL_COMPOSANT, + ETUDE_REF_FABRICANT_REF_SNECMA, + ETUDE_REVISION_REFERENCE, + ETUDE_TYPE_REFERENCE, + ETUDE_NOM_REFERENCE, + ETUDE_NOMBRE_REPERE_FONCTIONNEL, + ETUDE_IS_YELLOW_BACKGROUND, + ETUDE_RF_IS_YELLOW_BACKGROUND, + MONTAGE_REPERE_FONCTIONNEL_RECEPTEUR, + MONTAGE_REVISION_REPERE_FONCTIONNEL_RECEPTEUR, + MONTAGE_IDENTIFIANT_RECEPTEUR, + MONTAGE_REVISION_RECEPTEUR, + MONTAGE_NOM_RECEPTEUR, + MONTAGE_REPERE_FONCTIONNEL_COMPOSANT, + MONTAGE_REVISION_REPERE_FONCTIONNEL_COMPOSANT, + MONTAGE_REF_FABRICANT_REF_SNECMA, + MONTAGE_REVISION_REFERENCE, + MONTAGE_TYPE_REFERENCE, + MONTAGE_NOM_REFERENCE, + MONTAGE_IDENTIFIANT_RECEPTEUR_ORIGINE, + MONTAGE_NOM_RECEPTEUR_ORIGINE, + MONTAGE_NOMBRE_REPERE_FONCTIONNEL, + MONTAGE_IS_YELLOW_BACKGROUND, + MONTAGE_RF_IS_YELLOW_BACKGROUND +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/visitors/R21Visitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/visitors/R21Visitor.java new file mode 100644 index 0000000..4c4b6ce --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/visitors/R21Visitor.java @@ -0,0 +1,577 @@ +package com.capgemini.reports.definition.r21report.visitors; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.IBOMTree; +import com.capgemini.reports.definition.r21report.ExecutionR21; +import com.capgemini.reports.definition.r21report.ExecutionR21.ReportDataR21; +import com.capgemini.reports.definition.r21report.R21ReportKeys; +import com.capgemini.reports.definition.r21report.visitors.bomlineholder.R21BOMLineHolderVisitor; +import com.capgemini.reports.execution.mapconstructor.AbstractStaticTemplateMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.reports.parameters.ProductUnit; +import org.apache.commons.collections.ListUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +import static com.capgemini.reports.definition.r21report.visitors.R21VisitorKeys.*; + + +public class R21Visitor extends AbstractStaticTemplateMapConstructor { + private static final long serialVersionUID = 7945453397269802050L; + private static final Logger LOGGER = LoggerFactory.getLogger(R21Visitor.class); + + private final List> listOfAssemblyLines; + private final List> listOfTechnicalLines; + + private final ProductUnit productUnit; + private final EffectivityDate effectivity; + + /** + * Constructor. + * + * @param productUnit ProductUnit + * @param effectivity EffectivityDate + */ + public R21Visitor(final ProductUnit productUnit, final EffectivityDate effectivity) { + super(); + this.productUnit = productUnit; + this.effectivity = effectivity; + this.listOfAssemblyLines = new ArrayList<>(); + this.listOfTechnicalLines = new ArrayList<>(); + } + + + @Override + public void constructDataMaps(TcSession session, final PrintParameters printParameters, final ReportDataR21 data) { + long start = System.currentTimeMillis(); + if (data.getTopLineAssembly() == null || data.getTopLineTechnical() == null) { + throw new NoSuchElementException("No Product structure found"); + } + + // Parse all the snecma objects... + List> theResultReport = visitReport(data.getTopLineAssembly(), data.getTopLineTechnical()); + printParameters.addReportData(theResultReport); + LOGGER.info(EXECUTION_TIME_XXX_MS_FOR_YYY, System.currentTimeMillis() - start, "Data Map Construction"); + } + + /** + * Visit a R21 report. + * + * @param holderAssembly BOMLineHolder + * @param holderTechnical BOMLineHolder + * @return theR21report List> the known format of the printer + */ + private List> visitReport(final BOMLineHolder holderAssembly, final BOMLineHolder holderTechnical) { + parseExpansionBomAndRemoveRFandPartAssembs(holderAssembly); + + List> assemblyResult = visitReportAssembly(holderAssembly); + List> technicalResult = visitReportTechnical(holderTechnical); + LOGGER.info("There are {} initial element(s) in the Assembly view", assemblyResult.size()); + LOGGER.info("There are {} initial element(s) in the Technical view", technicalResult.size()); + + completeReportData(assemblyResult, technicalResult); + LOGGER.info("There are {} element(s) remaining in the Assembly view", listOfAssemblyLines.size()); + LOGGER.info("There are {} element(s) remaining in the Technical view", listOfTechnicalLines.size()); + + List> theR21report = createReport(); + + // Add the effectivity column + addEffectivityToReport(theR21report); + + // Translate the report in a known format for the printer and return it + return translate(theR21report); + } + + /** + * Create a R21 report. + * + * @return theR21report List> + */ + private List> createReport() { + List> theR21report; + if ((listOfAssemblyLines.isEmpty()) || (listOfTechnicalLines.isEmpty())) { + // Create the empty line if the Assembly or Technical are empty + theR21report = createEmptyLine(); + } + else { + // Retrieve the R21 report properties + theR21report = getListOfReportLines(listOfAssemblyLines, listOfTechnicalLines); + } + return theR21report; + } + + /** + * Create an empty line. + * + * @return List> a list with the only empty map + */ + private List> createEmptyLine() { + List> theR21report = new ArrayList<>(); + Map firstLine = new EnumMap<>(R21ReportKeys.class); + + // Technical view + firstLine.put(R21ReportKeys.ETUDE_REPERE_FONCTIONNEL_RECEPTEUR, ""); + firstLine.put(R21ReportKeys.ETUDE_REVISION_REPERE_FONCTIONNEL_RECEPTEUR, ""); + firstLine.put(R21ReportKeys.ETUDE_IDENTIFIANT_RECEPTEUR, ""); + firstLine.put(R21ReportKeys.ETUDE_REVISION_RECEPTEUR, ""); + firstLine.put(R21ReportKeys.ETUDE_NOM_RECEPTEUR, ""); + firstLine.put(R21ReportKeys.ETUDE_REPERE_FONCTIONNEL_COMPOSANT, ""); + firstLine.put(R21ReportKeys.ETUDE_REVISION_REPERE_FONCTIONNEL_COMPOSANT, ""); + firstLine.put(R21ReportKeys.ETUDE_REF_FABRICANT_REF_SNECMA, ""); + firstLine.put(R21ReportKeys.ETUDE_REVISION_REFERENCE, ""); + firstLine.put(R21ReportKeys.ETUDE_TYPE_REFERENCE, ""); + firstLine.put(R21ReportKeys.ETUDE_NOM_REFERENCE, ""); + firstLine.put(R21ReportKeys.ETUDE_NOMBRE_REPERE_FONCTIONNEL, ""); + + // Assembly view + firstLine.put(R21ReportKeys.MONTAGE_REPERE_FONCTIONNEL_RECEPTEUR, ""); + firstLine.put(R21ReportKeys.MONTAGE_REVISION_REPERE_FONCTIONNEL_RECEPTEUR, ""); + firstLine.put(R21ReportKeys.MONTAGE_IDENTIFIANT_RECEPTEUR, ""); + firstLine.put(R21ReportKeys.MONTAGE_REVISION_RECEPTEUR, ""); + firstLine.put(R21ReportKeys.MONTAGE_NOM_RECEPTEUR, ""); + firstLine.put(R21ReportKeys.MONTAGE_REPERE_FONCTIONNEL_COMPOSANT, ""); + firstLine.put(R21ReportKeys.MONTAGE_REVISION_REPERE_FONCTIONNEL_COMPOSANT, ""); + firstLine.put(R21ReportKeys.MONTAGE_REF_FABRICANT_REF_SNECMA, ""); + firstLine.put(R21ReportKeys.MONTAGE_REVISION_REFERENCE, ""); + firstLine.put(R21ReportKeys.MONTAGE_TYPE_REFERENCE, ""); + firstLine.put(R21ReportKeys.MONTAGE_NOM_REFERENCE, ""); + firstLine.put(R21ReportKeys.MONTAGE_IDENTIFIANT_RECEPTEUR_ORIGINE, ""); + firstLine.put(R21ReportKeys.MONTAGE_NOM_RECEPTEUR_ORIGINE, ""); + firstLine.put(R21ReportKeys.MONTAGE_NOMBRE_REPERE_FONCTIONNEL, ""); + + theR21report.add(firstLine); + return theR21report; + } + + /** + * Create the R21 report by mixing the Assembly list and the Technical list. + */ + private List> getListOfReportLines(final List> assemblyList, + final List> technicalList) { + List> theR21report = new ArrayList<>(); + + // Create the Technical view in the R21 report + for (Map curentMapInTechnicalList : technicalList) { + theR21report.add(makeTechnicalLine(curentMapInTechnicalList)); + } + + // Create the Assembly view in the R21 report + for (Map curentMapInAssemblyList : assemblyList) { + theR21report.add(makeAssemblyLine(curentMapInAssemblyList)); + } + return theR21report; + } + + private Map makeAssemblyLine(final Map curentMapInAssemblyList) { + Map theLine = new EnumMap<>(R21ReportKeys.class); + + theLine.put(R21ReportKeys.MONTAGE_REPERE_FONCTIONNEL_RECEPTEUR, curentMapInAssemblyList.get(REPERE_FONCTIONNEL_RECEPTEUR)); + theLine.put(R21ReportKeys.MONTAGE_REVISION_REPERE_FONCTIONNEL_RECEPTEUR, curentMapInAssemblyList.get(REVISION_REPERE_FONCTIONNEL_RECEPTEUR)); + theLine.put(R21ReportKeys.MONTAGE_IDENTIFIANT_RECEPTEUR, curentMapInAssemblyList.get(IDENTIFIANT_RECEPTEUR)); + theLine.put(R21ReportKeys.MONTAGE_REVISION_RECEPTEUR, curentMapInAssemblyList.get(REVISION_RECEPTEUR)); + theLine.put(R21ReportKeys.MONTAGE_NOM_RECEPTEUR, curentMapInAssemblyList.get(NOM_RECEPTEUR)); + theLine.put(R21ReportKeys.MONTAGE_REPERE_FONCTIONNEL_COMPOSANT, curentMapInAssemblyList.get(REPERE_FONCTIONNEL_COMPOSANT)); + theLine.put(R21ReportKeys.MONTAGE_REVISION_REPERE_FONCTIONNEL_COMPOSANT, curentMapInAssemblyList.get(REVISION_REPERE_FONCTIONNEL_COMPOSANT)); + theLine.put(R21ReportKeys.MONTAGE_REF_FABRICANT_REF_SNECMA, curentMapInAssemblyList.get(REF_FABRICANT_REF_SNECMA)); + theLine.put(R21ReportKeys.MONTAGE_REVISION_REFERENCE, curentMapInAssemblyList.get(REVISION_REFERENCE)); + theLine.put(R21ReportKeys.MONTAGE_TYPE_REFERENCE, curentMapInAssemblyList.get(TYPE_REFERENCE)); + theLine.put(R21ReportKeys.MONTAGE_NOM_REFERENCE, curentMapInAssemblyList.get(NOM_REFERENCE)); + theLine.put(R21ReportKeys.MONTAGE_IDENTIFIANT_RECEPTEUR_ORIGINE, curentMapInAssemblyList.get(IDENTIFIANT_RECEPTEUR_ORIGINE)); + theLine.put(R21ReportKeys.MONTAGE_NOM_RECEPTEUR_ORIGINE, curentMapInAssemblyList.get(NOM_RECEPTEUR_ORIGINE)); + theLine.put(R21ReportKeys.MONTAGE_NOMBRE_REPERE_FONCTIONNEL, curentMapInAssemblyList.get(NOMBRE_REPERE_FONCTIONNEL)); + theLine.put(R21ReportKeys.MONTAGE_IS_YELLOW_BACKGROUND, curentMapInAssemblyList.get(IS_YELLOW_BACKGROUND)); + theLine.put(R21ReportKeys.MONTAGE_RF_IS_YELLOW_BACKGROUND, curentMapInAssemblyList.get(RF_IS_YELLOW_BACKGROUND)); + + return theLine; + } + + private Map makeTechnicalLine(final Map curentMapInTechnicalList) { + Map theLine = new EnumMap<>(R21ReportKeys.class); + + theLine.put(R21ReportKeys.ETUDE_REPERE_FONCTIONNEL_RECEPTEUR, curentMapInTechnicalList.get(REPERE_FONCTIONNEL_RECEPTEUR)); + theLine.put(R21ReportKeys.ETUDE_REVISION_REPERE_FONCTIONNEL_RECEPTEUR, curentMapInTechnicalList.get(REVISION_REPERE_FONCTIONNEL_RECEPTEUR)); + theLine.put(R21ReportKeys.ETUDE_IDENTIFIANT_RECEPTEUR, curentMapInTechnicalList.get(IDENTIFIANT_RECEPTEUR)); + theLine.put(R21ReportKeys.ETUDE_REVISION_RECEPTEUR, curentMapInTechnicalList.get(REVISION_RECEPTEUR)); + theLine.put(R21ReportKeys.ETUDE_NOM_RECEPTEUR, curentMapInTechnicalList.get(NOM_RECEPTEUR)); + theLine.put(R21ReportKeys.ETUDE_REPERE_FONCTIONNEL_COMPOSANT, curentMapInTechnicalList.get(REPERE_FONCTIONNEL_COMPOSANT)); + theLine.put(R21ReportKeys.ETUDE_REVISION_REPERE_FONCTIONNEL_COMPOSANT, curentMapInTechnicalList.get(REVISION_REPERE_FONCTIONNEL_COMPOSANT)); + theLine.put(R21ReportKeys.ETUDE_REF_FABRICANT_REF_SNECMA, curentMapInTechnicalList.get(REF_FABRICANT_REF_SNECMA)); + theLine.put(R21ReportKeys.ETUDE_REVISION_REFERENCE, curentMapInTechnicalList.get(REVISION_REFERENCE)); + theLine.put(R21ReportKeys.ETUDE_TYPE_REFERENCE, curentMapInTechnicalList.get(TYPE_REFERENCE)); + theLine.put(R21ReportKeys.ETUDE_NOM_REFERENCE, curentMapInTechnicalList.get(NOM_REFERENCE)); + theLine.put(R21ReportKeys.ETUDE_NOMBRE_REPERE_FONCTIONNEL, curentMapInTechnicalList.get(NOMBRE_REPERE_FONCTIONNEL)); + theLine.put(R21ReportKeys.ETUDE_IS_YELLOW_BACKGROUND, curentMapInTechnicalList.get(IS_YELLOW_BACKGROUND)); + theLine.put(R21ReportKeys.ETUDE_RF_IS_YELLOW_BACKGROUND, curentMapInTechnicalList.get(RF_IS_YELLOW_BACKGROUND)); + + return theLine; + } + + /** + * Parse the expansion Bom and remove all the RF Part Assemb and the Part Assemb. + * + * @param aBom BOMLineHolder + */ + private void parseExpansionBomAndRemoveRFandPartAssembs(final BOMLineHolder aBom) { + // Parse the expansion Bom + List children = aBom.getBomChilds(); + if (!children.isEmpty()) { + for (BOMLineHolder actualChild : aBom.getBomChilds()) { + parseExpansionBomAndRemoveRFandPartAssembs(actualChild); + } + } + + // Treatment of the object by raising the expansion bom + // Avoid the ConcurrentModificationExecption by this way + if ((aBom.getSnecmaObject() != null) && (aBom.getParentBomLine() != null)) { + String parentType = aBom.getParentBomLine().getSnecmaObject().getType(); + + // Modify the value parent of the Bom + if (SnecmaObjectTypes.RF_PART_ASSEMB_REVISION.equals(parentType) || SnecmaObjectTypes.PART_ASSEMB_REVISION.equals(parentType)) { + BOMLineHolder newParentFound = getParentNoAssembs(aBom); + aBom.setParent(newParentFound); + } + } + + // Modify the value bomChildMap of the Bom + if (!children.isEmpty()) { + findAssembChildAndRemoveIt(aBom); + } + } + + /** + * Find RF Part Assemb or Part Assemb children.
+ * Remove this Assemb children and add their own children to the Bom's children. + * + * @param aBom BOMLineHolder + */ + private void findAssembChildAndRemoveIt(final BOMLineHolder aBom) { + List children = aBom.getBomChilds(); + List removedChildren = new ArrayList<>(); + List addedChildren = new ArrayList<>(); + + // Check if there are a RF Part Assemb or Part Assemb children + if (!children.isEmpty()) { + for (BOMLineHolder child : children) { + if (child.getSnecmaObject() != null) { + String entryChildType = child.getSnecmaObject().getType(); + if (SnecmaObjectTypes.RF_PART_ASSEMB_REVISION.equals(entryChildType) || SnecmaObjectTypes.PART_ASSEMB_REVISION.equals(entryChildType)) { + // List the RF Part Assemb or Part Assemb children + removedChildren.add(child); + + // Retrieve the bomChildMap of the RF Part Assemb or Part Assemb children + // No need to remove the Admin under a RF Part Assemb + // Because, for a R21 report, the Admin are treated only for a RF Part Assemb + addedChildren.addAll(child.getBomChilds()); + } + } + } + } + + // Removed the RF Part Assemb or Part Assemb children + if (!removedChildren.isEmpty()) { + for (BOMLineHolder toRemove : removedChildren) { + children.remove(toRemove); + } + } + + // Add the bomChildMap of the removed RF Part Assemb or Part Assemb children + // to the Bom's bomChildMap + if (!addedChildren.isEmpty()) { + children.addAll(addedChildren); + } + } + + /** + * Get a parent which is not a RF Part Assemb or a Part Assemb. + * + * @param aBom BOMLineHolder + */ + private BOMLineHolder getParentNoAssembs(final IBOMTree aBom) { + String parentBomType = aBom.getParentBomLine().getSnecmaObject().getType(); + if (!SnecmaObjectTypes.RF_PART_ASSEMB_REVISION.equals(parentBomType) + && !SnecmaObjectTypes.PART_ASSEMB_REVISION.equals(parentBomType)) { + return new BOMLineHolder(aBom); + } + else { + return getParentNoAssembs(aBom.getParentBomLine()); + } + } + + /** + * Find an Remove duplicate keys between two maps. + * + * @param assemblyList a List of key-values that exist in assembly view + * @param technicalList a List of key-values that exist in technical view + */ + private void completeReportData(final List> assemblyList, final List> technicalList) { + List comparativeAssemblyList = transformListForComparaisonInRemoveKeys(assemblyList); + List comparativeTechnicalList = transformListForComparaisonInRemoveKeys(technicalList); + + List consolidatedAssemblyList = countDuplicatedLines(comparativeAssemblyList); + List consolidateTechnicalList = countDuplicatedLines(comparativeTechnicalList); + + List theRemovedList = ListUtils.intersection(consolidatedAssemblyList, consolidateTechnicalList); + List uniqueAssembLines = ListUtils.removeAll(consolidatedAssemblyList, theRemovedList); + List uniqueTechnicalLines = ListUtils.removeAll(consolidateTechnicalList, theRemovedList); + + addReceptorOriginsData(uniqueAssembLines, uniqueTechnicalLines); + addBackgroundColor(uniqueAssembLines, uniqueTechnicalLines); + + listOfAssemblyLines.addAll(uniqueAssembLines); + listOfTechnicalLines.addAll(uniqueTechnicalLines); + } + + private void addBackgroundColor(List uniqueAssembLines, List uniqueTechnicalLines) { + addBackgroundColorAttributes(uniqueAssembLines, uniqueTechnicalLines); + addBackgroundColorAttributes(uniqueTechnicalLines, uniqueAssembLines); + } + + private void addBackgroundColorAttributes(List toCompare, List from) { + for (SuperMap fromSuperMap : from) { + SuperMap toCompareSuperMap = getSuperMapEquals(toCompare, fromSuperMap); + if (fromSuperMap.containsKey(NOMBRE_REPERE_FONCTIONNEL) + && Integer.parseInt(fromSuperMap.get(NOMBRE_REPERE_FONCTIONNEL)) > 1 + && toCompareSuperMap.isEmpty()) { + fromSuperMap.put(R21VisitorKeys.IS_YELLOW_BACKGROUND, "true"); + fromSuperMap.put(R21VisitorKeys.RF_IS_YELLOW_BACKGROUND, "true"); + } + else if (toCompareSuperMap.containsKey(NOMBRE_REPERE_FONCTIONNEL) + && fromSuperMap.containsKey(NOMBRE_REPERE_FONCTIONNEL) + && Integer.parseInt(toCompareSuperMap.get(NOMBRE_REPERE_FONCTIONNEL)) != Integer.parseInt(fromSuperMap.get(NOMBRE_REPERE_FONCTIONNEL))) { + fromSuperMap.put(R21VisitorKeys.IS_YELLOW_BACKGROUND, "true"); + } + } + } + + private void addReceptorOriginsData(List uniqueAssembLines, List uniqueTechnicalLines) { + for (SuperMap uniqueAssembLine : uniqueAssembLines) { + SuperMap superMap = getSuperMapOnlyDiffByRfReceptor(uniqueTechnicalLines, uniqueAssembLine); + uniqueAssembLine.put(IDENTIFIANT_RECEPTEUR_ORIGINE, superMap.containsKey(IDENTIFIANT_RECEPTEUR) ? superMap.get(IDENTIFIANT_RECEPTEUR) : ""); + uniqueAssembLine.put(NOM_RECEPTEUR_ORIGINE, superMap.containsKey(NOM_RECEPTEUR) ? superMap.get(NOM_RECEPTEUR) : ""); + } + } + + private SuperMap getSuperMapOnlyDiffByRfReceptor(List superMaps, SuperMap uniqueLine) { + for (SuperMap superMap : superMaps) { + if (uniqueLine.isOnlyDiffByRfReceptor(superMap) + && !uniqueLine.get(IDENTIFIANT_RECEPTEUR).equals(superMap.get(IDENTIFIANT_RECEPTEUR)) + && !uniqueLine.get(NOM_RECEPTEUR).equals(superMap.get(NOM_RECEPTEUR)) + ) { + return superMap; + } + } + return new SuperMap(); + } + + private SuperMap getSuperMapEquals(List superMaps, SuperMap uniqueLine) { + for (SuperMap superMap : superMaps) { + if (uniqueLine.isEquals(superMap)) { + return superMap; + } + } + return new SuperMap(); + } + + private List countDuplicatedLines(List comparativeList) { + List consolidatedList = new ArrayList<>(); + for (SuperMap map : comparativeList) { + if (consolidatedList.contains(map)) { + SuperMap superMap = consolidatedList.get(consolidatedList.indexOf(map)); + superMap.put(NOMBRE_REPERE_FONCTIONNEL, Integer.toString(Integer.parseInt(superMap.get(NOMBRE_REPERE_FONCTIONNEL)) + 1)); + } + else { + map.put(NOMBRE_REPERE_FONCTIONNEL, Integer.toString(1)); + consolidatedList.add(map); + } + } + return consolidatedList; + } + + private List transformListForComparaisonInRemoveKeys(final List> aListToTransform) { + List aListToReturn = new ArrayList<>(); + + for (Map currentMap : aListToTransform) { + SuperMap simpleMap = new SuperMap(); + simpleMap.putAll(currentMap); + aListToReturn.add(simpleMap); + } + return aListToReturn; + } + + /** + * Visit an Assembly BOM. + * + * @param holderAssembly BOMLineHolder + */ + private List> visitReportAssembly(final BOMLineHolder holderAssembly) { + return new R21BOMLineHolderVisitor().visitTopReceptorBom(holderAssembly); + } + + /** + * Visit a Technical BOM. + * + * @param holderTechnical BOMLineHolder + */ + private List> visitReportTechnical(final BOMLineHolder holderTechnical) { + return new R21BOMLineHolderVisitor().visitTopReceptorBom(holderTechnical); + } + + /** + * Add the value of the column TcEffectivity to the Report. + */ + private void addEffectivityToReport(final List> theResultReport) { + // Create the value of the effectivity for the R21 report + String theEffectivity = productUnit.getProductID() + " / " + productUnit.getUnit() + " / " + formatEffectivityDate(effectivity); + + // Put the effectivity in all the lines of the report + for (Map actualMap : theResultReport) { + actualMap.put(R21ReportKeys.EFFECTIVITE, theEffectivity); + } + } + + private static String formatEffectivityDate(final EffectivityDate eff) { + Calendar date; + if (eff.isNow()) { + date = Calendar.getInstance(); + } + else { + date = eff.getDateTime(); + } + DateFormat dateFormat = new SimpleDateFormat("dd-MMMMM-yy", Locale.FRENCH); + return dateFormat.format(date.getTime()); + } + + /** + * Translate the specific result of the visitor into something the printer can understand. + */ + private List> translate(final List> theActualReportList) { + // Construct the map list expected by the printer + List> printerMaps = new ArrayList<>(); + for (Map visitorMap : theActualReportList) { + Map printerMap = new HashMap<>(); + for (R21ReportKeys key : R21ReportKeys.values()) { + printerMap.put(key.toString(), visitorMap.get(key)); + } + printerMaps.add(printerMap); + } + + return printerMaps; + } + + @Override + public boolean equals(Object o) { + if (o == this) return true; + if (!(o instanceof R21Visitor)) return false; + R21Visitor other = (R21Visitor) o; + if (!other.canEqual(this)) return false; + if (!super.equals(o)) return false; + if (this.listOfAssemblyLines == null ? other.listOfAssemblyLines != null : !this.listOfAssemblyLines.equals(other.listOfAssemblyLines)) + return false; + if (this.listOfTechnicalLines == null ? other.listOfTechnicalLines != null : !this.listOfTechnicalLines.equals(other.listOfTechnicalLines)) + return false; + if (this.productUnit == null ? other.productUnit != null : !this.productUnit.equals(other.productUnit)) + return false; + return this.effectivity == null ? other.effectivity == null : this.effectivity.equals(other.effectivity); + } + + @Override + public int hashCode() { + final int PRIME = 59; + int result = 1; + result = result * PRIME + super.hashCode(); + result = result * PRIME + (this.listOfAssemblyLines == null ? 43 : this.listOfAssemblyLines.hashCode()); + result = result * PRIME + (this.listOfTechnicalLines == null ? 43 : this.listOfTechnicalLines.hashCode()); + result = result * PRIME + (this.productUnit == null ? 43 : this.productUnit.hashCode()); + result = result * PRIME + (this.effectivity == null ? 43 : this.effectivity.hashCode()); + return result; + } + + @Override + protected boolean canEqual(Object other) { + return other instanceof R21Visitor; + } + + /** + * This class is a HashMap with a special {@code equals} method. + */ + class SuperMap extends HashMap { + + private static final long serialVersionUID = 7843304491480106535L; + + @Override + public boolean equals(final Object other) { + if (other instanceof SuperMap) { + Map otherMap = (SuperMap) other; + for (Map.Entry entry : this.entrySet()) { + R21VisitorKeys key = entry.getKey(); + if (key != IDENTIFIANT_RECEPTEUR + && key != REVISION_RECEPTEUR + && key != NOM_RECEPTEUR + && key != TYPE_REFERENCE + && key != NOM_REFERENCE + && key != IS_YELLOW_BACKGROUND + && key != RF_IS_YELLOW_BACKGROUND + && key != NOM_RECEPTEUR_ORIGINE + && key != IDENTIFIANT_RECEPTEUR_ORIGINE + && !entry.getValue().equals(otherMap.get(key))) { + return false; + } + } + return true; + } + else { + return false; + } + } + + boolean isEquals(SuperMap otherMap) { + for (Map.Entry entry : this.entrySet()) { + R21VisitorKeys key = entry.getKey(); + if (key != IDENTIFIANT_RECEPTEUR + && key != REVISION_RECEPTEUR + && key != NOM_RECEPTEUR + && key != TYPE_REFERENCE + && key != NOM_REFERENCE + && key != NOMBRE_REPERE_FONCTIONNEL + && key != IS_YELLOW_BACKGROUND + && key != RF_IS_YELLOW_BACKGROUND + && key != NOM_RECEPTEUR_ORIGINE + && key != IDENTIFIANT_RECEPTEUR_ORIGINE + && !entry.getValue().equals(otherMap.get(key))) { + return false; + } + } + return true; + } + + boolean isOnlyDiffByRfReceptor(SuperMap otherMap) { + for (Map.Entry entry : this.entrySet()) { + R21VisitorKeys key = entry.getKey(); + if ( + key != REPERE_FONCTIONNEL_RECEPTEUR + && key != REVISION_REPERE_FONCTIONNEL_RECEPTEUR + && key != IDENTIFIANT_RECEPTEUR + && key != REVISION_RECEPTEUR + && key != NOM_RECEPTEUR + && key != TYPE_REFERENCE + && key != NOM_REFERENCE + && key != NOMBRE_REPERE_FONCTIONNEL + && key != IS_YELLOW_BACKGROUND + && key != RF_IS_YELLOW_BACKGROUND + && key != NOM_RECEPTEUR_ORIGINE + && key != IDENTIFIANT_RECEPTEUR_ORIGINE + && !entry.getValue().equals(otherMap.get(key))) { + return false; + } + } + return true; + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/visitors/R21VisitorKeys.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/visitors/R21VisitorKeys.java new file mode 100644 index 0000000..74acbbb --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/visitors/R21VisitorKeys.java @@ -0,0 +1,20 @@ +package com.capgemini.reports.definition.r21report.visitors; + +public enum R21VisitorKeys { + REPERE_FONCTIONNEL_RECEPTEUR, + REVISION_REPERE_FONCTIONNEL_RECEPTEUR, + IDENTIFIANT_RECEPTEUR, + REVISION_RECEPTEUR, + NOM_RECEPTEUR, + REPERE_FONCTIONNEL_COMPOSANT, + REVISION_REPERE_FONCTIONNEL_COMPOSANT, + REF_FABRICANT_REF_SNECMA, + REVISION_REFERENCE, + TYPE_REFERENCE, + NOM_REFERENCE, + NOMBRE_REPERE_FONCTIONNEL, + IDENTIFIANT_RECEPTEUR_ORIGINE, + NOM_RECEPTEUR_ORIGINE, + IS_YELLOW_BACKGROUND, + RF_IS_YELLOW_BACKGROUND +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/visitors/bomlineholder/R21AltOrDetBehaviour.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/visitors/bomlineholder/R21AltOrDetBehaviour.java new file mode 100644 index 0000000..3c267a8 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/visitors/bomlineholder/R21AltOrDetBehaviour.java @@ -0,0 +1,36 @@ +package com.capgemini.reports.definition.r21report.visitors.bomlineholder; + +import com.capgemini.reports.bomlineholder.processor.AltOrDetBehaviour; +import com.capgemini.reports.definition.r21report.visitors.R21VisitorKeys; + +import java.util.Map; + +/** + * This class defines the behaviour of the R21 reprot regarding Alts or Dets: it does nothing at all. + */ +public class R21AltOrDetBehaviour implements AltOrDetBehaviour { + + private static final long serialVersionUID = 5831924152460249403L; + + @Override + public boolean shouldVisitPartsInPseudoFolder() { + // No use in the R21 report + return false; + } + + @Override + public boolean shouldVisitPartsBelowAlt() { + // No use in the R21 report + return false; + } + + @Override + public void treatPartsInPseudoFolder(final Map map) { + // No use in the R21 report + } + + @Override + public void treatAlternateOrDETAsReceptor(final Map receptorMap) { + // No use in the R21 report + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/visitors/bomlineholder/R21BOMLineHolderVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/visitors/bomlineholder/R21BOMLineHolderVisitor.java new file mode 100644 index 0000000..d33eaa2 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/visitors/bomlineholder/R21BOMLineHolderVisitor.java @@ -0,0 +1,71 @@ +package com.capgemini.reports.definition.r21report.visitors.bomlineholder; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.visitor.AbstractBOMLineHolderVisitor; +import com.capgemini.reports.definition.r21report.visitors.R21VisitorKeys; +import com.capgemini.reports.definition.r21report.visitors.snecmaobject.R21ComponentVisitor; +import com.capgemini.reports.definition.r21report.visitors.snecmaobject.R21ReceptorVisitor; +import com.capgemini.reports.releasestatus.EffectivityBehaviourHelper; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.Map; + +/** + * Visitor of an expansion of BOMLineHolder for the R21 report. + */ +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class R21BOMLineHolderVisitor extends AbstractBOMLineHolderVisitor { + private static final long serialVersionUID = -2637811314864998456L; + + public R21BOMLineHolderVisitor() { + super(new R21ReceptorVisitor(), new R21ComponentVisitor(), EffectivityBehaviourHelper.visitOnlyUnitManagedParts(), + new R21AltOrDetBehaviour(), true, false, false); + } + + @Override + protected Map visitThisReceptor(final BOMLineHolder aBomLine) { + return aBomLine.getSnecmaObject().accept(receptorVisitor); + } + + @Override + protected Map visitThisComponent(final BOMLineHolder aBomLine) { + return aBomLine.getSnecmaObject().accept(componentVisitor); + } + + @Override + protected void mergeReceptorAndRepereReceptor(final Map aReceptor, final Map aRepereReceptor) { + aReceptor.putAll(aRepereReceptor); + } + + @Override + protected void mergeComponentAndRepereComponent(final Map aComponent, final Map aRepereComponent) { + aComponent.putAll(aRepereComponent); + } + + @Override + protected void mergeRepereReceptorandAdmin(final Map aRepereReceptor, final Map anAdmin) { + // No used in the R21 report + } + + @Override + protected void mergeRepereComponentandAdmin(final Map aRepereComponent, final Map anAdmin) { + // No used in the R21 report + } + + @Override + protected void addToReport(final Map aReceptor, final Map aComponent) { + // Put the Receptor and Repere Receptor in the Component and modify the Component + // Do not modify the receptor + aComponent.putAll(aReceptor); + + // Add to the R21 report + theReportTable.add(aComponent); + } + + @Override + protected void visitSpecificFirstLine(final BOMLineHolder bomHolder) { + // No use for R21 report + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/visitors/snecmaobject/R21ComponentVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/visitors/snecmaobject/R21ComponentVisitor.java new file mode 100644 index 0000000..165d0a1 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/visitors/snecmaobject/R21ComponentVisitor.java @@ -0,0 +1,157 @@ +package com.capgemini.reports.definition.r21report.visitors.snecmaobject; + +import com.capgemini.reports.definition.r21report.visitors.R21VisitorKeys; +import com.capgemini.reports.snecmaobjects.AbstractSnecmaObject; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAGRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericAssembRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.mockup.MockupRevision; +import com.capgemini.reports.snecmaobjects.part.*; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartAssembRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartRevision; +import com.capgemini.reports.snecmaobjects.supermodel.SuperModelRevision; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; + +import java.util.EnumMap; +import java.util.Map; + +/** + * Visit a Component for the R21 report. + */ +public class R21ComponentVisitor implements IComponentVisitor> { + private static final long serialVersionUID = -4065760039190332050L; + + private static String formatType(final String type) { + return type.substring(0, type.length() - " Revision".length()); + } + + @Override + public Map visitComponent(final ProductRevision aProductRev) { + return getComponentProperties(aProductRev); + } + + @Override + public Map visitComponent(final GenericRevision aGenericRev) { + return getComponentProperties(aGenericRev); + } + + @Override + public Map visitComponent(SuperModelRevision aSuperModelRev) { + return null; + } + + @Override + public Map visitComponent(final GenericAssembRevision aGenericAssembRev) { + return getComponentProperties(aGenericAssembRev); + } + + @Override + public Map visitComponent(final AlternateRevision aAlternateRev) { + return getComponentProperties(aAlternateRev); + } + + @Override + public Map visitComponent(final DETRevision aDetRev) { + return getComponentProperties(aDetRev); + } + + @Override + public Map visitComponent(final PartAeroRevision aPartAeroRev) { + return getComponentProperties(aPartAeroRev); + } + + @Override + public Map visitComponent(final PartNoAeroRevision aPartNoAeroRev) { + return getComponentProperties(aPartNoAeroRev); + } + + @Override + public Map visitComponent(final PartAssembRevision aPartAssembRev) { + return getComponentProperties(aPartAssembRev); + } + + @Override + public Map visitComponent(final PartMatRevision aPartMatRev) { + return getComponentProperties(aPartMatRev); + } + + @Override + public Map visitComponent(final StandardRevision aStandardRev) { + return getComponentProperties(aStandardRev); + } + + @Override + public Map visitComponent(final RFGenericRevision aRfGenericRev) { + return getComponentRepereProperties(aRfGenericRev); + } + + @Override + public Map visitComponent(final RFPartAssembRevision aRfPartAssembRev) { + return getComponentRepereProperties(aRfPartAssembRev); + } + + @Override + public Map visitComponent(final RFPartRevision aRfPartRev) { + return getComponentRepereProperties(aRfPartRev); + } + + @Override + public Map visitComponent(final RFAdminRevision aRfAdminRev) { + return new EnumMap<>(R21VisitorKeys.class); + } + + @Override + public Map visitComponent(final RFAdminARevision aRfAdminARev) { + return new EnumMap<>(R21VisitorKeys.class); + } + + @Override + public Map visitComponent(final RFAdminAPRevision aRfAdminAPRev) { + return new EnumMap<>(R21VisitorKeys.class); + } + + @Override + public Map visitComponent(final RFAdminAGRevision aRfAdminAGRev) { + return new EnumMap<>(R21VisitorKeys.class); + } + + /** + * Recover the Component properties to make a R21 report. + */ + private Map getComponentProperties(final AbstractSnecmaObject aPartOrGeneric) { + Map theMap = new EnumMap<>(R21VisitorKeys.class); + theMap.put(R21VisitorKeys.REF_FABRICANT_REF_SNECMA, aPartOrGeneric.getItemId()); + theMap.put(R21VisitorKeys.REVISION_REFERENCE, aPartOrGeneric.getRevisionId()); + theMap.put(R21VisitorKeys.TYPE_REFERENCE, formatType(aPartOrGeneric.getType())); + theMap.put(R21VisitorKeys.NOM_REFERENCE, aPartOrGeneric.getName()); + return theMap; + } + + /** + * Recover the Component Repere properties to make a R21 report. + */ + private Map getComponentRepereProperties(final AbstractSnecmaObject aRf) { + Map theMap = new EnumMap<>(R21VisitorKeys.class); + theMap.put(R21VisitorKeys.REPERE_FONCTIONNEL_COMPOSANT, aRf.getName()); + theMap.put(R21VisitorKeys.REVISION_REPERE_FONCTIONNEL_COMPOSANT, aRf.getRevisionId()); + return theMap; + } + + @Override + public Map visitComponent(final MockupRevision aMockupRev) { + // This object is not use in this report + return null; + } + + @Override + public Map visitComponent(final DescriptifRevision aDescriptifRev) { + // This object is not use in this report + return null; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/visitors/snecmaobject/R21ReceptorVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/visitors/snecmaobject/R21ReceptorVisitor.java new file mode 100644 index 0000000..c5c39be --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r21report/visitors/snecmaobject/R21ReceptorVisitor.java @@ -0,0 +1,158 @@ +package com.capgemini.reports.definition.r21report.visitors.snecmaobject; + +import com.capgemini.reports.definition.r21report.visitors.R21VisitorKeys; +import com.capgemini.reports.snecmaobjects.AbstractSnecmaObject; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAGRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericAssembRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.mockup.MockupRevision; +import com.capgemini.reports.snecmaobjects.part.*; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartAssembRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartRevision; +import com.capgemini.reports.snecmaobjects.supermodel.SuperModelRevision; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; + +import java.util.EnumMap; +import java.util.Map; + +/** + * Visit a Receptor for the R21 report. + */ +public class R21ReceptorVisitor implements IReceptorVisitor> { + private static final long serialVersionUID = -6416544750772729050L; + + @Override + public Map visitReceptor(final ProductRevision aProductRev) { + return getReceptorProperties(aProductRev); + } + + @Override + public Map visitReceptor(final GenericRevision aGenericRev) { + return getReceptorProperties(aGenericRev); + } + + @Override + public Map visitReceptor(final GenericAssembRevision aGenericAssembRev) { + return getReceptorProperties(aGenericAssembRev); + } + + @Override + public Map visitReceptor(SuperModelRevision aSuperModelRev) { + return null; + } + + @Override + public Map visitReceptor(final AlternateRevision aAlternateRev) { + return getReceptorProperties(aAlternateRev); + } + + @Override + public Map visitReceptor(final DETRevision aDetRev) { + return getReceptorProperties(aDetRev); + } + + @Override + public Map visitReceptor(final PartAeroRevision aPartAeroRev) { + return getReceptorProperties(aPartAeroRev); + } + + @Override + public Map visitReceptor(final PartNoAeroRevision aPartNoAeroRev) { + return getReceptorProperties(aPartNoAeroRev); + } + + @Override + public Map visitReceptor(final PartAssembRevision aPartAssembRev) { + return getReceptorProperties(aPartAssembRev); + } + + @Override + public Map visitReceptor(final PartMatRevision aPartMatRev) { + return getReceptorProperties(aPartMatRev); + } + + @Override + public Map visitReceptor(final StandardRevision aStandardRev) { + return getReceptorProperties(aStandardRev); + } + + @Override + public Map visitReceptor(final RFGenericRevision aRfGenericRev) { + return getRepereReceptorProperties(aRfGenericRev); + } + + @Override + public Map visitReceptor(final RFPartAssembRevision aRfPartAssembRev) { + return getRepereReceptorProperties(aRfPartAssembRev); + } + + @Override + public Map visitReceptor(final RFPartRevision aRfPartRev) { + return getRepereReceptorProperties(aRfPartRev); + } + + @Override + public Map visitReceptor(final RFAdminRevision aRfAdminRev) { + return new EnumMap<>(R21VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFAdminARevision aRfAdminARev) { + return new EnumMap<>(R21VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFAdminAPRevision aRfAdminAPRev) { + return new EnumMap<>(R21VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFAdminAGRevision aRfAdminAGRev) { + return new EnumMap<>(R21VisitorKeys.class); + } + + /** + * Recover the Receptor properties to make a R21 report. + */ + private Map getReceptorProperties(final AbstractSnecmaObject aPartOrGeneric) { + Map theMap = new EnumMap<>(R21VisitorKeys.class); + theMap.put(R21VisitorKeys.IDENTIFIANT_RECEPTEUR, aPartOrGeneric.getItemId()); + theMap.put(R21VisitorKeys.REVISION_RECEPTEUR, aPartOrGeneric.getRevisionId()); + theMap.put(R21VisitorKeys.NOM_RECEPTEUR, aPartOrGeneric.getName()); + + return theMap; + } + + /** + * Recover the Repere Receptor properties to make a R21 report. + */ + private Map getRepereReceptorProperties(final AbstractSnecmaObject aRf) { + Map theMap = new EnumMap<>(R21VisitorKeys.class); + theMap.put(R21VisitorKeys.REPERE_FONCTIONNEL_RECEPTEUR, aRf.getName()); + theMap.put(R21VisitorKeys.REVISION_REPERE_FONCTIONNEL_RECEPTEUR, aRf.getRevisionId()); + return theMap; + } + + @Override + public Map visitReceptor(final MockupRevision aMockupRev) { + // This object is not use in this report + return null; + } + + @Override + public Map visitReceptor(final DescriptifRevision aDescriptifRev) { + // This object is not use in this report + return null; + } + + @Override + public Map emptyRf() { + return new EnumMap<>(R21VisitorKeys.class); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/DataReportPreparatorR22.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/DataReportPreparatorR22.java new file mode 100644 index 0000000..62d3379 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/DataReportPreparatorR22.java @@ -0,0 +1,112 @@ +package com.capgemini.reports.definition.r22report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObjectFactory; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRule; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRuleProperties; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindow; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindowConfiguration; +import com.capgemini.framework.teamcenter.object.runtime.TcRevisionRulesConfiguration; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderFactory; +import com.capgemini.reports.bomlineholder.processor.DefaultAltOrDetBehaviour; +import com.capgemini.reports.definition.r22report.ExecutionR22.ReportDataR22; +import com.capgemini.reports.definition.r22report.visitors.R22Visitor; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.filter.AllIsGoodFilter; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.teamcenter.ObjectInfoLoader; +import com.capgemini.reports.teamcenter.resolution.structureservice.MultiStructureServiceCaller; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Form; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * This class will allow to prepare data and findAll back data for making report R22. + */ +class DataReportPreparatorR22 implements IDataReportPreparator { + private static final long serialVersionUID = 1219563840412154089L; + private static final Logger LOGGER = LoggerFactory.getLogger(ExecutionR22.class); + + private static final AllIsGoodFilter ACCEPT_ALL = new AllIsGoodFilter(); + + @Override + public String print(TcSession session, ExecutionR22 execution, IExecutionStrategy executionStrategy) throws KurtException { + PrintParameters printParameters = prepareData(session, execution); + executionStrategy.print(printParameters, execution); + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + } + + private PrintParameters prepareData(final TcSession session, final ExecutionR22 report) throws KurtException { + LOGGER.debug("PrepareData started on: {}", report.getReportIdentifier().getReportTitle()); + + // Obtain the top Part + List list = + new ItemRevisionQuery(session).searchIDAndRevision(report.getPartId(), report.getPartRevision()).findAll(); + if (list.isEmpty()) { + throw new InvalidUserInputException(UserInputErrorEnum.OBJECT_DOES_NOT_EXIST); + } + + ItemRevision itemRevision = null; + + for(ItemRevision currentItemRev : list) { + if(SnecmaObjectTypes.isPartRevision(currentItemRev.getTypeObject().getName())){ + itemRevision = currentItemRev; + break; + } + } + + if(itemRevision == null){ + throw new InvalidUserInputException(UserInputErrorEnum.THE_SELECTED_OBJECT_IS_NOT_PERMITTED_ON_THIS_REPORT); + } + + TcBomObject topLineObject = new TcBomObjectFactory(session, itemRevision).create(); + EffectivityDate effectivityDate = report.getEffectivity(); + + TcRevisionRuleProperties revisionRuleProperties = new TcRevisionRuleProperties(effectivityDate.isNow() ? null : effectivityDate.getDateTime()); + + TcRevisionRule revisionRule = session.findRevRule(report.getRevisionRule()); + TcRevisionRulesConfiguration revRulesConfiguration = new TcRevisionRulesConfiguration(revisionRule, revisionRuleProperties); + + try (TcBomWindow bomWindow = session.createBomWindow(new TcBomWindowConfiguration(topLineObject, revRulesConfiguration))) { + session.setObjectPropPolicy(report.getFullPolicy()); + + // Obtain the clause de propriete form the ItemRevision that was fetched in the config + String typeProduit = ObjectInfoLoader.getProductType(session, (ItemRevision) bomWindow.topLine().get_bl_line_object()); + String clausePropriete = ObjectInfoLoader.getClausePropriete(typeProduit, session); + + // Perform the job + BOMLineHolder unbuiltTopLine = new MultiStructureServiceCaller(session).resolve(bomWindow.topLine(), ACCEPT_ALL); + + List itemRevMaster = unbuiltTopLine.getAllItemRevMasters(); + session.loadProperties(itemRevMaster.toArray(new ModelObject[itemRevMaster.size()])); + BOMLineHolderFactory.buildTopBom(session, unbuiltTopLine, ACCEPT_ALL); + + DefaultAltOrDetBehaviour altOrDetBehaviour = new DefaultAltOrDetBehaviour<>(session, report.getEffectivity().getDateTime()); + unbuiltTopLine.process(altOrDetBehaviour); + unbuiltTopLine.freeze(); + + ReportDataR22 dataR22 = new ReportDataR22(clausePropriete, unbuiltTopLine); + + R22Visitor visitor = new R22Visitor(); + PrintParameters printParameters = visitor.makeMasterTemplate(report, dataR22); + visitor.constructDataMaps(session, printParameters, dataR22); + + LOGGER.debug("PrepareData ended on: {}", report.getReportIdentifier().getReportTitle()); + + return printParameters; + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/ExecutionR22.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/ExecutionR22.java new file mode 100644 index 0000000..4fdd965 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/ExecutionR22.java @@ -0,0 +1,353 @@ +package com.capgemini.reports.definition.r22report; + +import com.capgemini.framework.common.FileHelper; +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.framework.teamcenter.TeamcenterObjectTypes; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.*; +import com.capgemini.framework.teamcenter.files.FileManagement; +import com.capgemini.framework.teamcenter.files.FileManagement.FileType; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.IMANRelationQuery; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemQuery; +import com.capgemini.framework.teamcenter.statuating.StatusSetter; +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.builder.R22Builder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.definition.r22report.ExecutionR22.ReportDataR22; +import com.capgemini.reports.exceptions.InvalidDatasetException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.execution.actions.AbstractPostExecutionStep; +import com.capgemini.reports.execution.actions.IPostExecutionStep; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.reports.parameters.MonoMulti; +import com.capgemini.reports.reports.parameters.checker.ObjectTypeChecker; +import com.teamcenter.services.loose.core._2006_03.FileManagement.GetDatasetWriteTicketsInputData; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.ImanRelation; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.WorkspaceObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +/** + * This class controls the execution of an R22 report. + */ +public class ExecutionR22 extends AbstractExecutionReport { + /** + * The policy to use if the report is launched by workflow, when attaching it to the part as a dataset. + */ + public static final PolicyLocation R22_POLICY_XML_WKF = PolicyLocation.make("R22_policy_wkf", "/xml/policies/r22report/R22_policy_wkf.xml"); + private static final long serialVersionUID = -1050126556474290283L; + private static final Logger log = LoggerFactory.getLogger(ExecutionR22.class); + private static final int MILLIS_PER_SEC = 1000; + // Global parameters + private static final PolicyLocation R22_POLICY_XML_FULL = PolicyLocation.make("R22_policy_full", "/xml/policies/r22report/R22_policy_full.xml"); + private static final PolicyLocation R22_POLICY_XML_LIGHT = PolicyLocation.make("R22_policy_light", "/xml/policies/r22report/R22_policy_light.xml"); + private static final String OUTPUT_FOLDER = SettingsHelper.getReportLocation(); + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R22); + private static final String REPORT_REVISION_RULE = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R22", DEFAULT_REVISION_RULE); + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R22"); + + // Constants + private static final String FILE_SEPARATOR = "_"; + private static final String PATTERN_DATE = "dd-MM-yyyy"; + private static final String BOM_PAR_DATE = "BOMParDate"; + + // Report Configuration + private final EffectivityDate effectivity; + private final String partId; + private final String partRevision; + private final MonoMulti monoMulti; + + + /** + * Executes the Report R22. + * + * @param partId String - the Part Id + * @param partRevision String - the Part Revision + */ + public ExecutionR22(final String partId, final String partRevision) { + super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE); + this.partId = partId; + this.partRevision = partRevision; + this.effectivity = new EffectivityDate(); // Always today + this.monoMulti = MonoMulti.MULTI; + } + + @Override + public List getLaunchData() { + List criteriaValues = new ArrayList<>(); + criteriaValues.add(new CriteriaValue(ReportCriteriaEnum.PART_ID, partId)); + criteriaValues.add(new CriteriaValue(ReportCriteriaEnum.PART_REVISION, partRevision)); + criteriaValues.add(new CriteriaValue(ReportCriteriaEnum.MONO_MULTI, monoMulti.toString())); + return criteriaValues; + } + + @Override + public String getTemplateLocation() { + return JasperTemplate.TEMPLATE_R22.getFilepath(); + } + + @Override + public List getQuickChecks() { + List quickChecks = new ArrayList<>(); + quickChecks.add(new ObjectTypeChecker(partId, SnecmaObjectTypes.ALTERNATE, SnecmaObjectTypes.DET, SnecmaObjectTypes.PART_AERO, + SnecmaObjectTypes.PART_ASSEMB, SnecmaObjectTypes.PART_MAT, SnecmaObjectTypes.PART_NO_AERO, SnecmaObjectTypes.STANDARD)); + return quickChecks; + } + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R22_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R22_POLICY_XML_FULL; + } + + @Override + public List getLongChecks() { + return new ArrayList<>(); // Empty lists - not used for this report + } + + @Override + public ReportEnum getReportIdentifier() { + return wkf ? ReportEnum.REPORT_W22 : ReportEnum.REPORT_R22; + } + + @Override + public String getSpecifiedFileName() { + // Format file expected : R22-BOMParDATE_{ReferenceArticle}_{RevisionArticle}_{date_systeme}.pdf + String dateSystem = TeamcenterDateFormatter.formatCalendarToPattern(Calendar.getInstance(), PATTERN_DATE); + return "R22-BOMParDATE_" + partId + FILE_SEPARATOR + partRevision + FILE_SEPARATOR + + dateSystem; + } + + @Override + public PrintFormat getPrintingFormat() { + return PrintFormat.PDF; + } + + public String getPartId() { + return partId; + } + + public String getPartRevision() { + return partRevision; + } + + public EffectivityDate getEffectivity() { + return effectivity; + } + + @Override + public IDataReportPreparator getDataPreparator() { + return new DataReportPreparatorR22(); + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return new ExecutionR22(partId, partRevision); + } + + /** + * Returns a {@link IPostExecutionStep} which attaches the report to the Part as a Dataset (and feezes the Dataset). + * + * @return the action + */ + public IPostExecutionStep makeAttachPdfToPartAction() { + return new R22AttachPdfToPartAction(); + } + + + /* ************************************************************************************ + * Workflow action + * ************************************************************************************ */ + + private File copyFile(final String datasetFileName) throws NotFoundException { + String originalFileNameOnDisc = getFileNameOnDisc(); + File original = new File(OUTPUT_FOLDER + originalFileNameOnDisc + ".pdf"); + final File copy = new File(OUTPUT_FOLDER + datasetFileName + ".pdf"); + FileHelper.copy(original, copy); + return copy; + } + + private String makeDatasetName() { + return StringHelper.implode(FILE_SEPARATOR, BOM_PAR_DATE, partId, partRevision); + } + + private String makeDatasetFileName() { + Date startDate; + try { + startDate = new SimpleDateFormat(TeamcenterDateFormatter.DD_MM_YYYY_HH_MM_SS).parse(getStartTime()); + } catch (ParseException e) { + log.warn("Unable to parse stored start date, generating a date using NOW", e); + startDate = new Date(); + } + String dateStr = new SimpleDateFormat(TeamcenterDateFormatter.YYYYMMDD).format(startDate); + long timestamp = startDate.getTime() / MILLIS_PER_SEC; + String timestampStr = String.valueOf(timestamp); + return StringHelper.implode(FILE_SEPARATOR, BOM_PAR_DATE, partId, partRevision, dateStr, timestampStr); + } + + private Item obtainPart(final TcSession session) throws NotFoundException { + List matchingParts = new ItemQuery(session).searchID(partId).findAll(); + + for(Item currentPart : matchingParts){ + if(SnecmaObjectTypes.isPart(currentPart.getTypeObject().getName())){ + return currentPart; + } + } + + if (matchingParts.isEmpty()) { + throw new NotFoundException("Could not find the original part " + partId); + } else { + throw new NotFoundException(partId + " part not found other type found instead"); + } + + } + + private void destroyConflictingDatasets(final TcSession session, final String datasetName, final Item thePart) + throws FailedRelationshipActionException { + List existingRelations = new IMANRelationQuery(session).find(partId, datasetName); + log.debug("Wokflow launch: destrying previous datasets: {} relations found", existingRelations.size()); + // Let's browse all conflicting datasets + for (ImanRelation relation : existingRelations) { + ModelObject datasetMO = relation.get_secondary_object(); + + // Let's destroy the relation first + log.debug("Wokflow launch: destroying relation between part {} and datasets {}", thePart.getUid(), datasetMO.getUid()); + session.deleteObjects(relation); + + // Net's destroy the Dataset now that it is free from relationships + log.debug("Wokflow launch: destroying datasets {}", datasetMO.getUid()); + session.deleteObjects(datasetMO); + } + } + + private GetDatasetWriteTicketsInputData createDataset(final TcSession session, final String datasetName, final File fileCopy) + throws InvalidDatasetException { + String dataSetDescription = ReportEnum.REPORT_R22.getReportTitle(); + + // Perform the upload + GetDatasetWriteTicketsInputData data; + try { + data = FileManagement.addSingleDataSet(session, datasetName, dataSetDescription, fileCopy, FileType.FICHE_ARTICLE); + } catch (MalformedDataSetException | ConnectionMisconguredException e) { + throw new InvalidDatasetException("Unable to create the dataset for R22 report " + getReportTechnicalUid(), e); + } + return data; + } + + private void linkDatasetToPart(final TcSession session, final Item thePart, final ModelObject dataset) + throws FailedRelationshipActionException { + try { + session.createRelation(thePart, dataset, TeamcenterObjectTypes.IMAN_REFERENCE); + } catch (FailedRelationshipActionException e) { + // Unable to link back the dataset to the part. Let's cleanup behind us and destroy that orphan dataset! + session.deleteObjects(dataset); + throw e; + } + + } + + private void addFrozenStatusToDataset(final TcSession session, final ModelObject dataset) throws UnableToCreateStatusException { + StatusSetter statusMng = new StatusSetter(session); + statusMng.putStatus((WorkspaceObject) dataset, StatusEnum.FROZEN.getIdentifier()); + } + + @Override + public Class getReportBuilderClass() { + return R22Builder.class; + } + + /** + * POJO container of all data required for this report. + */ + public static class ReportDataR22 { + private final String clausePropriete; + private final BOMLineHolder topLine; + + protected ReportDataR22(final String clausePropriete, final BOMLineHolder topLine) { + this.clausePropriete = clausePropriete; + this.topLine = topLine; + } + + public String getClausePropriete() { + return clausePropriete; + } + + public BOMLineHolder getTopLine() { + return topLine; + } + } + + private class R22AttachPdfToPartAction extends AbstractPostExecutionStep { + private static final long serialVersionUID = -1516821856454786852L; + + /** + * Creates an action that will attach the pdf to the part. + */ + private R22AttachPdfToPartAction() { + super(ExecutionR22.class); + } + + @Override + public Void performPostActionOnReport(final TcSession session, final ExecutionR22 report, final DbReport theExecutingReport, + final String fileNameWithExtension) throws KurtException { + session.setObjectPropPolicy(R22_POLICY_XML_WKF); + + // Prepare naming & Make a copy with the correct name + log.debug("Wokflow launch: Beginning file copy"); + String datasetName = report.makeDatasetName(); + String datasetFileName = report.makeDatasetFileName(); + File fileCopy = report.copyFile(datasetFileName); + + // Obtain the Part + Item thePart = report.obtainPart(session); + + // Detect & destroy conflicting datasets on the part, if any + log.debug("Wokflow launch: Destroying previous datasets..."); + report.destroyConflictingDatasets(session, datasetName, thePart); + + // Create a new dataset + log.debug("Wokflow launch: Creating datasets {}", datasetName); + GetDatasetWriteTicketsInputData dataset = report.createDataset(session, datasetName, fileCopy); + + // Link the part to the dataset (if it fails, it will cleanup the dataset as well) + log.debug("Wokflow launch: Linking Part {} to newly created dataset {}", thePart.getUid(), dataset.dataset.getUid()); + report.linkDatasetToPart(session, thePart, dataset.dataset); + + // Freeze the dataset + log.debug("Wokflow launch: Adding 'Frozen' status to the dataset {}", dataset.dataset.getUid()); + report.addFrozenStatusToDataset(session, dataset.dataset); + + log.debug("R22 Execution from workflow has completed successfuly for part {}-{}", partId, partRevision); + return null; + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/R22Visitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/R22Visitor.java new file mode 100644 index 0000000..b410fc3 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/R22Visitor.java @@ -0,0 +1,123 @@ +package com.capgemini.reports.definition.r22report.visitors; + +import com.capgemini.framework.common.ResourceHelper; +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.definition.r22report.ExecutionR22; +import com.capgemini.reports.definition.r22report.ExecutionR22.ReportDataR22; +import com.capgemini.reports.definition.r22report.visitors.bomlineholder.R22BOMLineHolderVisitor; +import com.capgemini.reports.exceptions.FileLoadingException; +import com.capgemini.reports.execution.mapconstructor.AbstractStaticTemplateMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.reports.IReportVisitor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.awt.image.BufferedImage; +import java.util.*; + +/** + * Visit a R22 report. + */ +public class R22Visitor extends AbstractStaticTemplateMapConstructor implements IReportVisitor { + private static final long serialVersionUID = -1530604820422919903L; + private static final Logger LOGGER = LoggerFactory.getLogger(R22Visitor.class); + + private static final String SNECMA_LOGO = "/Jasper/images/Snecma_logo.png"; + private static final String EMPTY = ""; + private static final String MULTI_NIVEAUX = "Multi-niveaux"; + + private final R22BOMLineHolderVisitor r22BOMLineHolderVisitor = new R22BOMLineHolderVisitor(); + + public R22Visitor() { + super(); + } + + private static String check(final Object anInput) { + return anInput == null ? EMPTY : anInput.toString(); + } + + private List> translate(final List> visitorMaps) { + // Add empty fields in the first line + Map firstLine = visitorMaps.get(0); + + // Empty receptor + firstLine.put(R22VisitorKeys.RECEPTEUR, EMPTY); + firstLine.put(R22VisitorKeys.REPERE_FONCTIONNEL_REVISION, EMPTY); + firstLine.put(R22VisitorKeys.RESPONSABLE_REPERE, EMPTY); + firstLine.put(R22VisitorKeys.ALT, EMPTY); + firstLine.put(R22VisitorKeys.SB, EMPTY); + firstLine.put(R22VisitorKeys.NQC, EMPTY); + firstLine.put(R22VisitorKeys.PANACHAGE, EMPTY); + firstLine.put(R22VisitorKeys.COEFF, EMPTY); + + // Construct the map list expected by the printer + List> printerMaps = new ArrayList<>(); + for (Map visitorMap : visitorMaps) { + HashMap printerMap = new HashMap<>(); + for (R22VisitorKeys key : R22VisitorKeys.values()) { + printerMap.put(key.toString(), check(visitorMap.get(key))); + } + printerMaps.add(printerMap); + } + LOGGER.debug("Translate map {}", printerMaps); + return printerMaps; + } + + /** + * Add additional elements for header of R22 report. + * + * @param aDateNow Current date as string + * @param ressource url resource + * @param clausePropriete the 'clause de propriete' Snecma + * @return map of additional elements + */ + private EnumMap addAdditionalParameters(final String aDateNow, final String ressource, + final String clausePropriete) { + EnumMap map = new EnumMap<>(R22VisitorParametersKeys.class); + map.put(R22VisitorParametersKeys.CLAUSE_DE_PROPRIETE, clausePropriete); + map.put(R22VisitorParametersKeys.DATE_EFFECTIVITE, aDateNow); + map.put(R22VisitorParametersKeys.DATE_TRAITEMENT, aDateNow); + map.put(R22VisitorParametersKeys.NIVEAU, MULTI_NIVEAUX); + map.put(R22VisitorParametersKeys.REFERENCE_ARTICLE, r22BOMLineHolderVisitor.getReferenceItem()); + + try { + BufferedImage image = ResourceHelper.loadImage(ressource); + map.put(R22VisitorParametersKeys.LOGO_SNECMA, image); + } catch (FileLoadingException e) { + LOGGER.warn("Could not load Snecma logo", e); + } + + LOGGER.debug("MAP {}", map); + + return map; + } + + @Override + public List> visitReport(final BOMLineHolder holder) { + List> visitorMaps = r22BOMLineHolderVisitor.visitTopReceptorBom(holder); + return translate(visitorMaps); + } + + @Override + public void constructDataMaps(TcSession session, final PrintParameters printParameters, final ReportDataR22 data) throws KurtException { + long start = System.currentTimeMillis(); + if (data.getTopLine() == null) { + throw new NoSuchElementException("No object structure found"); + } + LOGGER.info("ConstructDataMaps "); + + // Parse all the snecma objects... + List> printerMaps = this.visitReport(data.getTopLine()); + LOGGER.debug("Printer map size {}", printerMaps.size()); + printParameters.addReportData(printerMaps); + + String dateNowInFrench = TeamcenterDateFormatter.formatCalendarToFrench(Calendar.getInstance()); + EnumMap additionalParameters = addAdditionalParameters(dateNowInFrench, SNECMA_LOGO, data.getClausePropriete()); + printParameters.addReportParameters(additionalParameters); + + LOGGER.info(EXECUTION_TIME_XXX_MS_FOR_YYY, System.currentTimeMillis() - start, "data filtering"); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/R22VisitorKeys.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/R22VisitorKeys.java new file mode 100644 index 0000000..5fc21bc --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/R22VisitorKeys.java @@ -0,0 +1,25 @@ +package com.capgemini.reports.definition.r22report.visitors; + +/** + * Enumeration of all the keys to the R22 report fields. + */ +public enum R22VisitorKeys { + RECEPTEUR, + REPERE_FONCTIONNEL_REVISION, + RESPONSABLE_REPERE, + ALT, + SB, + NQC, + PANACHAGE, + COEFF, + COMPOSANT, + FABRICANT, + DENOMINATION, + ALTERNATIVE, + CLASSEMENT, + SUIVI_UTILISATION, + SUIVI_MONTAGE, + MASSE_INDICATIVE, + UNITE_DE_MASSE, + CONCEPTEUR +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/R22VisitorParametersKeys.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/R22VisitorParametersKeys.java new file mode 100644 index 0000000..a6625cd --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/R22VisitorParametersKeys.java @@ -0,0 +1,14 @@ +package com.capgemini.reports.definition.r22report.visitors; + +/** + * Enumeration of all the parameters keys to the R22 report fields ( header). + */ + +public enum R22VisitorParametersKeys { + CLAUSE_DE_PROPRIETE, + DATE_TRAITEMENT, + DATE_EFFECTIVITE, + REFERENCE_ARTICLE, + NIVEAU, + LOGO_SNECMA +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/bomlineholder/R22AltOrDetBehaviour.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/bomlineholder/R22AltOrDetBehaviour.java new file mode 100644 index 0000000..6986f8c --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/bomlineholder/R22AltOrDetBehaviour.java @@ -0,0 +1,50 @@ +package com.capgemini.reports.definition.r22report.visitors.bomlineholder; + +import com.capgemini.reports.bomlineholder.processor.AltOrDetBehaviour; +import com.capgemini.reports.definition.r22report.visitors.R22VisitorKeys; +import com.capgemini.reports.snecmaobjects.part.AlternateRevision; +import com.capgemini.reports.snecmaobjects.part.DETRevision; + +import java.util.Map; + +/** + * This class visits Parts that are below an {@link AlternateRevision} or a {@link DETRevision}.
+ * It puts "Oui" in the ALTERNATIVE field of a map. + */ +public class R22AltOrDetBehaviour implements AltOrDetBehaviour { + private static final long serialVersionUID = -6520666717827385535L; + + private static final String OUI = "Oui"; + private static final String EMPTY_STRING = ""; + + @Override + public boolean shouldVisitPartsInPseudoFolder() { + return true; + } + + @Override + public boolean shouldVisitPartsBelowAlt() { + return true; + } + + @Override + public void treatPartsInPseudoFolder(final Map map) { + // EMPTY fields, if current object is an ALTERNATE or DET + map.put(R22VisitorKeys.REPERE_FONCTIONNEL_REVISION, EMPTY_STRING); + map.put(R22VisitorKeys.RESPONSABLE_REPERE, EMPTY_STRING); + map.put(R22VisitorKeys.ALT, EMPTY_STRING); + map.put(R22VisitorKeys.SB, EMPTY_STRING); + map.put(R22VisitorKeys.NQC, EMPTY_STRING); + map.put(R22VisitorKeys.PANACHAGE, EMPTY_STRING); + map.put(R22VisitorKeys.COEFF, EMPTY_STRING); + + // Column alternative must be defined to OUI + map.put(R22VisitorKeys.ALTERNATIVE, OUI); + } + + @Override + public void treatAlternateOrDETAsReceptor(final Map map) { + // Column alternative must be defined to OUI + map.put(R22VisitorKeys.ALTERNATIVE, OUI); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/bomlineholder/R22BOMLineHolderVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/bomlineholder/R22BOMLineHolderVisitor.java new file mode 100644 index 0000000..195d2bd --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/bomlineholder/R22BOMLineHolderVisitor.java @@ -0,0 +1,97 @@ +package com.capgemini.reports.definition.r22report.visitors.bomlineholder; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.visitor.AbstractBOMLineHolderVisitor; +import com.capgemini.reports.definition.r22report.visitors.R22VisitorKeys; +import com.capgemini.reports.definition.r22report.visitors.snecmaobject.R22ComponentVisitor; +import com.capgemini.reports.definition.r22report.visitors.snecmaobject.R22ReceptorVisitor; +import com.capgemini.reports.releasestatus.EffectivityBehaviourHelper; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; + +/** + * Visitor of an expansion of BOMLineHolder for the R22 report. + */ +public class R22BOMLineHolderVisitor extends AbstractBOMLineHolderVisitor { + private static final long serialVersionUID = -8251274449267683067L; + private static final Logger LOGGER = LoggerFactory.getLogger(R22BOMLineHolderVisitor.class); + private static final String SEMICOLON = " ; "; + private static final String SPACE = " "; + private ISnecmaObject topBomLine; + + public R22BOMLineHolderVisitor() { + super(new R22ReceptorVisitor(), new R22ComponentVisitor(), EffectivityBehaviourHelper.visitAnyPart(), new R22AltOrDetBehaviour(), true, + false, true); + } + + @Override + protected Map visitThisReceptor(final BOMLineHolder aBomLine) { + LOGGER.debug("visitThisReceptor {" + aBomLine.getUid() + "}"); + return aBomLine.getSnecmaObject().accept(receptorVisitor); + } + + @Override + protected Map visitThisComponent(final BOMLineHolder aBomLine) { + LOGGER.debug("visitThisComponent {" + aBomLine.getUid() + "}"); + Map aMap = aBomLine.getSnecmaObject().accept(componentVisitor); + // Put the BOMLine properties into the map + if (aBomLine.getSnecmaObject().isGeneric() || aBomLine.getSnecmaObject().isPart()) { + aMap.put(R22VisitorKeys.ALT, aBomLine.getBomAlt()); + aMap.put(R22VisitorKeys.SB, aBomLine.getBomSb()); + aMap.put(R22VisitorKeys.NQC, aBomLine.getBomQtyCumul()); + aMap.put(R22VisitorKeys.PANACHAGE, aBomLine.getBomPanache()); + aMap.put(R22VisitorKeys.COEFF, aBomLine.getBomQty()); + } + return aMap; + } + + @Override + protected void visitSpecificFirstLine(final BOMLineHolder aTopBomLine) { + topBomLine = aTopBomLine.getSnecmaObject(); + Map theFirstLine = topBomLine.accept(getComponentVisitor()); + theReportTable.add(theFirstLine); + } + + @Override + protected void mergeReceptorAndRepereReceptor(final Map aReceptor, final Map aRepereReceptor) { + aReceptor.putAll(aRepereReceptor); + } + + @Override + protected void mergeComponentAndRepereComponent(final Map aComponent, final Map aRepereComponent) { + aComponent.putAll(aRepereComponent); + } + + @Override + protected void mergeRepereReceptorandAdmin(final Map aRepereReceptor, final Map anAdmin) { + aRepereReceptor.putAll(anAdmin); + } + + @Override + protected void mergeRepereComponentandAdmin(final Map aRepereComponent, final Map anAdmin) { + aRepereComponent.putAll(anAdmin); + } + + @Override + protected void addToReport(final Map aReceptor, final Map aComponent) { + // Put the Receptor and Repere Receptor in the Component and modify the Component + // Do not modify the receptor + aComponent.putAll(aReceptor); + + // Add to the R22 report + theReportTable.add(aComponent); + } + + /** + * Format Item to display in report.
+ * EXPECTED : object id ; object revision id object name. + * + * @return reference item + */ + public String getReferenceItem() { + return topBomLine.getItemId() + SEMICOLON + topBomLine.getRevisionId() + SPACE + topBomLine.getName(); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/snecmaobject/R22ComponentVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/snecmaobject/R22ComponentVisitor.java new file mode 100644 index 0000000..c7798cd --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/snecmaobject/R22ComponentVisitor.java @@ -0,0 +1,218 @@ +package com.capgemini.reports.definition.r22report.visitors.snecmaobject; + +import com.capgemini.framework.common.DoubleFormatter; +import com.capgemini.framework.common.LanguageHelper; +import com.capgemini.reports.definition.r22report.visitors.R22VisitorKeys; +import com.capgemini.reports.snecmaobjects.AbstractSnecmaObject; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAGRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericAssembRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.mockup.MockupRevision; +import com.capgemini.reports.snecmaobjects.part.*; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.snecmaobjects.rf.AbstractRF; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartAssembRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartRevision; +import com.capgemini.reports.snecmaobjects.supermodel.SuperModelRevision; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; + +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; + +/** + * Visitor for Components of the r22 report. + */ +public class R22ComponentVisitor implements IComponentVisitor> { + private static final long serialVersionUID = -4087090295500160461L; + + // Formatting + private static final int MASS_SIGNIFICANT_DIGITS = 9; + private static final String SEPARATOR = " ; "; + + // Default content + private static final String EMPTY_STRING = ""; + private static final String NON = "Non"; + + /** + * Extracts left side of a string of the form "French text / English text".
+ * Separator slash may have any number (0+) of white spaces around them + * + * @param string + * @return the left side (if any "side" exists), an empty string otherwise + */ + private static String french(final String string) { + return LanguageHelper.french(string); + } + + @Override + public Map visitComponent(final ProductRevision aProductRev) { + // Not used + return new HashMap<>(); + } + + @Override + public Map visitComponent(final GenericRevision aGenericRev) { + // Not used + return new HashMap<>(); + } + + @Override + public Map visitComponent(SuperModelRevision aSuperModelRev) { + return null; + } + + @Override + public Map visitComponent(final GenericAssembRevision aGenericAssembRev) { + // Not used + return new HashMap<>(); + } + + @Override + public Map visitComponent(final AlternateRevision aAlternateRev) { + return getPartProperties(aAlternateRev); + } + + @Override + public Map visitComponent(final DETRevision aDetRev) { + return getPartProperties(aDetRev); + } + + @Override + public Map visitComponent(final PartAeroRevision aPartAeroRev) { + return getPartProperties(aPartAeroRev); + } + + @Override + public Map visitComponent(final PartNoAeroRevision aPartNoAeroRev) { + return getPartProperties(aPartNoAeroRev); + } + + @Override + public Map visitComponent(final PartAssembRevision aPartAssembRev) { + return getPartProperties(aPartAssembRev); + } + + @Override + public Map visitComponent(final PartMatRevision aPartMatRev) { + return getPartMatProperties(aPartMatRev); + } + + @Override + public Map visitComponent(final StandardRevision aStandardRev) { + return getPartProperties(aStandardRev); + } + + @Override + public Map visitComponent(final RFGenericRevision aRfGenericRev) { + // Not used + return new HashMap<>(); + } + + @Override + public Map visitComponent(final RFPartAssembRevision aRfPartAssembRev) { + return getReceptorProperties(aRfPartAssembRev); + } + + @Override + public Map visitComponent(final RFPartRevision aRfPartRev) { + return getReceptorProperties(aRfPartRev); + } + + @Override + public Map visitComponent(final RFAdminRevision aRfAdminRev) { + Map theMap = new EnumMap<>(R22VisitorKeys.class); + theMap.put(R22VisitorKeys.RESPONSABLE_REPERE, aRfAdminRev.getResponsableRepere()); + return theMap; + } + + @Override + public Map visitComponent(final RFAdminARevision aRfAdminARev) { + Map theMap = new EnumMap<>(R22VisitorKeys.class); + // Split because return value like oui/yes or Non/No + theMap.put(R22VisitorKeys.SUIVI_MONTAGE, french(aRfAdminARev.getSuiviMontage())); + theMap.put(R22VisitorKeys.RESPONSABLE_REPERE, aRfAdminARev.getResponsableRepere()); + return theMap; + } + + @Override + public Map visitComponent(final RFAdminAPRevision aRfAdminAPRev) { + Map theMap = new EnumMap<>(R22VisitorKeys.class); + // Split because return value like oui/yes or Non/No + theMap.put(R22VisitorKeys.SUIVI_MONTAGE, french(aRfAdminAPRev.getSuiviMontage())); + return theMap; + } + + @Override + public Map visitComponent(final RFAdminAGRevision aRfAdminAGRev) { + // Not used + return new HashMap<>(); + } + + private Map getAbstractSnecmaObjectProperties(final AbstractSnecmaObject snecmaObject) { + Map theMap = new EnumMap<>(R22VisitorKeys.class); + // Correspond colonne -> Réf. fabricant / Réf. SNECMA ; Révision + theMap.put(R22VisitorKeys.COMPOSANT, + snecmaObject.getItemId() + SEPARATOR + snecmaObject.getRevisionId()); + theMap.put(R22VisitorKeys.DENOMINATION, snecmaObject.getName()); + theMap.put(R22VisitorKeys.ALTERNATIVE, EMPTY_STRING); + return theMap; + } + + private Map getAbstractPartProperties(final AbstractPart part) { + Map theMap = new EnumMap<>(R22VisitorKeys.class); + theMap.put(R22VisitorKeys.FABRICANT, part.getResponsableConception()); + theMap.put(R22VisitorKeys.CLASSEMENT, part.getClassement()); + theMap.put(R22VisitorKeys.SUIVI_UTILISATION, french(part.getSuiviUtilisation())); + theMap.put(R22VisitorKeys.MASSE_INDICATIVE, DoubleFormatter.toSignificantDigits(part.getMass(), MASS_SIGNIFICANT_DIGITS)); + theMap.put(R22VisitorKeys.UNITE_DE_MASSE, part.getMassUnit()); + theMap.put(R22VisitorKeys.CONCEPTEUR, part.getRefCompleteConcepteur()); + return theMap; + } + + private Map getAbstractPartMatProperties(final PartMatRevision partMatRevision) { + Map theMap = new EnumMap<>(R22VisitorKeys.class); + theMap.put(R22VisitorKeys.FABRICANT, partMatRevision.getResponsableConception()); + theMap.put(R22VisitorKeys.CLASSEMENT, partMatRevision.getClassementMat()); + theMap.put(R22VisitorKeys.SUIVI_UTILISATION, NON); + theMap.put(R22VisitorKeys.MASSE_INDICATIVE, EMPTY_STRING); + theMap.put(R22VisitorKeys.UNITE_DE_MASSE, EMPTY_STRING); + theMap.put(R22VisitorKeys.CONCEPTEUR, EMPTY_STRING); + return theMap; + } + + private Map getPartMatProperties(final PartMatRevision anAbstractSnecmaObject) { + Map theMap = getAbstractSnecmaObjectProperties(anAbstractSnecmaObject); + theMap.putAll(getAbstractPartMatProperties(anAbstractSnecmaObject)); + return theMap; + } + + private Map getPartProperties(final AbstractPart anAbstractSnecmaObject) { + Map theMap = getAbstractSnecmaObjectProperties(anAbstractSnecmaObject); + theMap.putAll(getAbstractPartProperties(anAbstractSnecmaObject)); + return theMap; + } + + private Map getReceptorProperties(final AbstractRF rf) { + Map theMap = new EnumMap<>(R22VisitorKeys.class); + theMap.put(R22VisitorKeys.REPERE_FONCTIONNEL_REVISION, rf.getName() + SEPARATOR + rf.getRevisionId()); + return theMap; + } + + @Override + public Map visitComponent(final MockupRevision aMockupRev) { + // This object is not use in this report + return null; + } + + @Override + public Map visitComponent(final DescriptifRevision aDescriptifRev) { + // This object is not use in this report + return null; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/snecmaobject/R22ReceptorVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/snecmaobject/R22ReceptorVisitor.java new file mode 100644 index 0000000..961c191 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r22report/visitors/snecmaobject/R22ReceptorVisitor.java @@ -0,0 +1,160 @@ +package com.capgemini.reports.definition.r22report.visitors.snecmaobject; + +import com.capgemini.reports.definition.r22report.visitors.R22VisitorKeys; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAGRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericAssembRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.mockup.MockupRevision; +import com.capgemini.reports.snecmaobjects.part.*; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartAssembRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartRevision; +import com.capgemini.reports.snecmaobjects.supermodel.SuperModelRevision; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; + +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; + +/** + * Visit a Receptor SnecmaObject to make a R22 report. + */ +public class R22ReceptorVisitor implements IReceptorVisitor> { + private static final long serialVersionUID = -674550302066648191L; + + private static final String SEPARATOR = " ; "; + + @Override + public Map visitReceptor(final ProductRevision aProductRev) { + // No use in R22 report + return new HashMap<>(); + } + + @Override + public Map visitReceptor(final GenericRevision aGenericRev) { + // No use in R22 report + return new HashMap<>(); + } + + @Override + public Map visitReceptor(final GenericAssembRevision aGenericAssembRev) { + // No use in R22 report + return new HashMap<>(); + } + + @Override + public Map visitReceptor(SuperModelRevision aSuperModelRev) { + return null; + } + + @Override + public Map visitReceptor(final AlternateRevision aAlternateRev) { + return getReceptorProperties(aAlternateRev); + } + + @Override + public Map visitReceptor(final DETRevision aDetRev) { + return getReceptorProperties(aDetRev); + } + + @Override + public Map visitReceptor(final PartAeroRevision aPartAeroRev) { + return getReceptorProperties(aPartAeroRev); + } + + @Override + public Map visitReceptor(final PartNoAeroRevision aPartNoAeroRev) { + return getReceptorProperties(aPartNoAeroRev); + } + + @Override + public Map visitReceptor(final PartAssembRevision aPartAssembRev) { + return getReceptorProperties(aPartAssembRev); + } + + @Override + public Map visitReceptor(final PartMatRevision aPartMatRev) { + return getReceptorProperties(aPartMatRev); + } + + @Override + public Map visitReceptor(final StandardRevision aStandardRev) { + return getReceptorProperties(aStandardRev); + } + + @Override + public Map visitReceptor(final RFGenericRevision aRfGenericRev) { + // No use in R22 report + return new HashMap<>(); + } + + @Override + public Map visitReceptor(final RFPartAssembRevision aRfPartAssembRev) { + // No use in R22 report + return new HashMap<>(); + } + + @Override + public Map visitReceptor(final RFPartRevision aRfPartRev) { + // No use in R22 report + return new HashMap<>(); + } + + @Override + public Map visitReceptor(final RFAdminRevision aRfAdminRev) { + // No use in R22 report + return new HashMap<>(); + } + + @Override + public Map visitReceptor(final RFAdminARevision aRfAdminARev) { + // No use in R22 report + return new HashMap<>(); + } + + @Override + public Map visitReceptor(final RFAdminAPRevision aRfAdminAPRev) { + // No use in R22 report + return new HashMap<>(); + } + + @Override + public Map visitReceptor(final RFAdminAGRevision aRfAdminAGRev) { + // No use in R22 report + return new HashMap<>(); + } + + /** + * Get the Receptor properties.
+ *

+ * expected format : (item_id ; item_revision_id) + */ + private Map getReceptorProperties(final ISnecmaObject iSnecmaObject) { + Map theMap = new EnumMap<>(R22VisitorKeys.class); + theMap.put(R22VisitorKeys.RECEPTEUR, iSnecmaObject.getItemId() + SEPARATOR + iSnecmaObject.getRevisionId()); + return theMap; + } + + @Override + public Map visitReceptor(final MockupRevision aMockupRev) { + // This object is not use in this report + return null; + } + + @Override + public Map visitReceptor(DescriptifRevision aDescriptifRev) { + // This object is not use in this report + return null; + } + + @Override + public Map emptyRf() { + return new HashMap<>(); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/DataReportPreparatorR23.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/DataReportPreparatorR23.java new file mode 100644 index 0000000..1ca30b8 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/DataReportPreparatorR23.java @@ -0,0 +1,170 @@ +package com.capgemini.reports.definition.r23report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObjectFactory; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRule; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRuleProperties; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.product.TcProduct; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.product.TcProductRevision; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.unit.TcUnitRevision; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindow; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindowConfiguration; +import com.capgemini.framework.teamcenter.object.runtime.TcRevisionRulesConfiguration; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderFactory; +import com.capgemini.reports.bomlineholder.processor.DefaultAltOrDetBehaviour; +import com.capgemini.reports.definition.r23report.visitors.R23Visitor; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NoConfChangesException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.filter.AllIsGoodFilter; +import com.capgemini.reports.optimized.r23report.OptimizedR23Folder; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.reports.parameters.MonoMulti; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.teamcenter.resolution.structureservice.IStructureServiceCaller; +import com.capgemini.reports.teamcenter.resolution.structureservice.MultiStructureServiceCaller; +import com.capgemini.reports.teamcenter.resolution.structureservice.TripleStructureServiceCaller; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Form; +import com.teamcenter.soa.client.model.strong.PSBOMView; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.List; + +import static com.capgemini.framework.teamcenter.object.pom.status.StatusEnum.*; + +/** + * This class will allow to prepare data and findAll back data for making report R23. + */ +public class DataReportPreparatorR23 implements IDataReportPreparator { + private static final long serialVersionUID = 1758410914529352674L; + private static final Logger LOGGER = LoggerFactory.getLogger(DataReportPreparatorR23.class); + + private static final AllIsGoodFilter ACCEPT_ALL = new AllIsGoodFilter(); + + @Override + public String print(final TcSession session, final ExecutionR23 execution, final IExecutionStrategy executionStrategy) throws KurtException { + ProductUnit productUnit = execution.getProductUnit(); + TcProduct tcProduct = new TcProduct(session, productUnit.getProduct(session)); + TcProductRevision tcProductRevision = tcProduct.revisions().get(0); + execution.setProductLine(tcProductRevision.ligneProduit()); + PrintParameters printParameters = execution.reportParameters(); + + if (new OptimizedR23Folder().configurationHasNotChanged(productUnit)) { + throw new NoConfChangesException(UserInputErrorEnum.NO_CONFIGURATION_CHANGES.getMsgEn()); + } + + if (!hasMoreThanOneEffectiveUnit(session, execution, productUnit, tcProduct, tcProductRevision, printParameters)) { + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_EXTRACTED_FOR_CRITERIA); + } + + executionStrategy.print(printParameters, execution); + + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + } + + private boolean hasMoreThanOneEffectiveUnit(final TcSession session, final ExecutionR23 execution, final ProductUnit productUnit, final TcProduct tcProduct, final TcProductRevision tcProductRevision, final PrintParameters printParameters) throws KurtException { + boolean hasMoreThanOneEffectiveUnit = false; + for (TcUnitRevision unitRevision : unitToProcess(tcProductRevision, execution.isWithFrozenUnit(),execution.getProductUnitForUnit(), execution.getProductUnitFromUnit(), execution.getNbDaysSinceFrozenStr())) { + int unitNumber = unitRevision.unitNumber(); + // Get revision of the unit for usage in the report name + String unitRev = unitRevision.getUnitRev(); + // Get unit frozen information for usage in the report name + boolean isFrozen = false; + if(unitRevision.hasStatus(J3A, J3B, FROZEN, FROZEN_IN_PROCESS)) { + isFrozen = true; + } + LOGGER.debug("Unit [{}] Revision [{}] is Frozen ? = [{}]", unitNumber, unitRev, isFrozen); + ProductUnit subProductUnit = new ProductUnit(productUnit.getProductID(), unitNumber); + ExecutionR23 subExecution = new ExecutionR23(subProductUnit, execution.getGeneric(), execution.getMonoMulti(), execution.getEffectivityDate(), execution.isSuperModelBOM(), + execution.isWithFrozenUnit(), execution.getProductUnitForUnit(), execution.getProductUnitFromUnit(), execution.getNbDaysSinceFrozenStr()); + subExecution.setProductLine(tcProductRevision.ligneProduit()); + subExecution.setUnitRevision(unitRev); + subExecution.setFrozenUnit(isFrozen); + try { + printParameters.addSubReport("R23-" + unitNumber, prepareData(session, subExecution, tcProduct, unitNumber)); + hasMoreThanOneEffectiveUnit = true; + } + catch (KurtException e) { + LOGGER.warn(e.getMessage(), e); + } + } + return hasMoreThanOneEffectiveUnit; + } + + private List unitToProcess(final TcProductRevision tcProductRevision, boolean isWithFrozenUnit, ProductUnit productUnitForUnit, ProductUnit productUnitFromUnit, String nbDaysSinceFrozenStr) throws KurtException { + List unitsToProcess = tcProductRevision.r23UnitRevisions(isWithFrozenUnit, productUnitForUnit, productUnitFromUnit, nbDaysSinceFrozenStr); + if (unitsToProcess.isEmpty()) { + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_NO_FROZEN_OR_OPEN_UNIT_TO_THE_PRODUCT); + } + return unitsToProcess; + } + + private PrintParameters prepareData(final TcSession session, final ExecutionR23 report, final TcProduct tcProduct, final int unitNumber) throws KurtException { + LOGGER.debug("PrepareData started on: {}", report.getReportIdentifier().getReportTitle()); + + TcBomObject topLineObject= new TcBomObjectFactory(session, report.getGeneric().getItem(session)).create(); + TcProduct productObject = new TcProduct(session, report.getProductUnit().getProduct(session)); + TcProductRevision productObjectRevision = productObject.revisions().get(0); + + EffectivityDate effectivityDate = report.getEffectivityDate(); + TcRevisionRuleProperties revisionRuleProperties = new TcRevisionRuleProperties(tcProduct, unitNumber, effectivityDate.isNow() ? null : effectivityDate.getDateTime()); + + TcRevisionRule revisionRule = session.findRevRule(report.getRevisionRule()); + TcRevisionRulesConfiguration revRulesConfiguration = new TcRevisionRulesConfiguration(revisionRule, revisionRuleProperties); + + IStructureServiceCaller service; + if (MonoMulti.MONO.equals(report.getMonoMulti())) { + service = new TripleStructureServiceCaller(session); + } else { + service = new MultiStructureServiceCaller(session); + } + + TcBomWindowConfiguration tcBomWindowConfiguration ; + if (report.isSuperModelBOM()) { + PSBOMView modelBom = productObjectRevision.bomViewRev(); + tcBomWindowConfiguration = new TcBomWindowConfiguration (topLineObject,modelBom,revRulesConfiguration); + } else { + tcBomWindowConfiguration = new TcBomWindowConfiguration(topLineObject, revRulesConfiguration); + } + + + try (TcBomWindow bomWindow = session.createBomWindow(tcBomWindowConfiguration)) { + session.setObjectPropPolicy(report.getFullPolicy()); + + BOMLineHolder unbuiltTopLine = service.resolve(bomWindow.topLine(), ACCEPT_ALL); + List itemRevMaster = unbuiltTopLine.getAllItemRevMasters(); + session.loadProperties(itemRevMaster.toArray(new ModelObject[itemRevMaster.size()])); + + BOMLineHolderFactory.buildTopBom(session, unbuiltTopLine, ACCEPT_ALL); + DefaultAltOrDetBehaviour aBOMLineHolderProcessor = new DefaultAltOrDetBehaviour<>(session, effectivityDate.isNow() ? null : effectivityDate.getDateTime()); + unbuiltTopLine.process(aBOMLineHolderProcessor); + PrintParameters printParameters = report.subReportParameters(); + unbuiltTopLine.freeze(); + + new R23Visitor(unitNumber).constructDataMaps(session, printParameters, unbuiltTopLine); + + LOGGER.debug("PrepareData ended on: {}", report.getReportIdentifier().getReportTitle()); + return printParameters; + } + catch (EmptyNomenclatureException e) { + switch (report.getGeneric().getType()) { + case GENERIC: + case GENERIC_ASSEMB: + throw new KurtException("Empty Bom for Unit " + unitNumber, e); + default: + throw new KurtException("The TC Nomenclature Resolution returned null", e); + } + } + finally { + session.emptyPolicy(); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/ExecutionR23.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/ExecutionR23.java new file mode 100644 index 0000000..b4e6ccc --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/ExecutionR23.java @@ -0,0 +1,259 @@ +package com.capgemini.reports.definition.r23report; + +import com.capgemini.framework.common.*; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.builder.R23Builder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.exceptions.FileLoadingException; +import com.capgemini.reports.exceptions.ReportPrintException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.printing.Printer; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.reports.parameters.*; +import com.capgemini.reports.reports.parameters.Generics.GenericType; +import com.capgemini.reports.reports.parameters.checker.*; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +/** + * Obtain data for report R23.
+ * Contain {@link IChecker} for a report's construction + */ +@Getter +@EqualsAndHashCode(callSuper = true) +public class ExecutionR23 extends AbstractExecutionReport { + /** + * Policy for inspecting Alternates and DETs more closely (i.e. looking into their pseudo-folders for alternative parts). + */ + public static final PolicyLocation R23_POLICY_XML_ALT = PolicyLocation.make("R23_policy_alt", "/xml/policies/r23report/R23_policy_alt.xml"); + private static final long serialVersionUID = -1413103619999188847L; + private static final Logger LOGGER = LoggerFactory.getLogger(ExecutionR23.class); + private static final DataReportPreparatorR23 DATA_REPORT_PREPARATOR_R23 = new DataReportPreparatorR23(); + // Policies parameters + private static final PolicyLocation R23_POLICY_XML_LIGHT = PolicyLocation.make("R23_policy_light", "/xml/policies/r23report/R23_policy_light.xml"); + private static final PolicyLocation R23_POLICY_XML_FULL = PolicyLocation.make("R23_policy_full", "/xml/policies/r23report/R23_policy_full.xml"); + // Launch type parameter + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R23"); + + // Revision rule parameter + private static final String REPORT_REVISION_RULE = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R23", DEFAULT_REVISION_RULE); + + // Priority parameter + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R23); + + private static final String FILE_SEPARATOR = "_"; + private static final String PATTERN_DATE = "dd-MM-yyyy"; + + // Internal working data + private final Generics generic; + private final MonoMulti monoMulti; + private final ProductUnit productUnit; + private final EffectivityDate effectivityDate; + private final boolean isSuperModelBOM; + private final boolean isWithFrozenUnit; + private final ProductUnit productUnitForUnit; + private final ProductUnit productUnitFromUnit; + private final String nbDaysSinceFrozenStr; + + + @Setter + private BOMLineHolder topLine; + private String productLine; + private String unitRevision; + private boolean isFrozenUnit = false; + + /** + * Constructor. + * + * @param aProductUnit {@link ProductUnit} - the product + * @param aGeneric le generic {@link Generics} - represent the generic. Can be null if the wanted configuration is only with the Product and the Unit. + * @param aMonoMulti {@link MonoMulti} - represent the type of resolution structure + * @param effectivityDate {@link EffectivityDate} - represent the effectivity date + * @param isSuperModelBOM boolean + * @param isWithFrozenUnit boolean. If true ask to include frozen units + * @param productUnitForUnit {@link ProductUnit} - the product and unit. Can be null if the wanted configuration is only with the Product + * @param productUnitFromUnit {@link ProductUnit} - the product and from_unit. Can be null if the wanted configuration is only with the Product or only with one unit + * @param nbDaysSinceFrozen nb of days since frozen status set on unit. + */ + + public ExecutionR23(final ProductUnit aProductUnit, final Generics aGeneric, final MonoMulti aMonoMulti, final EffectivityDate effectivityDate, final boolean isSuperModelBOM, final boolean isWithFrozenUnit, final ProductUnit productUnitForUnit, final ProductUnit productUnitFromUnit, final String nbDaysSinceFrozen) { + super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE); + this.productUnit = aProductUnit; + this.generic = aGeneric; + this.monoMulti = aMonoMulti; + this.effectivityDate = effectivityDate; + this.isSuperModelBOM = isSuperModelBOM; + this.isWithFrozenUnit = isWithFrozenUnit; + this.productUnitForUnit = productUnitForUnit; + this.productUnitFromUnit = productUnitFromUnit; + this.nbDaysSinceFrozenStr = nbDaysSinceFrozen; + } + + @Override + public List getLaunchData() { + List theCriteria = new ArrayList<>(); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PRODUCT, productUnit.getProductID())); + if (generic.getType() == GenericType.GENERIC) { + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC, generic.getID())); + } + if (generic.getType() == GenericType.GENERIC_ASSEMB) { + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC_ASSEMB, generic.getID())); + } + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.MONO_MULTI, monoMulti.toString())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.SUPERMODEL, Boolean.toString(isSuperModelBOM))); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.EFFECTIVITY_DATE, effectivityDate.formatAsInputCriteria())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.WITH_FROZEN_UNIT, Boolean.toString(isWithFrozenUnit))); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.UNIT, productUnitForUnit.getUnitStr())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.FROM_UNIT, productUnitFromUnit.getUnitStr())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.UNITS_FROZEN_SINCE_LESS_THAN, nbDaysSinceFrozenStr)); + + return theCriteria; + } + + @Override + public String getSpecifiedFileName() { + StringBuilder builder = new StringBuilder("R23").append(FILE_SEPARATOR); + if (generic.getType() != GenericType.ONLY_PRODUCT) { + builder.append(generic.getID()).append(FILE_SEPARATOR); + } + builder.append(productUnit.getProductID()).append(FILE_SEPARATOR); + builder.append(productLine.replaceAll(StringHelper.REGEXP_ALPHANUM, " ")).append(FILE_SEPARATOR); + builder.append(TeamcenterDateFormatter.formatCalendarToPattern(Calendar.getInstance(), PATTERN_DATE)).append(FILE_SEPARATOR); + builder.append(monoMulti.toString()); + return builder.toString(); + } + + /** + * Returns the file name as it will be saved to disc locally. + * FEB459 added unit revision and GELE suffix + * + * @return the file name + */ + private String getSubReportFileName() { + StringBuilder builder = new StringBuilder("R23").append(FILE_SEPARATOR); + if (generic.getType() != GenericType.ONLY_PRODUCT) { + builder.append(generic.getID()).append(FILE_SEPARATOR); + } + builder.append(productUnit.getProductID()).append(FILE_SEPARATOR); + builder.append(productLine.replaceAll(StringHelper.REGEXP_ALPHANUM, " ")).append(FILE_SEPARATOR); + builder.append(productUnit.getUnitStr()).append(FILE_SEPARATOR); + builder.append(unitRevision).append(FILE_SEPARATOR); + builder.append(TeamcenterDateFormatter.formatCalendarToPattern(Calendar.getInstance(), PATTERN_DATE)).append(FILE_SEPARATOR); + builder.append(monoMulti.toString()); + if(isFrozenUnit) { + builder.append(FILE_SEPARATOR).append("GELE"); + } + return builder.toString(); + } + + @Override + public Printer getPrinter() { + return new Printer(Printer.AvailablePrinter.ZIP); + } + + @Override + public PrintFormat getPrintingFormat() { + return PrintFormat.XLSX; + } + + @Override + public ReportEnum getReportIdentifier() { + return ReportEnum.REPORT_R23; + } + + @Override + public List getQuickChecks() { + List quickChecks = new ArrayList<>(); + quickChecks.add(new GenericExistenceChecker(generic)); + quickChecks.add(new ProductChecker(productUnit.getProductID())); + quickChecks.add(new EffectivityChecker(effectivityDate)); + if(!productUnitForUnit.getUnitStr().isEmpty()) { // If a Unit is filled -> check product/unit correspondance + quickChecks.add(new ProductUnitChecker(productUnitForUnit)); + } + return quickChecks; + } + + @Override + public List getLongChecks() { + List longChecks = new ArrayList<>(); + longChecks.add(new GenericUnderProductUnitChecker(generic)); + return longChecks; + } + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R23_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R23_POLICY_XML_FULL; + } + + @Override + public String getTemplateLocation() { + return JasperTemplate.TEMPLATE_R23.getFilepath(); + } + + @Override + public IDataReportPreparator getDataPreparator() { + return DATA_REPORT_PREPARATOR_R23; + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return new ExecutionR23(productUnit, generic, monoMulti, effectivityDate, isSuperModelBOM, isWithFrozenUnit, productUnitForUnit, productUnitFromUnit, nbDaysSinceFrozenStr); + } + + @Override + public Class getReportBuilderClass() { + return R23Builder.class; + } + + public PrintParameters reportParameters() { + return new PrintParameters(Printer.PrintFormat.ZIP, getFileNameOnDisc(), ReportFolderOutputHelper.getStorageFolderLocation(getLaunchType())); + } + + public PrintParameters subReportParameters() throws ReportPrintException, FileLoadingException { + String storageFolder = ReportFolderOutputHelper.getStorageFolderLocation(getLaunchType()); + String templateLocation = getTemplateLocation(); + try (InputStream templateStream = ResourceHelper.getResourceAsStream(templateLocation)) { + PrintParameters printParameters = PrintParameters.createMainReport(getPrintingFormat(), getSubReportFileName(), storageFolder, templateStream); + printParameters.setReportTitle(getReportIdentifier().getReportTitle()); + return printParameters; + } + catch (IOException e) { + LOGGER.error("Unable to close the template file properly from " + templateLocation, e); + return null; // IOException is only thrown by close() which, if it ever fails, means you have much bigger problems! + } + } + + public void setProductLine(String productLine) { + this.productLine = productLine; + } + + public void setUnitRevision(String unitRevision) { + this.unitRevision = unitRevision; + } + + public void setFrozenUnit(boolean frozenUnit) { + isFrozenUnit = frozenUnit; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/visitors/R23Visitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/visitors/R23Visitor.java new file mode 100644 index 0000000..b030d43 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/visitors/R23Visitor.java @@ -0,0 +1,121 @@ +package com.capgemini.reports.definition.r23report.visitors; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.definition.r23report.ExecutionR23; +import com.capgemini.reports.definition.r23report.visitors.bomlineholder.R23BOMLineHolderVisitor; +import com.capgemini.reports.execution.mapconstructor.AbstractStaticTemplateMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.reports.IReportVisitor; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +/** + * Visit a R23 report. + */ +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class R23Visitor extends AbstractStaticTemplateMapConstructor implements IReportVisitor { + private static final long serialVersionUID = 3013480234676995245L; + + private static final String NULL = ""; + private static final String EMPTY = ""; + + protected final R23BOMLineHolderVisitor r23BOMLineHolderVisitor = new R23BOMLineHolderVisitor(); + private final int unitNumber; + + /** + * Constructor. + */ + public R23Visitor(final int unitNumber) { + this.unitNumber = unitNumber; + } + + private static String check(final Object anInput) { + return anInput == null ? NULL : anInput.toString(); + } + + /** + * Translate the specific result of the visitor into something the printer can understand. + */ + private List> translate(final List> visitorMaps) { + // Add empty fields in the first line + Map firstLine = visitorMaps.get(0); + // Empty receptor + firstLine.put(R23VisitorKeys.UNIT_NUM, String.valueOf(unitNumber)); + firstLine.put(R23VisitorKeys.IDENTIFIANT_RECEPTEUR, EMPTY); + firstLine.put(R23VisitorKeys.REVISION_RECEPTEUR, EMPTY); + firstLine.put(R23VisitorKeys.NOM_RECEPTEUR, EMPTY); + // Empty RF + firstLine.put(R23VisitorKeys.REPERE_FONCTIONNEL, EMPTY); + firstLine.put(R23VisitorKeys.REVISION_REPERE_FONCTIONNEL, EMPTY); + firstLine.put(R23VisitorKeys.IDENTIFIANT_REPERE_FONCTIONNEL, EMPTY); + firstLine.put(R23VisitorKeys.MAQUETTE, EMPTY); + firstLine.put(R23VisitorKeys.TRANSFERT_LIEN_LOGISTIQUE, EMPTY); + firstLine.put(R23VisitorKeys.TRANSFERT_LIEN_MONTAGE, EMPTY); + firstLine.put(R23VisitorKeys.UIN, EMPTY); + firstLine.put(R23VisitorKeys.EQUIVALENT_SNSSIN, EMPTY); + firstLine.put(R23VisitorKeys.RESPONSABLE_REPERE, EMPTY); + firstLine.put(R23VisitorKeys.SUIVI_MONTAGE, EMPTY); + firstLine.put(R23VisitorKeys.IDENTIFIANT_RF_ADMIN, EMPTY); + firstLine.put(R23VisitorKeys.REVISION_RF_ADMIN, EMPTY); + firstLine.put(R23VisitorKeys.IDENTIFIANT_RF_ADMIN_AP, EMPTY); + firstLine.put(R23VisitorKeys.REVISION_RF_ADMIN_AP, EMPTY); + firstLine.put(R23VisitorKeys.FRONTIERE_AVION, EMPTY); + firstLine.put(R23VisitorKeys.FRONTIERE_COOPERANT, EMPTY); + firstLine.put(R23VisitorKeys.GEOMETRIE_PIECE_RIGIDE, EMPTY); + firstLine.put(R23VisitorKeys.GEOMETRIE_SIMPLIFIE_RIGIDE, EMPTY); + firstLine.put(R23VisitorKeys.ENVELOPPE_DE_CINEMATIQUE, EMPTY); + firstLine.put(R23VisitorKeys.ENVELOPPE_DE_MAINTENANCE, EMPTY); + firstLine.put(R23VisitorKeys.ENVELOPPE_DE_MONTAGE_DEMONTAGE, EMPTY); + firstLine.put(R23VisitorKeys.TRACE_AXIALE, EMPTY); + firstLine.put(R23VisitorKeys.INTERFACE, EMPTY); + firstLine.put(R23VisitorKeys.PROJECT_MOTEUR, EMPTY); + firstLine.put(R23VisitorKeys.MAQUETTE_ECHANGEABLE, EMPTY); + firstLine.put(R23VisitorKeys.WORKPACKAGE, EMPTY); + // Empty BOM + firstLine.put(R23VisitorKeys.ALT, EMPTY); + firstLine.put(R23VisitorKeys.SB, EMPTY); + firstLine.put(R23VisitorKeys.QUANTITE_CUMULEE, EMPTY); + firstLine.put(R23VisitorKeys.PANACHE, EMPTY); + firstLine.put(R23VisitorKeys.QUANTITE, EMPTY); + + // Construct the map list expected by the printer + List> printerMaps = new ArrayList<>(); + for (Map visitorMap : visitorMaps) { + Map printerMap = new HashMap<>(); + for (R23VisitorKeys key : R23VisitorKeys.values()) { + printerMap.put(key.toString(), check(visitorMap.get(key))); + } + printerMaps.add(printerMap); + } + + return printerMaps; + } + + @Override + public List> visitReport(final BOMLineHolder holder) { + List> visitorMaps = r23BOMLineHolderVisitor.visitTopReceptorBom(holder); + return translate(visitorMaps); + } + + @Override + public void constructDataMaps(TcSession session, final PrintParameters printParameters, final BOMLineHolder data) throws KurtException { + long start = System.currentTimeMillis(); + if (data == null) { + throw new NoSuchElementException("No Product structure found"); + } + + // Parse all the snecma objects... + List> printerMaps = this.visitReport(data); + printParameters.addReportData(printerMaps); + log.info("Filtering time : {} ms", System.currentTimeMillis() - start); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/visitors/R23VisitorKeys.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/visitors/R23VisitorKeys.java new file mode 100644 index 0000000..99fd70a --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/visitors/R23VisitorKeys.java @@ -0,0 +1,63 @@ +package com.capgemini.reports.definition.r23report.visitors; + +/** + * Enumeration of all the columns of the R23 report. + */ +public enum R23VisitorKeys { + IDENTIFIANT_RECEPTEUR, + REVISION_RECEPTEUR, + NOM_RECEPTEUR, + REPERE_FONCTIONNEL, + REVISION_REPERE_FONCTIONNEL, + UIN, + EQUIVALENT_SNSSIN, + RESPONSABLE_REPERE, + SUIVI_MONTAGE, + ALT, + SB, + QUANTITE_CUMULEE, + PANACHE, + QUANTITE, + REF_FABRICANT_REF_SNECMA, + REVISION_REFERENCE, + REFERENCE_CONCEPTEUR, + TYPE_REFERENCE, + NOM_REFERENCE, + DESIGNATION_EN, + REFERENCE_TRANSPOSEE, + RESPONSABLE_CONCEPTION, + ALTERNATIVE, + CLASSEMENT, + SUIVI_UTILISATION, + SUIVI_DUREE_VIE, + MASSE_INDICATIVE, + UNITE_DE_MASSE, + IDENTIFIANT_REPERE_FONCTIONNEL, + MAQUETTE, + TRANSFERT_LIEN_LOGISTIQUE, + TRANSFERT_LIEN_MONTAGE, + STATUT_REFERENCE_ARTICLE, + SUIVI_DEVELOPPEMENT, + TYPE_PRODUIT, + DOCUMENT_CONTROLE, + OBTURATION, + IDENTIFIANT_RF_ADMIN, + REVISION_RF_ADMIN, + IDENTIFIANT_RF_ADMIN_AP, + REVISION_RF_ADMIN_AP, + FRONTIERE_AVION, + FRONTIERE_COOPERANT, + GEOMETRIE_PIECE_RIGIDE, + GEOMETRIE_SIMPLIFIE_RIGIDE, + ENVELOPPE_DE_CINEMATIQUE, + ENVELOPPE_DE_MAINTENANCE, + ENVELOPPE_DE_MONTAGE_DEMONTAGE, + TRACE_AXIALE, + INTERFACE, + PROJECT_MOTEUR, + MAQUETTE_ECHANGEABLE, + WORKPACKAGE, + UNIT_NUM, + CR, + CN +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/visitors/bomlineholder/R23AltOrDetBehaviour.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/visitors/bomlineholder/R23AltOrDetBehaviour.java new file mode 100644 index 0000000..489aab7 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/visitors/bomlineholder/R23AltOrDetBehaviour.java @@ -0,0 +1,77 @@ +package com.capgemini.reports.definition.r23report.visitors.bomlineholder; + +import com.capgemini.reports.bomlineholder.processor.AltOrDetBehaviour; +import com.capgemini.reports.definition.r23report.visitors.R23VisitorKeys; +import com.capgemini.reports.snecmaobjects.part.AlternateRevision; +import com.capgemini.reports.snecmaobjects.part.DETRevision; + +import java.util.Map; + +/** + * This class visits Parts that are below an {@link AlternateRevision} or a {@link DETRevision}.
+ * It puts "Oui" in the ALTERNATIVE field of a map. + */ +public class R23AltOrDetBehaviour implements AltOrDetBehaviour { + private static final long serialVersionUID = -7332694328622575681L; + + private static final String OUI = "Oui"; + private static final String EMPTY_STRING = ""; + + @Override + public boolean shouldVisitPartsInPseudoFolder() { + return true; + } + + @Override + public boolean shouldVisitPartsBelowAlt() { + return true; + } + + @Override + public void treatPartsInPseudoFolder(final Map map) { + treatAnyPartBelowThisAltOrDet(map); + } + + @Override + public void treatAlternateOrDETAsReceptor(final Map map) { + treatAnyPartBelowThisAltOrDet(map); + } + + private void treatAnyPartBelowThisAltOrDet(final Map map) { + // Empty fields + map.put(R23VisitorKeys.REPERE_FONCTIONNEL, EMPTY_STRING); + map.put(R23VisitorKeys.IDENTIFIANT_REPERE_FONCTIONNEL, EMPTY_STRING); + map.put(R23VisitorKeys.REVISION_REPERE_FONCTIONNEL, EMPTY_STRING); + map.put(R23VisitorKeys.MAQUETTE, EMPTY_STRING); + map.put(R23VisitorKeys.UIN, EMPTY_STRING); + map.put(R23VisitorKeys.EQUIVALENT_SNSSIN, EMPTY_STRING); + map.put(R23VisitorKeys.RESPONSABLE_REPERE, EMPTY_STRING); + map.put(R23VisitorKeys.TRANSFERT_LIEN_LOGISTIQUE, EMPTY_STRING); + map.put(R23VisitorKeys.TRANSFERT_LIEN_MONTAGE, EMPTY_STRING); + map.put(R23VisitorKeys.SUIVI_MONTAGE, EMPTY_STRING); + map.put(R23VisitorKeys.IDENTIFIANT_RF_ADMIN, EMPTY_STRING); + map.put(R23VisitorKeys.REVISION_RF_ADMIN, EMPTY_STRING); + map.put(R23VisitorKeys.IDENTIFIANT_RF_ADMIN_AP, EMPTY_STRING); + map.put(R23VisitorKeys.REVISION_RF_ADMIN_AP, EMPTY_STRING); + map.put(R23VisitorKeys.FRONTIERE_AVION, EMPTY_STRING); + map.put(R23VisitorKeys.FRONTIERE_COOPERANT, EMPTY_STRING); + map.put(R23VisitorKeys.GEOMETRIE_PIECE_RIGIDE, EMPTY_STRING); + map.put(R23VisitorKeys.GEOMETRIE_SIMPLIFIE_RIGIDE, EMPTY_STRING); + map.put(R23VisitorKeys.ENVELOPPE_DE_CINEMATIQUE, EMPTY_STRING); + map.put(R23VisitorKeys.ENVELOPPE_DE_MAINTENANCE, EMPTY_STRING); + map.put(R23VisitorKeys.ENVELOPPE_DE_MONTAGE_DEMONTAGE, EMPTY_STRING); + map.put(R23VisitorKeys.TRACE_AXIALE, EMPTY_STRING); + map.put(R23VisitorKeys.INTERFACE, EMPTY_STRING); + map.put(R23VisitorKeys.PROJECT_MOTEUR, EMPTY_STRING); + map.put(R23VisitorKeys.MAQUETTE_ECHANGEABLE, EMPTY_STRING); + map.put(R23VisitorKeys.WORKPACKAGE, EMPTY_STRING); + map.put(R23VisitorKeys.ALT, EMPTY_STRING); + map.put(R23VisitorKeys.SB, EMPTY_STRING); + map.put(R23VisitorKeys.QUANTITE_CUMULEE, EMPTY_STRING); + map.put(R23VisitorKeys.PANACHE, EMPTY_STRING); + map.put(R23VisitorKeys.QUANTITE, EMPTY_STRING); + + // Mention that these parts are alternatives to each other + map.put(R23VisitorKeys.ALTERNATIVE, OUI); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/visitors/bomlineholder/R23BOMLineHolderVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/visitors/bomlineholder/R23BOMLineHolderVisitor.java new file mode 100644 index 0000000..5834594 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/visitors/bomlineholder/R23BOMLineHolderVisitor.java @@ -0,0 +1,83 @@ +package com.capgemini.reports.definition.r23report.visitors.bomlineholder; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.visitor.AbstractBOMLineHolderVisitor; +import com.capgemini.reports.definition.r23report.visitors.R23VisitorKeys; +import com.capgemini.reports.definition.r23report.visitors.snecmaobject.R23ComponentVisitor; +import com.capgemini.reports.definition.r23report.visitors.snecmaobject.R23ReceptorVisitor; +import com.capgemini.reports.releasestatus.EffectivityBehaviourHelper; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.Map; + +/** + * Visitor of an expansion of BOMLineHolder for the R23 report. + */ +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class R23BOMLineHolderVisitor extends AbstractBOMLineHolderVisitor { + private static final long serialVersionUID = -3036778839181191276L; + + public R23BOMLineHolderVisitor() { + super(new R23ReceptorVisitor(), new R23ComponentVisitor(), EffectivityBehaviourHelper.visitOnlyUnitManagedParts(), + new R23AltOrDetBehaviour(), false, true, false); + } + + @Override + protected Map visitThisReceptor(final BOMLineHolder aBomLine) { + return aBomLine.getSnecmaObject().accept(receptorVisitor); + } + + @Override + protected Map visitThisComponent(final BOMLineHolder aBomLine) { + Map aMap = aBomLine.getSnecmaObject().accept(componentVisitor); + + // Put the BOMLine properties into the map + if ((aBomLine.getSnecmaObject().isGeneric()) || (aBomLine.getSnecmaObject().isPart() || (aBomLine.getSnecmaObject().isSuperModel()))) { + aMap.put(R23VisitorKeys.ALT, aBomLine.getBomAlt()); + aMap.put(R23VisitorKeys.SB, aBomLine.getBomSb()); + aMap.put(R23VisitorKeys.QUANTITE_CUMULEE, aBomLine.getBomQtyCumul()); + aMap.put(R23VisitorKeys.PANACHE, aBomLine.getBomPanache()); + aMap.put(R23VisitorKeys.QUANTITE, aBomLine.getBomQty()); + aMap.put(R23VisitorKeys.UIN, aBomLine.getUin()); + } + return aMap; + } + + @Override + protected void visitSpecificFirstLine(final BOMLineHolder aTopBomLine) { + Map theFirstLine = aTopBomLine.getSnecmaObject().accept(getComponentVisitor()); + theReportTable.add(theFirstLine); + } + + @Override + protected void mergeReceptorAndRepereReceptor(final Map aReceptor, final Map aRepereReceptor) { + aReceptor.putAll(aRepereReceptor); + } + + @Override + protected void mergeComponentAndRepereComponent(final Map aComponent, final Map aRepereComponent) { + aComponent.putAll(aRepereComponent); + } + + @Override + protected void mergeRepereReceptorandAdmin(final Map aRepereReceptor, final Map anAdmin) { + aRepereReceptor.putAll(anAdmin); + } + + @Override + protected void mergeRepereComponentandAdmin(final Map aRepereComponent, final Map anAdmin) { + aRepereComponent.putAll(anAdmin); + } + + @Override + protected void addToReport(final Map aReceptor, final Map aComponent) { + // Put the Receptor and Repere Receptor in the Component and modify the Component + // Do not modify the receptor + aComponent.putAll(aReceptor); + + // Add to the R21 report + theReportTable.add(aComponent); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/visitors/snecmaobject/R23ComponentVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/visitors/snecmaobject/R23ComponentVisitor.java new file mode 100644 index 0000000..2cd599a --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/visitors/snecmaobject/R23ComponentVisitor.java @@ -0,0 +1,407 @@ +package com.capgemini.reports.definition.r23report.visitors.snecmaobject; + +import com.capgemini.framework.common.DoubleFormatter; +import com.capgemini.framework.common.LanguageHelper; +import com.capgemini.framework.teamcenter.object.pom.status.TcReleaseStatus; +import com.capgemini.reports.definition.r23report.visitors.R23VisitorKeys; +import com.capgemini.reports.snecmaobjects.AbstractSnecmaObject; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAGRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision; +import com.capgemini.reports.snecmaobjects.generic.AbstractGenericRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericAssembRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.mockup.MockupRevision; +import com.capgemini.reports.snecmaobjects.part.*; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.snecmaobjects.rf.AbstractRF; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartAssembRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartRevision; +import com.capgemini.reports.snecmaobjects.supermodel.AbstractSuperModelRevision; +import com.capgemini.reports.snecmaobjects.supermodel.SuperModelRevision; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; + +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +/** + * Visit a Component SnecmaObject to make a R23 report. + */ +public class R23ComponentVisitor implements IComponentVisitor> { + private static final long serialVersionUID = 7703811551227059716L; + + private static final int MASS_SIGNIFICANT_DIGITS = 15; + private static final String EMPTY_STRING = ""; + private static final String PART_MAT = "PartMat"; + private static final String SEPARATOR = " / "; + private static final String VALUE_MATIERE = "matière"; + private static final String PRODUIT = "Produit"; + private static final String GENERIQUE_MONTAGE = "Générique Montage"; + private static final String GENERIQUE = "Générique"; + private static final String SUPERMODEL = "Super Model"; + private static final String PARAM_NON = "Non"; + private static final String PARAM_OUI = "Oui"; + + private static String french(final String string) { + return LanguageHelper.french(string); + } + + @Override + public Map visitComponent(final ProductRevision aProductRev) { + Map theMap = getAbstractSnecmaObjectProperties(aProductRev); + theMap.put(R23VisitorKeys.DESIGNATION_EN, aProductRev.getDesignationEN()); + theMap.put(R23VisitorKeys.TYPE_PRODUIT, aProductRev.getTypeProduit()); + theMap.put(R23VisitorKeys.TYPE_REFERENCE, PRODUIT); + theMap.put(R23VisitorKeys.SUIVI_UTILISATION, PARAM_NON); + theMap.put(R23VisitorKeys.SUIVI_DUREE_VIE, PARAM_NON); + theMap.put(R23VisitorKeys.REFERENCE_CONCEPTEUR, EMPTY_STRING); + theMap.put(R23VisitorKeys.REFERENCE_TRANSPOSEE, EMPTY_STRING); + theMap.put(R23VisitorKeys.RESPONSABLE_CONCEPTION, EMPTY_STRING); + theMap.put(R23VisitorKeys.MASSE_INDICATIVE, EMPTY_STRING); + theMap.put(R23VisitorKeys.UNITE_DE_MASSE, EMPTY_STRING); + theMap.put(R23VisitorKeys.STATUT_REFERENCE_ARTICLE, statutReferenceArticle(aProductRev.getStatusList())); + theMap.put(R23VisitorKeys.CLASSEMENT, "-"); + theMap.put(R23VisitorKeys.ALTERNATIVE, EMPTY_STRING); + theMap.put(R23VisitorKeys.SUIVI_DEVELOPPEMENT, EMPTY_STRING); + theMap.put(R23VisitorKeys.DOCUMENT_CONTROLE, EMPTY_STRING); + theMap.put(R23VisitorKeys.OBTURATION, EMPTY_STRING); + + return theMap; + } + + private String statutReferenceArticle(final List statuses) { + StringBuilder builder = new StringBuilder(); + int size = statuses.size(); + for (int i = 0; i < size; i++) { + builder.append(statuses.get(i).getDisplayableName()); + if (i != size - 1) { + builder.append(", "); + } + } + return builder.toString(); + } + + @Override + public Map visitComponent(final GenericRevision aGenericRev) { + Map theMap = getAbstractSnecmaObjectProperties(aGenericRev); + theMap.put(R23VisitorKeys.TYPE_REFERENCE, GENERIQUE); + putGenericProperties(theMap, aGenericRev); + return theMap; + } + + @Override + public Map visitComponent(final GenericAssembRevision aGenericAssembRev) { + Map theMap = getAbstractSnecmaObjectProperties(aGenericAssembRev); + theMap.put(R23VisitorKeys.TYPE_REFERENCE, GENERIQUE_MONTAGE); + putGenericProperties(theMap, aGenericAssembRev); + return theMap; + } + + @Override + public Map visitComponent(final SuperModelRevision aSuperModelRev) { + Map theMap = getAbstractSnecmaObjectProperties(aSuperModelRev); + theMap.put(R23VisitorKeys.TYPE_REFERENCE, GENERIQUE); + putSuperModelProperties(theMap, aSuperModelRev); + return theMap; + } + + @Override + public Map visitComponent(final AlternateRevision anAlternateRev) { + Map theMap = getAbstractSnecmaObjectProperties(anAlternateRev); + putPartProperties(theMap, anAlternateRev); + theMap.put(R23VisitorKeys.TYPE_REFERENCE, french(anAlternateRev.getTypeAlt1()) + SEPARATOR + french(anAlternateRev.getTypeAlt2())); + theMap.put(R23VisitorKeys.SUIVI_DEVELOPPEMENT, french(anAlternateRev.getSuiviDeveloppement())); + theMap.put(R23VisitorKeys.DOCUMENT_CONTROLE, french(anAlternateRev.getDocumentControle())); + theMap.put(R23VisitorKeys.OBTURATION, french(anAlternateRev.getObturation())); + return theMap; + } + + @Override + public Map visitComponent(final DETRevision aDetRev) { + Map theMap = getAbstractSnecmaObjectProperties(aDetRev); + putPartProperties(theMap, aDetRev); + theMap.put(R23VisitorKeys.TYPE_REFERENCE, french(aDetRev.getTypeDet1()) + SEPARATOR + french(aDetRev.getTypeDet2())); + theMap.put(R23VisitorKeys.SUIVI_DEVELOPPEMENT, french(aDetRev.getSuiviDeveloppement())); + theMap.put(R23VisitorKeys.DOCUMENT_CONTROLE, french(aDetRev.getDocumentControle())); + theMap.put(R23VisitorKeys.OBTURATION, french(aDetRev.getObturation())); + return theMap; + } + + @Override + public Map visitComponent(final PartAeroRevision aPartAeroRev) { + Map theMap = getAbstractSnecmaObjectProperties(aPartAeroRev); + putPartProperties(theMap, aPartAeroRev); + theMap.put(R23VisitorKeys.TYPE_REFERENCE, french(aPartAeroRev.getTypeAero1()) + SEPARATOR + french(aPartAeroRev.getTypeAero2()) + SEPARATOR + french(aPartAeroRev.getTypeAero3())); + theMap.put(R23VisitorKeys.SUIVI_DEVELOPPEMENT, french(aPartAeroRev.getSuiviDeveloppement())); + theMap.put(R23VisitorKeys.DOCUMENT_CONTROLE, french(aPartAeroRev.getDocumentControle())); + theMap.put(R23VisitorKeys.OBTURATION, french(aPartAeroRev.getObturation())); + return theMap; + } + + @Override + public Map visitComponent(final PartNoAeroRevision aPartNoAeroRev) { + Map theMap = getAbstractSnecmaObjectProperties(aPartNoAeroRev); + putPartProperties(theMap, aPartNoAeroRev); + theMap.put(R23VisitorKeys.TYPE_REFERENCE, french(aPartNoAeroRev.getTypeNoAero())); + theMap.put(R23VisitorKeys.SUIVI_DEVELOPPEMENT, french(aPartNoAeroRev.getSuiviDeveloppement())); + theMap.put(R23VisitorKeys.DOCUMENT_CONTROLE, french(aPartNoAeroRev.getDocumentControle())); + theMap.put(R23VisitorKeys.OBTURATION, EMPTY_STRING); + return theMap; + } + + @Override + public Map visitComponent(final PartAssembRevision aPartAssembRev) { + Map theMap = getAbstractSnecmaObjectProperties(aPartAssembRev); + putPartProperties(theMap, aPartAssembRev); + theMap.put(R23VisitorKeys.TYPE_REFERENCE, french(aPartAssembRev.getTypePartMontage1()) + SEPARATOR + french(aPartAssembRev.getTypePartMontage2())); + theMap.put(R23VisitorKeys.SUIVI_DEVELOPPEMENT, EMPTY_STRING); + theMap.put(R23VisitorKeys.DOCUMENT_CONTROLE, french(aPartAssembRev.getDocumentControle())); + theMap.put(R23VisitorKeys.OBTURATION, EMPTY_STRING); + return theMap; + } + + @Override + public Map visitComponent(final PartMatRevision aPartMatRev) { + Map theMap = getAbstractSnecmaObjectProperties(aPartMatRev); + putPartProperties(theMap, aPartMatRev); + theMap.put(R23VisitorKeys.TYPE_REFERENCE, VALUE_MATIERE); + theMap.put(R23VisitorKeys.CLASSEMENT, aPartMatRev.getClassementMat()); + theMap.put(R23VisitorKeys.SUIVI_UTILISATION, PARAM_NON); + theMap.put(R23VisitorKeys.SUIVI_DUREE_VIE, PARAM_NON); + theMap.put(R23VisitorKeys.SUIVI_DEVELOPPEMENT, EMPTY_STRING); + theMap.put(R23VisitorKeys.DOCUMENT_CONTROLE, EMPTY_STRING); + theMap.put(R23VisitorKeys.OBTURATION, EMPTY_STRING); + return theMap; + } + + @Override + public Map visitComponent(final StandardRevision aStandardRev) { + Map theMap = getAbstractSnecmaObjectProperties(aStandardRev); + putPartProperties(theMap, aStandardRev); + theMap.put(R23VisitorKeys.TYPE_REFERENCE, french(aStandardRev.getTypeStandard())); + theMap.put(R23VisitorKeys.SUIVI_DEVELOPPEMENT, french(aStandardRev.getSuiviDeveloppement())); + theMap.put(R23VisitorKeys.DOCUMENT_CONTROLE, french(aStandardRev.getDocumentControle())); + theMap.put(R23VisitorKeys.OBTURATION, EMPTY_STRING); + return theMap; + } + + /** + * Get Component properties to make a R23 report. + * + * @param anAbstractSnecmaObject AbstractSnecmaObject + * @return theMap Map + */ + private Map getAbstractSnecmaObjectProperties(final AbstractSnecmaObject anAbstractSnecmaObject) { + Map theMap = new EnumMap<>(R23VisitorKeys.class); + theMap.put(R23VisitorKeys.REF_FABRICANT_REF_SNECMA, anAbstractSnecmaObject.getItemId()); + theMap.put(R23VisitorKeys.NOM_REFERENCE, anAbstractSnecmaObject.getName()); + theMap.put(R23VisitorKeys.REVISION_REFERENCE, anAbstractSnecmaObject.getRevisionId()); + theMap.put(R23VisitorKeys.ALTERNATIVE, EMPTY_STRING); + theMap.put(R23VisitorKeys.CR, anAbstractSnecmaObject.getCRPseudoFolderContentAsString()); + theMap.put(R23VisitorKeys.CN, anAbstractSnecmaObject.getCNPseudoFolderContentAsString()); + return theMap; + } + + /** + * Put the Generic properties into aMap. + * + * @param aMap Map + * @param anAbstractGenericRevision AbstractGenericRevision + */ + private void putGenericProperties(final Map aMap, final AbstractGenericRevision anAbstractGenericRevision) { + aMap.put(R23VisitorKeys.DESIGNATION_EN, anAbstractGenericRevision.getDesignationEN()); + aMap.put(R23VisitorKeys.RESPONSABLE_CONCEPTION, anAbstractGenericRevision.getResponsableConception()); + aMap.put(R23VisitorKeys.SUIVI_UTILISATION, PARAM_OUI); + aMap.put(R23VisitorKeys.SUIVI_DUREE_VIE, PARAM_NON); + aMap.put(R23VisitorKeys.REFERENCE_CONCEPTEUR, EMPTY_STRING); + aMap.put(R23VisitorKeys.REFERENCE_TRANSPOSEE, EMPTY_STRING); + aMap.put(R23VisitorKeys.MASSE_INDICATIVE, EMPTY_STRING); + aMap.put(R23VisitorKeys.UNITE_DE_MASSE, EMPTY_STRING); + aMap.put(R23VisitorKeys.STATUT_REFERENCE_ARTICLE, statutReferenceArticle(anAbstractGenericRevision.getStatusList())); + aMap.put(R23VisitorKeys.ALTERNATIVE, EMPTY_STRING); + aMap.put(R23VisitorKeys.CLASSEMENT, "-"); + aMap.put(R23VisitorKeys.TYPE_PRODUIT, EMPTY_STRING); + aMap.put(R23VisitorKeys.SUIVI_DEVELOPPEMENT, EMPTY_STRING); + aMap.put(R23VisitorKeys.DOCUMENT_CONTROLE, EMPTY_STRING); + aMap.put(R23VisitorKeys.OBTURATION, EMPTY_STRING); + } + + + /** + * Put the Super Model properties into aMap. + * + * @param aMap Map + * @param anAbstractSuperModelRevision AbstractSuperModelRevision + */ + private void putSuperModelProperties(final Map aMap, final AbstractSuperModelRevision anAbstractSuperModelRevision) { + aMap.put(R23VisitorKeys.SUIVI_UTILISATION, EMPTY_STRING); + aMap.put(R23VisitorKeys.SUIVI_DUREE_VIE, EMPTY_STRING); + aMap.put(R23VisitorKeys.REFERENCE_CONCEPTEUR, EMPTY_STRING); + aMap.put(R23VisitorKeys.REFERENCE_TRANSPOSEE, EMPTY_STRING); + aMap.put(R23VisitorKeys.MASSE_INDICATIVE, EMPTY_STRING); + aMap.put(R23VisitorKeys.UNITE_DE_MASSE, EMPTY_STRING); + aMap.put(R23VisitorKeys.TYPE_REFERENCE, french(anAbstractSuperModelRevision.getType())); + aMap.put(R23VisitorKeys.STATUT_REFERENCE_ARTICLE, statutReferenceArticle(anAbstractSuperModelRevision.getStatusList())); + aMap.put(R23VisitorKeys.ALTERNATIVE, EMPTY_STRING); + aMap.put(R23VisitorKeys.CLASSEMENT, "-"); + aMap.put(R23VisitorKeys.TYPE_PRODUIT, EMPTY_STRING); + aMap.put(R23VisitorKeys.SUIVI_DEVELOPPEMENT, EMPTY_STRING); + aMap.put(R23VisitorKeys.DOCUMENT_CONTROLE, EMPTY_STRING); + aMap.put(R23VisitorKeys.OBTURATION, EMPTY_STRING); + aMap.put(R23VisitorKeys.DESIGNATION_EN, EMPTY_STRING); + aMap.put(R23VisitorKeys.RESPONSABLE_CONCEPTION, EMPTY_STRING); + + } + + + + + + + + + /** + * Put the Part properties into aMap. + * + * @param aMap Map + * @param anAbstractPart AbstractPart + */ + private void putPartProperties(final Map aMap, final AbstractPart anAbstractPart) { + aMap.put(R23VisitorKeys.DESIGNATION_EN, anAbstractPart.getDesignationEN()); + aMap.put(R23VisitorKeys.REFERENCE_CONCEPTEUR, anAbstractPart.getRefCompleteConcepteur()); + aMap.put(R23VisitorKeys.REFERENCE_TRANSPOSEE, anAbstractPart.getRefTransposeeSnecma()); + aMap.put(R23VisitorKeys.RESPONSABLE_CONCEPTION, anAbstractPart.getResponsableConception()); + if (!PART_MAT.equals(anAbstractPart.getType())) { + aMap.put(R23VisitorKeys.CLASSEMENT, anAbstractPart.getClassement()); + aMap.put(R23VisitorKeys.SUIVI_UTILISATION, french(anAbstractPart.getSuiviUtilisation())); + aMap.put(R23VisitorKeys.SUIVI_DUREE_VIE, french(anAbstractPart.getSuiviDureeVie())); + } + aMap.put(R23VisitorKeys.MASSE_INDICATIVE, DoubleFormatter.toSignificantDigits(anAbstractPart.getMass(), MASS_SIGNIFICANT_DIGITS)); + aMap.put(R23VisitorKeys.UNITE_DE_MASSE, anAbstractPart.getMassUnit()); + aMap.put(R23VisitorKeys.STATUT_REFERENCE_ARTICLE, statutReferenceArticle(anAbstractPart.getStatusList())); + aMap.put(R23VisitorKeys.TYPE_PRODUIT, anAbstractPart.getTypeProduit()); + } + + @Override + public Map visitComponent(final RFGenericRevision aRfGenericRev) { + Map theMap = getRfProperties(aRfGenericRev); + theMap.put(R23VisitorKeys.SUIVI_MONTAGE, PARAM_NON); + return theMap; + } + + @Override + public Map visitComponent(final RFPartAssembRevision aRfPartAssembRev) { + Map theMap = new EnumMap<>(R23VisitorKeys.class); + theMap.put(R23VisitorKeys.REPERE_FONCTIONNEL, aRfPartAssembRev.getName()); + theMap.put(R23VisitorKeys.REVISION_REPERE_FONCTIONNEL, aRfPartAssembRev.getRevisionId()); + theMap.put(R23VisitorKeys.IDENTIFIANT_REPERE_FONCTIONNEL, aRfPartAssembRev.getItemId()); + theMap.put(R23VisitorKeys.EQUIVALENT_SNSSIN, EMPTY_STRING); + return theMap; + } + + @Override + public Map visitComponent(final RFPartRevision aRfPartRev) { + return getRfProperties(aRfPartRev); + } + + @Override + public Map visitComponent(final RFAdminRevision aRfAdminRev) { + Map theMap = new EnumMap<>(R23VisitorKeys.class); + theMap.put(R23VisitorKeys.MAQUETTE, french(aRfAdminRev.getMaqIntExt())); + theMap.put(R23VisitorKeys.IDENTIFIANT_RF_ADMIN, aRfAdminRev.getItemId()); + theMap.put(R23VisitorKeys.REVISION_RF_ADMIN, aRfAdminRev.getRevisionId()); + theMap.put(R23VisitorKeys.RESPONSABLE_REPERE, aRfAdminRev.getResponsableRepere()); + theMap.put(R23VisitorKeys.FRONTIERE_AVION, french(aRfAdminRev.getFrontiereAvion())); + theMap.put(R23VisitorKeys.FRONTIERE_COOPERANT, french(aRfAdminRev.getFrontiereCooperant())); + theMap.put(R23VisitorKeys.GEOMETRIE_PIECE_RIGIDE, french(aRfAdminRev.getGeometriePieceRigide())); + theMap.put(R23VisitorKeys.GEOMETRIE_SIMPLIFIE_RIGIDE, french(aRfAdminRev.getGeometrieSimplifiee())); + theMap.put(R23VisitorKeys.ENVELOPPE_DE_CINEMATIQUE, french(aRfAdminRev.getEnveloppeCinematique())); + theMap.put(R23VisitorKeys.ENVELOPPE_DE_MAINTENANCE, french(aRfAdminRev.getEnveloppeMaintenance())); + theMap.put(R23VisitorKeys.ENVELOPPE_DE_MONTAGE_DEMONTAGE, french(aRfAdminRev.getEnveloppeMontage())); + theMap.put(R23VisitorKeys.TRACE_AXIALE, french(aRfAdminRev.getTraceAxiale())); + theMap.put(R23VisitorKeys.INTERFACE, french(aRfAdminRev.getInterfaceRfAdmin())); + theMap.put(R23VisitorKeys.PROJECT_MOTEUR, aRfAdminRev.getProjetMoteur()); + theMap.put(R23VisitorKeys.MAQUETTE_ECHANGEABLE, aRfAdminRev.getMaqEchangeable()); + theMap.put(R23VisitorKeys.WORKPACKAGE, aRfAdminRev.getWorkpackage()); + return theMap; + } + + @Override + public Map visitComponent(final RFAdminARevision aRfAdminARev) { + Map theMap = new EnumMap<>(R23VisitorKeys.class); + theMap.put(R23VisitorKeys.SUIVI_MONTAGE, french(aRfAdminARev.getSuiviMontage())); + theMap.put(R23VisitorKeys.RESPONSABLE_REPERE, aRfAdminARev.getResponsableRepere()); + theMap.put(R23VisitorKeys.MAQUETTE, french(aRfAdminARev.getMaqIntExt())); + theMap.put(R23VisitorKeys.IDENTIFIANT_RF_ADMIN, EMPTY_STRING); + theMap.put(R23VisitorKeys.REVISION_RF_ADMIN, EMPTY_STRING); + theMap.put(R23VisitorKeys.IDENTIFIANT_RF_ADMIN_AP, EMPTY_STRING); + theMap.put(R23VisitorKeys.REVISION_RF_ADMIN_AP, EMPTY_STRING); + theMap.put(R23VisitorKeys.FRONTIERE_AVION, EMPTY_STRING); + theMap.put(R23VisitorKeys.FRONTIERE_COOPERANT, EMPTY_STRING); + theMap.put(R23VisitorKeys.GEOMETRIE_PIECE_RIGIDE, EMPTY_STRING); + theMap.put(R23VisitorKeys.GEOMETRIE_SIMPLIFIE_RIGIDE, EMPTY_STRING); + theMap.put(R23VisitorKeys.ENVELOPPE_DE_CINEMATIQUE, EMPTY_STRING); + theMap.put(R23VisitorKeys.ENVELOPPE_DE_MAINTENANCE, EMPTY_STRING); + theMap.put(R23VisitorKeys.ENVELOPPE_DE_MONTAGE_DEMONTAGE, EMPTY_STRING); + theMap.put(R23VisitorKeys.TRACE_AXIALE, EMPTY_STRING); + theMap.put(R23VisitorKeys.INTERFACE, EMPTY_STRING); + theMap.put(R23VisitorKeys.PROJECT_MOTEUR, EMPTY_STRING); + theMap.put(R23VisitorKeys.MAQUETTE_ECHANGEABLE, EMPTY_STRING); + theMap.put(R23VisitorKeys.WORKPACKAGE, EMPTY_STRING); + theMap.put(R23VisitorKeys.TRANSFERT_LIEN_LOGISTIQUE, french(aRfAdminARev.getTransfertLienLogisti())); + theMap.put(R23VisitorKeys.TRANSFERT_LIEN_MONTAGE, french(aRfAdminARev.getTransfertLienMontage())); + return theMap; + } + + @Override + public Map visitComponent(final RFAdminAPRevision aRfAdminAPRev) { + Map theMap = new EnumMap<>(R23VisitorKeys.class); + theMap.put(R23VisitorKeys.IDENTIFIANT_RF_ADMIN_AP, aRfAdminAPRev.getItemId()); + theMap.put(R23VisitorKeys.REVISION_RF_ADMIN_AP, aRfAdminAPRev.getRevisionId()); + theMap.put(R23VisitorKeys.SUIVI_MONTAGE, french(aRfAdminAPRev.getSuiviMontage())); + theMap.put(R23VisitorKeys.TRANSFERT_LIEN_LOGISTIQUE, french(aRfAdminAPRev.getTransfertLienLogisti())); + theMap.put(R23VisitorKeys.TRANSFERT_LIEN_MONTAGE, french(aRfAdminAPRev.getTransfertLienMontage())); + return theMap; + } + + @Override + public Map visitComponent(final RFAdminAGRevision aRfAdminAGRev) { + Map theMap = new EnumMap<>(R23VisitorKeys.class); + theMap.put(R23VisitorKeys.IDENTIFIANT_RF_ADMIN_AP, EMPTY_STRING); + theMap.put(R23VisitorKeys.REVISION_RF_ADMIN_AP, EMPTY_STRING); + theMap.put(R23VisitorKeys.TRANSFERT_LIEN_LOGISTIQUE, french(aRfAdminAGRev.getTransfertLienLogisti())); + theMap.put(R23VisitorKeys.TRANSFERT_LIEN_MONTAGE, french(aRfAdminAGRev.getTransfertLienMontage())); + return theMap; + } + + /** + * Get the Repere Component properties to make a R23 report. + * + * @param anAbstractRF AbstractRF + * @return theMap Map + */ + private Map getRfProperties(final AbstractRF anAbstractRF) { + Map theMap = new EnumMap<>(R23VisitorKeys.class); + theMap.put(R23VisitorKeys.REPERE_FONCTIONNEL, anAbstractRF.getName()); + theMap.put(R23VisitorKeys.IDENTIFIANT_REPERE_FONCTIONNEL, anAbstractRF.getItemId()); + theMap.put(R23VisitorKeys.REVISION_REPERE_FONCTIONNEL, anAbstractRF.getRevisionId()); + theMap.put(R23VisitorKeys.EQUIVALENT_SNSSIN, anAbstractRF.getEquivalentSnsSin()); + return theMap; + } + + @Override + public Map visitComponent(final MockupRevision aMockupRev) { + // This object is not use in this report + return null; + } + + @Override + public Map visitComponent(final DescriptifRevision aDescriptifRev) { + // This object is not use in this report + return null; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/visitors/snecmaobject/R23ReceptorVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/visitors/snecmaobject/R23ReceptorVisitor.java new file mode 100644 index 0000000..eaa34f9 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r23report/visitors/snecmaobject/R23ReceptorVisitor.java @@ -0,0 +1,154 @@ +package com.capgemini.reports.definition.r23report.visitors.snecmaobject; + +import com.capgemini.reports.definition.r23report.visitors.R23VisitorKeys; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAGRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericAssembRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.mockup.MockupRevision; +import com.capgemini.reports.snecmaobjects.part.*; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartAssembRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartRevision; +import com.capgemini.reports.snecmaobjects.supermodel.SuperModelRevision; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; + +import java.util.EnumMap; +import java.util.Map; + +/** + * Visit a Receptor SnecmaObject to make a R23 report. + */ +public class R23ReceptorVisitor implements IReceptorVisitor> { + private static final long serialVersionUID = 390235455677826754L; + + @Override + public Map visitReceptor(final ProductRevision aProductRev) { + return getReceptorProperties(aProductRev); + } + + @Override + public Map visitReceptor(final GenericRevision aGenericRev) { + return getReceptorProperties(aGenericRev); + } + + @Override + public Map visitReceptor(final SuperModelRevision aSuperModelRev) { + return getReceptorProperties(aSuperModelRev); + } + + @Override + public Map visitReceptor(final GenericAssembRevision aGenericAssembRev) { + return getReceptorProperties(aGenericAssembRev); + } + + @Override + public Map visitReceptor(final AlternateRevision anAlternateRev) { + return getReceptorProperties(anAlternateRev); + } + + @Override + public Map visitReceptor(final DETRevision aDetRev) { + return getReceptorProperties(aDetRev); + } + + @Override + public Map visitReceptor(final PartAeroRevision aPartAeroRev) { + return getReceptorProperties(aPartAeroRev); + } + + @Override + public Map visitReceptor(final PartNoAeroRevision aPartNoAeroRev) { + return getReceptorProperties(aPartNoAeroRev); + } + + @Override + public Map visitReceptor(final PartAssembRevision aPartAssembRev) { + return getReceptorProperties(aPartAssembRev); + } + + @Override + public Map visitReceptor(final PartMatRevision aPartMatRev) { + return getReceptorProperties(aPartMatRev); + } + + @Override + public Map visitReceptor(final StandardRevision aStandardRev) { + return getReceptorProperties(aStandardRev); + } + + @Override + public Map visitReceptor(final RFGenericRevision aRfGenericRev) { + // No use in R23 report + return new EnumMap<>(R23VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFPartAssembRevision aRfPartAssembRev) { + // No use in R23 report + return new EnumMap<>(R23VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFPartRevision aRfPartRev) { + // No use in R23 report + return new EnumMap<>(R23VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFAdminRevision aRfAdminRev) { + // No use in R23 report + return new EnumMap<>(R23VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFAdminARevision aRfAdminARev) { + // No use in R23 report + return new EnumMap<>(R23VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFAdminAPRevision aRfAdminAPRev) { + // No use in R23 report + return new EnumMap<>(R23VisitorKeys.class); + } + + @Override + public Map visitReceptor(final RFAdminAGRevision aRfAdminAGRev) { + // No use in R23 report + return new EnumMap<>(R23VisitorKeys.class); + } + + /** + * Get the Receptor properties. + */ + private Map getReceptorProperties(final ISnecmaObject iSnecmaObject) { + Map theMap = new EnumMap<>(R23VisitorKeys.class); + theMap.put(R23VisitorKeys.IDENTIFIANT_RECEPTEUR, iSnecmaObject.getItemId()); + theMap.put(R23VisitorKeys.NOM_RECEPTEUR, iSnecmaObject.getName()); + theMap.put(R23VisitorKeys.REVISION_RECEPTEUR, iSnecmaObject.getRevisionId()); + return theMap; + } + + @Override + public Map visitReceptor(final MockupRevision aMockupRev) { + // This object is not use in this report + return null; + } + + @Override + public Map visitReceptor(final DescriptifRevision aDescriptifRev) { + // This object is not use in this report + return null; + } + + @Override + public Map emptyRf() { + return new EnumMap<>(R23VisitorKeys.class); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r24report/DataReportPreparatorR24.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r24report/DataReportPreparatorR24.java new file mode 100644 index 0000000..810b23d --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r24report/DataReportPreparatorR24.java @@ -0,0 +1,270 @@ +package com.capgemini.reports.definition.r24report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRule; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRuleProperties; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.generic.TcGeneric; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.generic.TcGenericPv; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.product.TcProduct; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.product.TcProductRevision; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.unit.TcUnitRevision; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindow; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindowConfiguration; +import com.capgemini.framework.teamcenter.object.runtime.TcRevisionRulesConfiguration; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.documentationobjects.DocNorm; +import com.capgemini.reports.documentationobjects.DocNormStandard; +import com.capgemini.reports.documentationobjects.DocTechnic; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NoConfChangesException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.optimized.r24report.OptimizedR24Folder; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.releasestatus.RevisionStatusAndDate; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import com.capgemini.reports.snecmaobjects.part.PartAeroRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.capgemini.reports.teamcenter.ObjectInfoHelper; +import com.capgemini.reports.teamcenter.ObjectInfoLoader; +import com.capgemini.reports.teamcenter.resolution.structureservice.SingleStructureServiceCaller; +import com.google.common.base.Optional; +import com.google.common.collect.FluentIterable; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; +import net.lingala.zip4j.exception.ZipException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +/** + * This class will allow to prepare data and findAll back data for making report R24. + */ +@Slf4j +@EqualsAndHashCode +public class DataReportPreparatorR24 implements IDataReportPreparator { + private static final long serialVersionUID = 3714231249482402544L; + + private static final Logger LOGGER = LoggerFactory.getLogger(DataReportPreparatorR24.class); + + private static final String REC_DEFINITION = "REC-Définition de récupération / Recovery design"; + private static final String MCI_MASSE_CENTRE_DE_GRAVITE = "MCI-Masse, Centre de gravité et inertie / Mass, gravity center and inertia"; + private static final String REALISATION_ACHIEVEMENT = "Réalisation / Achievement"; + + @Override + public String print(TcSession session, ExecutionR24 execution, IExecutionStrategy executionStrategy) throws KurtException, ZipException { + ProductUnit productUnit = execution.getProductUnit(); + TcProduct tcProduct = new TcProduct(session, productUnit.getProduct(session)); + TcProductRevision tcProductRevision = tcProduct.revisions().get(0); + execution.setProductLine(tcProductRevision.ligneProduit()); + String typeProduit = tcProductRevision.productType(); + PrintParameters printParameters = execution.reportParameters(); + + if (new OptimizedR24Folder().configurationHasNotChanged(productUnit)) { + throw new NoConfChangesException(UserInputErrorEnum.NO_CONFIGURATION_CHANGES.getMsgEn()); + } + + int unitNumber = productUnit.getUnit(); + Optional tcUnitRevision = tcProductRevision.unitRevision(unitNumber); + if (!tcUnitRevision.isPresent()) { + throw new InvalidUserInputException(UserInputErrorEnum.PRODUCT_AND_UNIT_DOES_NOT_EXIST); + } + TcRevisionRulesConfiguration revisionRulesConfiguration = revisionRulesConfiguration(session, execution, tcProduct, unitNumber); + + session.setObjectPropPolicy(execution.getFullPolicy()); + + List tcGenericPvs = tcUnitRevision.get().genericPvs(); + List tcGenerics = FluentIterable.from(tcGenericPvs).filter(TcGeneric.class).toList(); + int genericsDontExistForPU = 0; + for (TcGeneric generic : tcGenerics) { + try { + ExecutionR24 subExecution = new ExecutionR24(execution.getProductUnit(), generic.getItem(), execution.getTypeImpression(), execution.getFrenchInput()); + subExecution.setProductLine(tcProductRevision.ligneProduit()); + subExecution.setTypeProduit(typeProduit); + subExecution.setClausePropriete(ObjectInfoLoader.getClausePropriete(typeProduit, session)); + printParameters.addSubReport("R24-" + generic.getItem().get_item_id(), prepareData(session, subExecution, generic, revisionRulesConfiguration)); + } + catch (EmptyNomenclatureException e) { + genericsDontExistForPU++; + log.warn("No Bom for generic:" + generic.getItem().get_item_id() + " for PU:" + productUnit.getProductID() + "/" + productUnit.getUnitStr()); + } + } + if (genericsDontExistForPU == tcGenerics.size()) { + throw new InvalidUserInputException(UserInputErrorEnum.NO_GENERIC_FOUND_FOR_THIS_PU); + } + + executionStrategy.print(printParameters, execution); + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + } + + private TcRevisionRulesConfiguration revisionRulesConfiguration(final TcSession session, final ExecutionR24 report, final TcProduct productObject, int unit) throws KurtException { + TcRevisionRuleProperties revisionRuleProperties = new TcRevisionRuleProperties(productObject, unit); + TcRevisionRule revisionRule = session.findRevRule(report.getRevisionRule()); + return new TcRevisionRulesConfiguration(revisionRule, revisionRuleProperties); + } + + private PrintParameters prepareData(final TcSession session, final ExecutionR24 report, final TcGeneric tcGeneric, final TcRevisionRulesConfiguration revisionRulesConfiguration) throws KurtException { + LOGGER.debug("PrepareData started on: {}", report.getReportIdentifier().getReportTitle()); + TcBomWindowConfiguration bomWindowConfiguration = new TcBomWindowConfiguration(tcGeneric, revisionRulesConfiguration); + try (TcBomWindow bomWindow = session.createBomWindow(bomWindowConfiguration)) { + BOMLineHolder rfGenericBom = new SingleStructureServiceCaller(session).resolve(bomWindow.topLine(), new R24BOMLineExplorer()); + + // Treatment of the RFGenericBom + ItemRevision rfGeneric = rfGenericBom.getItemRevision(); + report.setRfGenericRev(new RFGenericRevision(session, rfGeneric)); + + for (BOMLineHolder currentChild : rfGenericBom.getBomChilds()) { + ItemRevision itemRevChild = currentChild.getItemRevision(); + String childType = itemRevChild.getTypeObject().getName(); + if (SnecmaObjectTypes.PART_AERO_REVISION.equals(childType)) { + report.getPartNumberRevList().add(new PartAeroRevision(session, itemRevChild)); + } + else if (SnecmaObjectTypes.DESCRIPTIF_REVISION.equals(childType)) { + retrieveDocNormAndDocNormStandardLists(session, itemRevChild, report); + retrieveDocTechnicList(session, itemRevChild, report); + } + else if (SnecmaObjectTypes.RF_ADMIN_REVISION.equals(childType)) { + report.setRfAdminRev(new RFAdminRevision(session, itemRevChild)); + report.setFrontiereAvion(report.getRfAdminRev().getFrontiereAvion()); + report.setFrontiereCooperant(report.getRfAdminRev().getFrontiereCooperant()); + } + } + + ItemRevision generivRev = (ItemRevision) bomWindow.topLine().get_bl_line_object(); + String typeGeneric = generivRev.getTypeObject().getName(); + if (SnecmaObjectTypes.GENERIC_REVISION.equals(typeGeneric)) { + report.setGenericRev(new GenericRevision(session, generivRev)); + } + else { + throw new KurtException("Object should be a Generic but is a: " + typeGeneric); + } + + // Specific treatment of DocTechnic + filterDocTechnic(report); + filterForDefinitionCertifiee(report); + PrintParameters printParameters = report.subReportParameters(); + new R24Printer().constructDataMaps(session, printParameters, report); + LOGGER.debug("PrepareData ended on: {}", report.getReportIdentifier().getReportTitle()); + return printParameters; + } + } + + private void filterForDefinitionCertifiee(final ExecutionR24 report) { + if (report.isDefCertifiee()) { + List transitList = new ArrayList<>(); + for (DocTechnic docTechnic : report.getDocTechnicList()) { + // These values are forbidden + if ("Définition / Design".equals(docTechnic.getTypeDocTechnic1())) { + transitList.add(docTechnic); + } + } + report.getDocTechnicList().clear(); + report.getDocTechnicList().addAll(transitList); + } + } + + /** + * Returns true if this report execution generated an empty table of documents (no doc found). + * + * @param report - the execution report which provide all informations for the report + * @return true if the table of documents is empty + */ + public boolean isEmptyTable(final ExecutionR24 report) { + return report.getDocNormList().isEmpty() && report.getDocNormStandardList().isEmpty() && report.getDocTechnicList().isEmpty(); + } + + /** + * Retrieve the {@link DocNorm} and the {@link DocNormStandard} in their respective {@link List}s. + * + * @param session {@link TcSession} - the tc session + * @param itemRevision {@link ItemRevision} - the object which possess all the documents + * @param report - the execution report which provide all informations for the report + */ + private void retrieveDocNormAndDocNormStandardLists(final TcSession session, + final ItemRevision itemRevision, final ExecutionR24 report) { + List referenceDoclist = AbstractPart.returnReferenceDocuments(session, itemRevision); + if (!referenceDoclist.isEmpty()) { + for (Item docItem : referenceDoclist) { + if (docItem == null) { + continue; + } + String docType = docItem.getTypeObject().getName(); + String docId = docItem.get_item_id(); + if (SnecmaObjectTypes.DOC_NORM.equals(docType)) { + ItemRevision selectedDocRev = getDocNormAndDocNormStandardRevisions(session, docId); + report.docNormList.add(new DocNorm(session, selectedDocRev)); + } + else if (SnecmaObjectTypes.DOC_NORM_STANDARD.equals(docType)) { + ItemRevision selectedDocRev = getDocNormAndDocNormStandardRevisions(session, docId); + report.docNormStandardList.add(new DocNormStandard(session, selectedDocRev)); + } + } + } + } + + private ItemRevision getDocNormAndDocNormStandardRevisions(final TcSession session, final String docId) { + // Retrieve the revisions + List listOfDocNormRev = new ItemRevisionQuery(session).searchID(docId).findAll(); + // Try to obtain the revision with the latest release date... + Optional selectedDocRev; + selectedDocRev = ObjectInfoHelper.getRevisionFromStatusWithMostRecentReleaseDate(session, listOfDocNormRev, Calendar.getInstance(), + StatusEnum.PUBLISHED, StatusEnum.FROZEN); + if (selectedDocRev.isPresent()) { + return selectedDocRev.get(); + } + else { + // No release date found, now obtain the revision with latest modification date + RevisionStatusAndDate revAndStatus = + ObjectInfoHelper.getRevisionAndStatusWithMostRecentModificationDate(listOfDocNormRev, Calendar.getInstance()); + return revAndStatus.getItemRevision(); + } + } + + /** + * Retrieve the {@link DocTechnic} in a {@link List}. + */ + private void retrieveDocTechnicList(final TcSession session, final ItemRevision partItemRevision, final ExecutionR24 report) { + List technicDocObjects = AbstractPart.returnDefinitionDocuments(session, partItemRevision); + if (!technicDocObjects.isEmpty()) { + for (ItemRevision docTechnicRev : technicDocObjects) { + if (docTechnicRev != null) { + report.docTechnicList.add(new DocTechnic(session, docTechnicRev)); + } + } + } + } + + /** + * Filter the DocTechnic with specific values on the type_doc_technic_1 and type_doc_technic_2 properties. + * + * @param report - the execution report which provide all informations for the report + */ + private void filterDocTechnic(final ExecutionR24 report) { + List transitList = new ArrayList<>(); + for (DocTechnic docTechnic : report.docTechnicList) { + // These values are forbidden + String typeDocTechnic1 = docTechnic.getTypeDocTechnic1(); + String typeDocTechnic2 = docTechnic.getTypeDocTechnic2(); + if (!(REALISATION_ACHIEVEMENT.equals(typeDocTechnic1) + && (MCI_MASSE_CENTRE_DE_GRAVITE.equals(typeDocTechnic2) || REC_DEFINITION.equals(typeDocTechnic2)))) { + transitList.add(docTechnic); + } + } + report.docTechnicList.clear(); + report.docTechnicList.addAll(transitList); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r24report/ExecutionR24.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r24report/ExecutionR24.java new file mode 100644 index 0000000..61ace27 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r24report/ExecutionR24.java @@ -0,0 +1,232 @@ +package com.capgemini.reports.definition.r24report; + +import com.capgemini.framework.common.*; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.builder.R24Builder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal; +import com.capgemini.reports.definition.r23report.ExecutionR23; +import com.capgemini.reports.documentationobjects.DocNorm; +import com.capgemini.reports.documentationobjects.DocNormStandard; +import com.capgemini.reports.documentationobjects.DocTechnic; +import com.capgemini.reports.exceptions.FileLoadingException; +import com.capgemini.reports.exceptions.ReportPrintException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.printing.Printer; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.reports.parameters.checker.ProductChecker; +import com.capgemini.reports.reports.parameters.checker.ProductUnitChecker; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.generic.AbstractGenericRevision; +import com.capgemini.reports.snecmaobjects.part.PartAeroRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.teamcenter.soa.client.model.strong.Item; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +/** + * This class controls the execution of a R24 report. + */ +@Getter +@Setter(value = AccessLevel.PROTECTED) +@EqualsAndHashCode(callSuper = true) +public class ExecutionR24 extends AbstractExecutionReport { + protected static final String FRENCH_LANGUAGE = "Francais"; + private static final long serialVersionUID = -5076506178171189943L; + private static final Logger LOGGER = LoggerFactory.getLogger(ExecutionR23.class); + // Policies + private static final PolicyLocation R24_POLICY_XML_FULL = PolicyLocation.make("R24_policy_full", "/xml/policies/r24report/R24_policy_full.xml"); + private static final PolicyLocation R24_POLICY_XML_LIGHT = PolicyLocation.make("R24_policy_light", "/xml/policies/r24report/R24_policy_light.xml"); + // Priority parameter + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R24); + // Revision rule parameter + private static final String REPORT_REVISION_RULE = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R24", DEFAULT_REVISION_RULE); + // Launch type parameter + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R24"); + // Configuration + private static final String FILE_SEPARATOR = "_"; + private static final String PATTERN_DATE = "dd-MM-yyyy"; + // Report parameters + protected final boolean french; + protected final String frenchInput; + // Documents gathered + protected final List docNormList = new ArrayList<>(); + protected final List docNormStandardList = new ArrayList<>(); + protected final List docTechnicList = new ArrayList<>(); + // Raw input parameters + protected final ProductUnit productUnit; + protected final Item genericItem; + // Internal working data + protected final String typeImpression; + protected final boolean isDefCertifiee; + // Data gathered + protected String dateReleased = ""; + protected String revisionArticle = ""; + protected String typeProduit; + protected String clausePropriete; + protected RFGenericRevision rfGenericRev; + // Data gathered + protected AbstractGenericRevision genericRev; + protected List partNumberRevList = new ArrayList<>(); + protected RFAdminRevision rfAdminRev; + protected String frontiereAvion = ""; + protected String frontiereCooperant = ""; + private String productLine; + + /** + * Constructor. + * + * @param produitUnit {@link ProductUnit} - the Product id and the Unit range. + * @param typeImpression {@link String} - the type of impression of the report + * @param langage {@link String} - the language selected by the user + */ + public ExecutionR24(final ProductUnit produitUnit, final String typeImpression, final String langage) { + this(produitUnit, null, typeImpression, langage); + } + + public ExecutionR24(final ProductUnit produitUnit, final Item generic, final String typeImpression, final String langage) { + super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE); + this.genericItem = generic; + this.frenchInput = langage; + this.french = isFrench(langage); + this.productUnit = produitUnit; + this.isDefCertifiee = "Def_certifiee".equals(typeImpression); + this.typeImpression = typeImpression; + } + + protected static boolean isFrench(final String language) { + return FRENCH_LANGUAGE.equals(language); + } + + @Override + public List getLaunchData() { + List theCriteria = new ArrayList<>(); + theCriteria.add(new MngCriteriaVal.CriteriaValue(ReportCriteriaEnum.PRODUCT, productUnit.getProductID())); + theCriteria.add(new MngCriteriaVal.CriteriaValue(ReportCriteriaEnum.UNIT, productUnit.getUnitStr())); + theCriteria.add(new MngCriteriaVal.CriteriaValue(ReportCriteriaEnum.TYPE_IMPRESSION, typeImpression)); + theCriteria.add(new MngCriteriaVal.CriteriaValue(ReportCriteriaEnum.LANGUAGE, frenchInput)); + return theCriteria; + } + + @Override + public List getQuickChecks() { + ArrayList quickChecks = new ArrayList<>(); + quickChecks.add(new ProductChecker(productUnit.getProductID())); + quickChecks.add(new ProductUnitChecker(productUnit)); + return quickChecks; + } + + @Override + public String getTemplateLocation() { + return JasperTemplate.TEMPLATE_R24.getFilepath(); + } + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R24_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R24_POLICY_XML_FULL; + } + + @Override + public List getLongChecks() { + return new ArrayList<>(); + } + + @Override + public ReportEnum getReportIdentifier() { + return ReportEnum.REPORT_R24; + } + + /** + * Format file expected : R24_"Critère produit"_"Ligne produit"_"Critère Unit"_"générique traité"_"date_système".XLSX + */ + private String getSubReportFileName() { + return setFileName(true).toString(); + } + + /** + * Format file expected : R24_"Critère produit"_"Ligne produit"_"Critère Unit"_"date_système".zip + * + * @return zip filename + */ + @Override + public String getSpecifiedFileName() { + return setFileName(false).toString(); + } + + private StringBuilder setFileName(Boolean addItemId) { + StringBuilder filename = new StringBuilder("R24").append(FILE_SEPARATOR); + filename.append(productUnit.getProductID()).append(FILE_SEPARATOR); + filename.append(productLine.replaceAll(StringHelper.REGEXP_ALPHANUM, " ")).append(FILE_SEPARATOR); + filename.append(productUnit.getUnitStr()).append(FILE_SEPARATOR); + if (addItemId) { + filename.append(genericItem.get_item_id()).append(FILE_SEPARATOR); + } + filename.append(TeamcenterDateFormatter.formatCalendarToPattern(Calendar.getInstance(), PATTERN_DATE)); + + return filename; + } + + @Override + public Printer getPrinter() { + return new Printer(Printer.AvailablePrinter.ZIP); + } + + @Override + public Printer.PrintFormat getPrintingFormat() { + return Printer.PrintFormat.XLSX; + } + + @Override + public IDataReportPreparator getDataPreparator() { + return new DataReportPreparatorR24(); + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return new ExecutionR24(productUnit, typeImpression, frenchInput); + } + + @Override + public Class getReportBuilderClass() { + return R24Builder.class; + } + + public PrintParameters reportParameters() { + return new PrintParameters(Printer.PrintFormat.ZIP, getFileNameOnDisc(), ReportFolderOutputHelper.getStorageFolderLocation(getLaunchType())); + } + + public PrintParameters subReportParameters() throws ReportPrintException, FileLoadingException { + String storageFolder = ReportFolderOutputHelper.getStorageFolderLocation(getLaunchType()); + String templateLocation = getTemplateLocation(); + try (InputStream templateStream = ResourceHelper.getResourceAsStream(templateLocation)) { + PrintParameters printParameters = PrintParameters.createMainReport(getPrintingFormat(), getSubReportFileName(), storageFolder, templateStream); + printParameters.setReportTitle(getReportIdentifier().getReportTitle()); + return printParameters; + } catch (IOException e) { + LOGGER.error("Unable to close the template file properly from " + templateLocation, e); + return null; // IOException is only thrown by close() which, if it ever fails, means you have much bigger problems! + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r24report/R24BOMLineExplorer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r24report/R24BOMLineExplorer.java new file mode 100644 index 0000000..bf00409 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r24report/R24BOMLineExplorer.java @@ -0,0 +1,33 @@ +package com.capgemini.reports.definition.r24report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.resolution.filtering.ITcTypeFilter; +import com.capgemini.framework.teamcenter.resolution.filtering.TcTypeInclusionFilter; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderHelper; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.MalformedNomenclatureException; +import com.capgemini.reports.teamcenter.resolution.IBOMLineExplorer; +import com.capgemini.reports.teamcenter.resolution.structureservice.SingleStructureServiceCaller; + +/** + * Explorer of {@link BOMLineHolder}s used in {@link SingleStructureServiceCaller} for R24 report.
+ * Thanks to this class, the SINGLE resolution structure could carry on and the Part Number could be taken.
+ * The Rf Generic is returned, and its children Part Aero / RF Admin and Descriptif are loaded + */ +public class R24BOMLineExplorer implements IBOMLineExplorer { + + private static final ITcTypeFilter FILTER_PART_ADMIN_DESCRIPTION = new TcTypeInclusionFilter(SnecmaObjectTypes.PART_AERO_REVISION, SnecmaObjectTypes.RF_ADMIN_REVISION, SnecmaObjectTypes.DESCRIPTIF_REVISION); + private static final ITcTypeFilter FILTER_RF_GENERIC_REVISION = new TcTypeInclusionFilter(SnecmaObjectTypes.RF_GENERIC_REVISION); + + @Override + public BOMLineHolder explore(TcSession session, final SingleStructureServiceCaller.SingleLevelExpander expander, final BOMLineHolder genericBom) throws EmptyNomenclatureException, + InvalidInputException, MalformedNomenclatureException { + BOMLineHolder expandedGenericBom = expander.expand(genericBom, FILTER_RF_GENERIC_REVISION); + BOMLineHolder rfGeneric = BOMLineHolderHelper.findRfGenericBL(expandedGenericBom); + return expander.expand(rfGeneric, FILTER_PART_ADMIN_DESCRIPTION); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r24report/R24Printer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r24report/R24Printer.java new file mode 100644 index 0000000..f74df34 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r24report/R24Printer.java @@ -0,0 +1,192 @@ +package com.capgemini.reports.definition.r24report; + +import com.capgemini.framework.common.LanguageHelper; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.definition.r15r16r17reports.AbstractExecutionR15R16R17; +import com.capgemini.reports.definition.r15r16r17reports.CommunR15R16R17ComponentVisitor; +import com.capgemini.reports.definition.r15r16r17reports.R15R16R17R24R25Keys; +import com.capgemini.reports.definition.r15r16r17reports.R15R16R17R24R25Keys.Page2; +import com.capgemini.reports.documentationobjects.DocNorm; +import com.capgemini.reports.documentationobjects.DocNormStandard; +import com.capgemini.reports.documentationobjects.DocTechnic; +import com.capgemini.reports.execution.mapconstructor.AbstractStaticTemplateMapConstructor; +import com.capgemini.reports.execution.mapconstructor.IMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.snecmaobjects.part.PartAeroRevision; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +/** + * This class is able to put the data gathered by an {@link ExecutionR24} into some {@link PrintParameters} for printing. + */ +@Slf4j +public class R24Printer extends AbstractStaticTemplateMapConstructor implements IMapConstructor { + private static final long serialVersionUID = -789205459094400840L; + + private static final String N_A = "N/A"; + + private static final String EMPTY_STRING = StringHelper.EMPTY; + private static final String UNKNOWN_STR = "???"; + private static final String SANS_OBJET = "Sans objet"; + private static final String NOT_APPLICABLE = "Not applicable "; + + private static String french(final String string) { + return LanguageHelper.french(string); + } + + private static String english(final String string) { + return LanguageHelper.english(string); + } + + /** + * Puts the data gathered by an {@link AbstractExecutionR15R16R17} into some {@link PrintParameters} for printing. + * + * @param execution the data-bearing {@link AbstractExecutionR15R16R17} + * @param mainReport the {@link PrintParameters} + */ + private void print(final ExecutionR24 execution, final PrintParameters mainReport) { + // first put generic data + DataReportPreparatorR24 preparator = (DataReportPreparatorR24) execution.getDataPreparator(); + mainReport.addReportParameters(setupStringParameters(execution)); + mainReport.addReportParameter(R15R16R17R24R25Keys.EMPTY_TABLE.toString(), preparator.isEmptyTable(execution)); + mainReport.addReportDataFromEnum(setupData(execution)); + + // Now add the specific stuff + addOptionalParameters(execution, mainReport); + } + + private Map setupStringParameters(final ExecutionR24 execution) { + Map params = new EnumMap<>(R15R16R17R24R25Keys.class); + params.put(R15R16R17R24R25Keys.CLAUSE_PROPRIETE, execution.getClausePropriete()); + params.put(R15R16R17R24R25Keys.PRODUCT_TYPE, execution.getTypeProduit()); + params.put(R15R16R17R24R25Keys.REPORT_TITLE, getTitle()); + params.put(R15R16R17R24R25Keys.ITEM_REVISION_ID, execution.getRevisionArticle()); + String dateReleased = execution.getDateReleased(); + params.put(R15R16R17R24R25Keys.RELEASE_DATE, execution.isFrench() ? french(dateReleased) : english(dateReleased)); + return params; + } + + private List> setupData(final ExecutionR24 execution) { + List> dataTable = new ArrayList<>(); + boolean isFrench = execution.isFrench(); + for (DocNorm norm : execution.getDocNormList()) { + dataTable.add(getDocNormLine(norm, isFrench)); + } + for (DocNormStandard normStd : execution.getDocNormStandardList()) { + dataTable.add(getDocNormStandardLine(normStd, isFrench)); + } + for (DocTechnic technic : execution.getDocTechnicList()) { + dataTable.add(getDocTechnicLine(technic, isFrench)); + } + + // If there are no documents, add an empty line to provoke band printing + if (dataTable.isEmpty()) { + Map line = new EnumMap<>(Page2.class); + line.put(Page2.DOC_NUMBER, "(No document found)"); + line.put(Page2.ISSUE, N_A); + line.put(Page2.DOC_TYPE, N_A); + line.put(Page2.DOC_TITLE, N_A); + dataTable.add(line); + } + return dataTable; + } + + private Map getDocNormLine(final DocNorm docNorm, final boolean isFrench) { + String idOrigine = docNorm.getIdOrigine(); + Map line = new EnumMap<>(Page2.class); + line.put(Page2.DOC_NUMBER, (idOrigine == null || idOrigine.isEmpty()) ? docNorm.getDocId() : idOrigine); + line.put(Page2.ISSUE, "-"); + String typeDocNorm = docNorm.getTypeDocNorm(); + line.put(Page2.DOC_TYPE, isFrench ? french(typeDocNorm) : english(typeDocNorm)); + line.put(Page2.DOC_TITLE, isFrench ? docNorm.getItemName() : docNorm.getDesignationEn()); + return line; + } + + private Map getDocNormStandardLine(final DocNormStandard normStd, final boolean isFrench) { + Map line = new EnumMap<>(Page2.class); + String idOrigine = normStd.getIdOrigine(); + line.put(Page2.DOC_NUMBER, (idOrigine == null || idOrigine.isEmpty()) ? normStd.getDocId() : idOrigine); + line.put(Page2.ISSUE, "-"); + line.put(Page2.DOC_TYPE, isFrench ? "Norme pour articles standards" : "Norm for standards items"); + line.put(Page2.DOC_TITLE, isFrench ? normStd.getItemName() : normStd.getDesignationEn()); + return line; + } + + private Map getDocTechnicLine(final DocTechnic technic, final boolean isFrench) { + Map line = new EnumMap<>(Page2.class); + String idOrigine = technic.getIdOrigine(); + line.put(Page2.DOC_NUMBER, (idOrigine == null || idOrigine.isEmpty()) ? technic.getDocId() : idOrigine); + line.put(Page2.ISSUE, technic.getIndice()); + + String typeDocTechnic1 = technic.getTypeDocTechnic1(); + String type1 = isFrench ? french(typeDocTechnic1) : english(typeDocTechnic1); + String typeDocTechnic2 = technic.getTypeDocTechnic2(); + String type2 = isFrench ? french(typeDocTechnic2) : english(typeDocTechnic2); + line.put(Page2.DOC_TYPE, type1 + " / " + type2); + + line.put(Page2.DOC_TITLE, isFrench ? technic.getName() : technic.getDesignationEn()); + return line; + } + + private void addOptionalParameters(final ExecutionR24 execution, final PrintParameters mainReport) { + Map params = new EnumMap<>(R15R16R17R24R25Keys.class); + List partNumberRevList = execution.getPartNumberRevList(); + if (partNumberRevList != null && !partNumberRevList.isEmpty()) { + Map map = new EnumMap<>(R15R16R17R24R25Keys.class); + if (partNumberRevList.size() == 1) { + map = partNumberRevList.get(0).accept(getVisitor(execution.isFrench())); + map.remove(R15R16R17R24R25Keys.PART_VERSION); + } else { + map.put(R15R16R17R24R25Keys.ITEM_ID, UNKNOWN_STR); + map.put(R15R16R17R24R25Keys.PART_NUMBER, UNKNOWN_STR); + map.put(R15R16R17R24R25Keys.MANUFACTURER_CODE, UNKNOWN_STR); + map.put(R15R16R17R24R25Keys.FRENCH_DESIGNATION, UNKNOWN_STR); + map.put(R15R16R17R24R25Keys.ENGLISH_DESIGNATION, UNKNOWN_STR); + map.put(R15R16R17R24R25Keys.OBTURATION, execution.isFrench() ? SANS_OBJET : NOT_APPLICABLE); + map.put(R15R16R17R24R25Keys.CLASSIFICATION, "-"); + map.put(R15R16R17R24R25Keys.FIELD_OPN_SERIALISATION, UNKNOWN_STR); + map.put(R15R16R17R24R25Keys.LOG_DOCUMENT, execution.isFrench() ? SANS_OBJET : NOT_APPLICABLE); + } + map.put(R15R16R17R24R25Keys.PART_VERSION, EMPTY_STRING); + params.putAll(map); + } else { + params.putAll(execution.getGenericRev().accept(getVisitor(execution.isFrench()))); + } + params.put(R15R16R17R24R25Keys.MT_NUMBER, EMPTY_STRING); + params.put(R15R16R17R24R25Keys.PREVIOUS_RELEASE_DATE, EMPTY_STRING); + params.put(R15R16R17R24R25Keys.ITEM_ID, execution.getGenericItem().get_item_id()); + mainReport.addReportParameters(params); + + Map map = new EnumMap<>(R15R16R17R24R25Keys.SpecificR15R16.class); + boolean isFrench = execution.isFrench(); + String frontiereAvion = execution.getFrontiereAvion(); + map.put(R15R16R17R24R25Keys.SpecificR15R16.INSTALLATION_INTERFACE, isFrench ? french(frontiereAvion) : english(frontiereAvion)); + String frontiereCooperant = execution.getFrontiereCooperant(); + map.put(R15R16R17R24R25Keys.SpecificR15R16.PARTNER_INTERFACE, isFrench ? french(frontiereCooperant) : english(frontiereCooperant)); + map.put(R15R16R17R24R25Keys.SpecificR15R16.PRODUCT_UNIT, execution.getProductUnit().toString()); + mainReport.addReportParameters(map); + mainReport.addReportParameter(R15R16R17R24R25Keys.SpecificR15R16.IS_PREVIOUS_DEF.toString(), false); + } + + private String getTitle() { + return StringHelper.EMPTY; + } + + private IComponentVisitor> getVisitor(final boolean isFrench) { + return new CommunR15R16R17ComponentVisitor(isFrench); + } + + @Override + public void constructDataMaps(TcSession session, final PrintParameters printParameters, final ExecutionR24 data) throws KurtException { + long start = System.currentTimeMillis(); + this.print(data, printParameters); + log.trace("Execution time : {} ms for {}", System.currentTimeMillis() - start, "data filtering"); + } +} \ No newline at end of file diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r25report/DataReportPreparatorR25.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r25report/DataReportPreparatorR25.java new file mode 100644 index 0000000..d1a89e9 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r25report/DataReportPreparatorR25.java @@ -0,0 +1,298 @@ +package com.capgemini.reports.definition.r25report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRule; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRuleProperties; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.generic.TcGeneric; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.generic.TcGenericPv; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.product.TcProduct; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.product.TcProductRevision; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.unit.TcUnitRevision; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindow; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindowConfiguration; +import com.capgemini.framework.teamcenter.object.runtime.TcRevisionRulesConfiguration; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.documentationobjects.DocNorm; +import com.capgemini.reports.documentationobjects.DocNormStandard; +import com.capgemini.reports.documentationobjects.DocTechnic; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.releasestatus.RevisionStatusAndDate; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import com.capgemini.reports.snecmaobjects.part.PartAeroRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.capgemini.reports.teamcenter.ObjectInfoHelper; +import com.capgemini.reports.teamcenter.ObjectInfoLoader; +import com.capgemini.reports.teamcenter.resolution.structureservice.SingleStructureServiceCaller; +import com.google.common.base.Optional; +import com.google.common.collect.FluentIterable; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import net.lingala.zip4j.exception.ZipException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +import static com.capgemini.framework.teamcenter.object.pom.status.StatusEnum.OPEN; + +/** + * This class will allow to prepare data and findAll back data for making report R25. + */ +public class DataReportPreparatorR25 implements IDataReportPreparator { + private static final long serialVersionUID = 3714231249482402544L; + + private static final Logger LOGGER = LoggerFactory.getLogger(DataReportPreparatorR25.class); + + private static final String REC_DEFINITION = "REC-Définition de récupération / Recovery design"; + private static final String MCI_MASSE_CENTRE_DE_GRAVITE = "MCI-Masse, Centre de gravité et inertie / Mass, gravity center and inertia"; + private static final String REALISATION_ACHIEVEMENT = "Réalisation / Achievement"; + + @Override + public String print(TcSession session, ExecutionR25 execution, IExecutionStrategy executionStrategy) throws KurtException, ZipException { + ProductUnit productUnit = execution.getProductUnit(); + TcProduct tcProduct = new TcProduct(session, productUnit.getProduct(session)); + TcProductRevision tcProductRevision = tcProduct.revisions().get(0); + execution.setProductLine(tcProductRevision.ligneProduit()); + String typeProduit = tcProductRevision.productType(); + session.setObjectPropPolicy(execution.getFullPolicy()); + PrintParameters printParameters = execution.reportParameters(); + + // Si l'utilisateur n'a pas saisi le Unit + if (productUnit.getUnitStr().isEmpty()) { + for (TcUnitRevision unitRevision : unitToProcess(tcProductRevision)) { + int unitNumber = unitRevision.unitNumber(); + ProductUnit subProductUnit = new ProductUnit(productUnit.getProductID(), unitNumber); + ExecutionR25 subExecution = new ExecutionR25(subProductUnit, execution.getTypeImpression(), execution.getFrenchInput()); + subExecution.setProductLine(tcProductRevision.ligneProduit()); + printParameters + .addSubReport("R25-" + subProductUnit.getProductID() + "-" + unitNumber, + collectData(session, subExecution, subExecution.reportSubZipParameters(), typeProduit, subProductUnit, tcProduct, unitNumber, tcProductRevision, tcProductRevision.openUnitRevision(unitNumber))); + } + } + else { + productUnit.parseUserUnit(); + int unitNumber = productUnit.getUnit(); + Optional tcUnitRevision = tcProductRevision.notCancelledRevision(unitNumber); + if (!tcUnitRevision.isPresent()) { + throw new InvalidUserInputException(UserInputErrorEnum.PRODUCT_AND_UNIT_DOES_NOT_EXIST); + } + collectData(session, execution, printParameters, typeProduit, productUnit, tcProduct, unitNumber, tcProductRevision, tcUnitRevision); + } + + executionStrategy.print(printParameters, execution); + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + + } + + private List unitToProcess(final TcProductRevision tcProductRevision) throws InvalidUserInputException { + List unitsToProcess = new ArrayList<>(); + unitsToProcess.addAll(tcProductRevision.unitRevisionsWithStatus(OPEN)); + if (unitsToProcess.isEmpty()) { + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_NO_OPEN_UNIT_TO_THE_PRODUCT); + } + return unitsToProcess; + } + + private PrintParameters collectData(final TcSession session, final ExecutionR25 execution, final PrintParameters subReportParameters, String typeProduit, ProductUnit productUnit, TcProduct tcProduct, int unitNumber, TcProductRevision tcProductRevision, Optional tcUnitRevision) throws KurtException { + List tcGenericPvs = tcUnitRevision.get().genericPvs(); + List tcGenerics = FluentIterable.from(tcGenericPvs).filter(TcGeneric.class).toList(); + int genericsDontExistForPU = 0; + + for (TcGeneric generic : tcGenerics) { + try { + TcRevisionRulesConfiguration revisionRulesConfiguration = revisionRulesConfiguration(session, execution, tcProduct, unitNumber); + ExecutionR25 subExecution = new ExecutionR25(productUnit, generic.getItem(), execution.getTypeImpression(), execution.getFrenchInput()); + subExecution.setProductLine(tcProductRevision.ligneProduit()); + subExecution.setTypeProduit(typeProduit); + subExecution.setClausePropriete(ObjectInfoLoader.getClausePropriete(typeProduit, session)); + subReportParameters.addSubReport("R25-" + generic.getItem().get_item_id(), prepareData(session, subExecution, generic, revisionRulesConfiguration)); + } + catch (EmptyNomenclatureException e) { + genericsDontExistForPU++; + LOGGER.warn("No Bom for generic:" + generic.getItem().get_item_id() + " for PU:" + productUnit.getProductID() + "/" + productUnit.getUnitStr()); + } + } + + if (genericsDontExistForPU == tcGenerics.size()) { + throw new InvalidUserInputException(UserInputErrorEnum.NO_GENERIC_FOUND_FOR_THIS_PU); + } + + return subReportParameters; + } + + private TcRevisionRulesConfiguration revisionRulesConfiguration(final TcSession session, final ExecutionR25 report, final TcProduct productObject, int unit) throws KurtException { + TcRevisionRuleProperties revisionRuleProperties = new TcRevisionRuleProperties(productObject, unit); + TcRevisionRule revisionRule = session.findRevRule(report.getRevisionRule()); + return new TcRevisionRulesConfiguration(revisionRule, revisionRuleProperties); + } + + private PrintParameters prepareData(final TcSession session, final ExecutionR25 report, final TcGeneric tcGeneric, final TcRevisionRulesConfiguration revisionRulesConfiguration) throws KurtException { + LOGGER.debug("PrepareData started on: {}", report.getReportIdentifier().getReportTitle()); + TcBomWindowConfiguration bomWindowConfiguration = new TcBomWindowConfiguration(tcGeneric, revisionRulesConfiguration); + try (TcBomWindow bomWindow = session.createBomWindow(bomWindowConfiguration)) { + BOMLineHolder rfGenericBom = new SingleStructureServiceCaller(session).resolve(bomWindow.topLine(), new R25BOMLineExplorer()); + + // Treatment of the RFGenericBom + ItemRevision rfGeneric = rfGenericBom.getItemRevision(); + report.setRfGenericRev(new RFGenericRevision(session, rfGeneric)); + + for (BOMLineHolder currentChild : rfGenericBom.getBomChilds()) { + ItemRevision itemRevChild = currentChild.getItemRevision(); + String childType = itemRevChild.getTypeObject().getName(); + if (SnecmaObjectTypes.PART_AERO_REVISION.equals(childType)) { + report.getPartNumberRevList().add(new PartAeroRevision(session, itemRevChild)); + } + else if (SnecmaObjectTypes.DESCRIPTIF_REVISION.equals(childType)) { + report.setDescriptifRev(new DescriptifRevision(session, itemRevChild)); + retrieveDocNormAndDocNormStandardLists(session, itemRevChild, report); + retrieveDocTechnicList(session, itemRevChild, report); + } + else if (SnecmaObjectTypes.RF_ADMIN_REVISION.equals(childType)) { + report.setRfAdminRev(new RFAdminRevision(session, itemRevChild)); + report.setFrontiereAvion(report.getRfAdminRev().getFrontiereAvion()); + report.setFrontiereCooperant(report.getRfAdminRev().getFrontiereCooperant()); + } + } + + ItemRevision generivRev = (ItemRevision) bomWindow.topLine().get_bl_line_object(); + String typeGeneric = generivRev.getTypeObject().getName(); + if (SnecmaObjectTypes.GENERIC_REVISION.equals(typeGeneric)) { + report.setGenericRev(new GenericRevision(session, generivRev)); + } + else { + throw new KurtException("Object should be a Generic but is a: " + typeGeneric); + } + + // Specific treatment of DocTechnic + filterDocTechnic(report); + filterForDefinitionCertifiee(report); + PrintParameters printParameters = report.subReportParameters(); + new R25Printer().constructDataMaps(session, printParameters, report); + LOGGER.debug("PrepareData ended on: {}", report.getReportIdentifier().getReportTitle()); + return printParameters; + } + } + + /** + * Returns true if this report execution generated an empty table of documents (no doc found). + * + * @param report - the execution report which provide all informations for the report + * @return true if the table of documents is empty + */ + public boolean isEmptyTable(final ExecutionR25 report) { + return report.getDocNormList().isEmpty() && report.getDocNormStandardList().isEmpty() && report.getDocTechnicList().isEmpty(); + } + + /** + * Retrieve the {@link DocNorm} and the {@link DocNormStandard} in their respective {@link List}s. + * + * @param session {@link TcSession} - the tc session + * @param itemRevision {@link ItemRevision} - the object which possess all the documents + * @param report - the execution report which provide all informations for the report + */ + private void retrieveDocNormAndDocNormStandardLists(final TcSession session, + final ItemRevision itemRevision, final ExecutionR25 report) { + List referenceDoclist = AbstractPart.returnReferenceDocuments(session, itemRevision); + if (!referenceDoclist.isEmpty()) { + for (Item docItem : referenceDoclist) { + if (docItem == null) { + continue; + } + String docType = docItem.getTypeObject().getName(); + String docId = docItem.get_item_id(); + if (SnecmaObjectTypes.DOC_NORM.equals(docType)) { + ItemRevision selectedDocRev = retrieveDocNormAndDocNormStandardRevisions(session, docId); + report.docNormList.add(new DocNorm(session, selectedDocRev)); + } + else if (SnecmaObjectTypes.DOC_NORM_STANDARD.equals(docType)) { + ItemRevision selectedDocRev = retrieveDocNormAndDocNormStandardRevisions(session, docId); + report.docNormStandardList.add(new DocNormStandard(session, selectedDocRev)); + } + } + } + } + + private ItemRevision retrieveDocNormAndDocNormStandardRevisions(final TcSession session, final String docId) { + // Retrieve the revisions + List listOfDocNormRev = new ItemRevisionQuery(session).searchID(docId).findAll(); + // Try to obtain the revision with the latest release date... + Optional selectedDocRev; + selectedDocRev = ObjectInfoHelper.getRevisionFromStatusWithMostRecentReleaseDate(session, listOfDocNormRev, Calendar.getInstance(), + StatusEnum.PUBLISHED, StatusEnum.FROZEN); + if (selectedDocRev.isPresent()) { + return selectedDocRev.get(); + } + else { + // No release date found, now obtain the revision with latest modification date + RevisionStatusAndDate revAndStatus = + ObjectInfoHelper.getRevisionAndStatusWithMostRecentModificationDate(listOfDocNormRev, Calendar.getInstance()); + return revAndStatus.getItemRevision(); + } + } + + /** + * Retrieve the {@link DocTechnic} in a {@link List}. + */ + private void retrieveDocTechnicList(final TcSession session, final ItemRevision partItemRevision, final ExecutionR25 report) { + List technicDocObjects = AbstractPart.returnDefinitionDocuments(session, partItemRevision); + if (!technicDocObjects.isEmpty()) { + for (ItemRevision docTechnicRev : technicDocObjects) { + if (docTechnicRev != null) { + report.docTechnicList.add(new DocTechnic(session, docTechnicRev)); + } + } + } + } + + /** + * Filter the DocTechnic with specific values on the type_doc_technic_1 and type_doc_technic_2 properties. + * + * @param report - the execution report which provide all informations for the report + */ + private void filterDocTechnic(final ExecutionR25 report) { + List transitList = new ArrayList<>(); + for (DocTechnic docTechnic : report.docTechnicList) { + // These values are forbidden + String typeDocTechnic1 = docTechnic.getTypeDocTechnic1(); + String typeDocTechnic2 = docTechnic.getTypeDocTechnic2(); + if (!(REALISATION_ACHIEVEMENT.equals(typeDocTechnic1) + && (MCI_MASSE_CENTRE_DE_GRAVITE.equals(typeDocTechnic2) || REC_DEFINITION.equals(typeDocTechnic2)))) { + transitList.add(docTechnic); + } + } + report.docTechnicList.clear(); + report.docTechnicList.addAll(transitList); + } + + private void filterForDefinitionCertifiee(final ExecutionR25 report) { + if (report.isDefCertifiee()) { + List transitList = new ArrayList<>(); + for (DocTechnic docTechnic : report.getDocTechnicList()) { + // These values are forbidden + if ("Définition / Design".equals(docTechnic.getTypeDocTechnic1())) { + transitList.add(docTechnic); + } + } + report.getDocTechnicList().clear(); + report.getDocTechnicList().addAll(transitList); + } + } +} + + + diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r25report/ExecutionR25.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r25report/ExecutionR25.java new file mode 100644 index 0000000..532ca96 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r25report/ExecutionR25.java @@ -0,0 +1,241 @@ +package com.capgemini.reports.definition.r25report; + +import com.capgemini.framework.common.*; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.builder.R25Builder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal; +import com.capgemini.reports.documentationobjects.DocNorm; +import com.capgemini.reports.documentationobjects.DocNormStandard; +import com.capgemini.reports.documentationobjects.DocTechnic; +import com.capgemini.reports.exceptions.FileLoadingException; +import com.capgemini.reports.exceptions.ReportPrintException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.printing.Printer; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.reports.parameters.checker.ProductChecker; +import com.capgemini.reports.reports.parameters.checker.ProductUnitChecker; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision; +import com.capgemini.reports.snecmaobjects.generic.AbstractGenericRevision; +import com.capgemini.reports.snecmaobjects.part.PartAeroRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.teamcenter.soa.client.model.strong.Item; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +/** + * This class controls the execution of a R25 report. + */ +@Getter +@Setter(value = AccessLevel.PROTECTED) +@EqualsAndHashCode(callSuper = true) +public class ExecutionR25 extends AbstractExecutionReport { + protected static final String FRENCH_LANGUAGE = "Francais"; + private static final long serialVersionUID = -5076506178171189943L; + private static final Logger LOGGER = LoggerFactory.getLogger(ExecutionR25.class); + // Policies + private static final PolicyLocation R25_POLICY_XML_FULL = PolicyLocation.make("R25_policy_full", "/xml/policies/r25report/R25_policy_full.xml"); + private static final PolicyLocation R25_POLICY_XML_LIGHT = PolicyLocation.make("R25_policy_light", "/xml/policies/r25report/R25_policy_light.xml"); + // Priority parameter + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R25); + // Revision rule parameter + private static final String REPORT_REVISION_RULE = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R25", DEFAULT_REVISION_RULE); + // Launch type parameter + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R25"); + // Configuration + private static final String FILE_SEPARATOR = "_"; + private static final String PATTERN_DATE = "dd-MM-yyyy"; + // Report parameters + protected final boolean french; + protected final String frenchInput; + // Documents gathered + protected final List docNormList = new ArrayList<>(); + protected final List docNormStandardList = new ArrayList<>(); + protected final List docTechnicList = new ArrayList<>(); + // Raw input parameters + protected final ProductUnit productUnit; + protected final Item genericItem; + // Internal working data + protected final String typeImpression; + protected final boolean isDefCertifiee; + // Data gathered + protected String dateReleased = ""; + protected String revisionArticle = ""; + protected String typeProduit; + protected String clausePropriete; + protected RFGenericRevision rfGenericRev; + // Data gathered + protected AbstractGenericRevision genericRev; + protected List partNumberRevList = new ArrayList<>(); + protected RFAdminRevision rfAdminRev; + protected DescriptifRevision descriptifRev; + protected String frontiereAvion = ""; + protected String frontiereCooperant = ""; + private String productLine; + + /** + * Constructor. + * + * @param produitUnit {@link ProductUnit} - the Product id and the Unit range. + * @param typeImpression {@link String} - the type of impression of the report + * @param langage {@link String} - the language selected by the user + */ + public ExecutionR25(final ProductUnit produitUnit, final String typeImpression, final String langage) { + this(produitUnit, null, typeImpression, langage); + } + + public ExecutionR25(final ProductUnit produitUnit, final Item generic, final String typeImpression, final String langage) { + super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE); + this.genericItem = generic; + this.frenchInput = langage; + this.french = isFrench(langage); + this.productUnit = produitUnit; + this.isDefCertifiee = "Def_certifiee".equals(typeImpression); + this.typeImpression = typeImpression; + } + + protected static boolean isFrench(final String language) { + return FRENCH_LANGUAGE.equals(language); + } + + @Override + public List getLaunchData() { + List theCriteria = new ArrayList<>(); + theCriteria.add(new MngCriteriaVal.CriteriaValue(ReportCriteriaEnum.PRODUCT, productUnit.getProductID())); + theCriteria.add(new MngCriteriaVal.CriteriaValue(ReportCriteriaEnum.UNIT, productUnit.getUnitStr())); + theCriteria.add(new MngCriteriaVal.CriteriaValue(ReportCriteriaEnum.TYPE_IMPRESSION, typeImpression)); + theCriteria.add(new MngCriteriaVal.CriteriaValue(ReportCriteriaEnum.LANGUAGE, frenchInput)); + return theCriteria; + } + + @Override + public List getQuickChecks() { + ArrayList quickChecks = new ArrayList<>(); + quickChecks.add(new ProductChecker(productUnit.getProductID())); + if (!productUnit.getUnitStr().isEmpty()) { + quickChecks.add(new ProductUnitChecker(productUnit)); + } + return quickChecks; + } + + @Override + public String getTemplateLocation() { + return JasperTemplate.TEMPLATE_R25.getFilepath(); + } + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R25_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R25_POLICY_XML_FULL; + } + + @Override + public List getLongChecks() { + return new ArrayList<>(); + } + + @Override + public ReportEnum getReportIdentifier() { + return ReportEnum.REPORT_R25; + } + + /** + * Format file expected : R25_"Critère produit"_"Ligne produit"_"Critère Unit"_"générique traité"_"date_système".XLSX + */ + private String getSubReportFileName() { + return setFileName(true).toString(); + } + + /** + * Format file expected : R25_"Critère produit"_"Ligne produit"_"Critère Unit"_"date_système".zip + * + * @return zip filename + */ + @Override + public String getSpecifiedFileName() { + return setFileName(false).toString(); + } + + private StringBuilder setFileName(Boolean addItemId) { + StringBuilder filename = new StringBuilder("R25").append(FILE_SEPARATOR); + filename.append(productUnit.getProductID()).append(FILE_SEPARATOR); + filename.append(productLine.replaceAll(StringHelper.REGEXP_ALPHANUM, " ")).append(FILE_SEPARATOR); + if (!productUnit.getUnitStr().isEmpty()) { + filename.append(productUnit.getUnitStr()).append(FILE_SEPARATOR); + } + if (addItemId) { + filename.append(genericItem.get_item_id()).append(FILE_SEPARATOR); + } + filename.append(TeamcenterDateFormatter.formatCalendarToPattern(Calendar.getInstance(), PATTERN_DATE)); + + return filename; + } + + @Override + public Printer getPrinter() { + return new Printer(Printer.AvailablePrinter.ZIP); + } + + @Override + public Printer.PrintFormat getPrintingFormat() { + return Printer.PrintFormat.XLSX; + } + + @Override + public IDataReportPreparator getDataPreparator() { + return new DataReportPreparatorR25(); + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return new ExecutionR25(productUnit, typeImpression, frenchInput); + } + + @Override + public Class getReportBuilderClass() { + return R25Builder.class; + } + + public PrintParameters reportParameters() { + return new PrintParameters(Printer.PrintFormat.ZIP, getFileNameOnDisc(), ReportFolderOutputHelper.getStorageFolderLocation(getLaunchType())); + } + + public PrintParameters reportSubZipParameters() { + return new PrintParameters(Printer.PrintFormat.ZIP, getSpecifiedFileName(), ReportFolderOutputHelper.getStorageFolderLocation(getLaunchType())); + } + + public PrintParameters subReportParameters() throws ReportPrintException, FileLoadingException { + String storageFolder = ReportFolderOutputHelper.getStorageFolderLocation(getLaunchType()); + String templateLocation = getTemplateLocation(); + try (InputStream templateStream = ResourceHelper.getResourceAsStream(templateLocation)) { + PrintParameters printParameters = PrintParameters.createMainReport(getPrintingFormat(), getSubReportFileName(), storageFolder, templateStream); + printParameters.setReportTitle(getReportIdentifier().getReportTitle()); + return printParameters; + } catch (IOException e) { + LOGGER.error("Unable to close the template file properly from " + templateLocation, e); + return null; // IOException is only thrown by close() which, if it ever fails, means you have much bigger problems! + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r25report/R25BOMLineExplorer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r25report/R25BOMLineExplorer.java new file mode 100644 index 0000000..20d5ef5 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r25report/R25BOMLineExplorer.java @@ -0,0 +1,33 @@ +package com.capgemini.reports.definition.r25report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.resolution.filtering.ITcTypeFilter; +import com.capgemini.framework.teamcenter.resolution.filtering.TcTypeInclusionFilter; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderHelper; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.MalformedNomenclatureException; +import com.capgemini.reports.teamcenter.resolution.IBOMLineExplorer; +import com.capgemini.reports.teamcenter.resolution.structureservice.SingleStructureServiceCaller; + +/** + * Explorer of {@link BOMLineHolder}s used in {@link SingleStructureServiceCaller} for R24 report.
+ * Thanks to this class, the SINGLE resolution structure could carry on and the Part Number could be taken.
+ * The Rf Generic is returned, and its children Part Aero / RF Admin and Descriptif are loaded + */ +public class R25BOMLineExplorer implements IBOMLineExplorer { + + private static final ITcTypeFilter FILTER_PART_ADMIN_DESCRIPTION = new TcTypeInclusionFilter(SnecmaObjectTypes.PART_AERO_REVISION, SnecmaObjectTypes.RF_ADMIN_REVISION, SnecmaObjectTypes.DESCRIPTIF_REVISION); + private static final ITcTypeFilter FILTER_RF_GENERIC_REVISION = new TcTypeInclusionFilter(SnecmaObjectTypes.RF_GENERIC_REVISION); + + @Override + public BOMLineHolder explore(TcSession session, final SingleStructureServiceCaller.SingleLevelExpander expander, final BOMLineHolder genericBom) throws EmptyNomenclatureException, + InvalidInputException, MalformedNomenclatureException { + BOMLineHolder expandedGenericBom = expander.expand(genericBom, FILTER_RF_GENERIC_REVISION); + BOMLineHolder rfGeneric = BOMLineHolderHelper.findRfGenericBL(expandedGenericBom); + return expander.expand(rfGeneric, FILTER_PART_ADMIN_DESCRIPTION); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r25report/R25Printer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r25report/R25Printer.java new file mode 100644 index 0000000..423b748 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r25report/R25Printer.java @@ -0,0 +1,230 @@ +package com.capgemini.reports.definition.r25report; + +import com.capgemini.framework.common.LanguageHelper; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.reports.definition.r15r16r17reports.AbstractExecutionR15R16R17; +import com.capgemini.reports.definition.r15r16r17reports.CommunR15R16R17ComponentVisitor; +import com.capgemini.reports.definition.r15r16r17reports.R15R16R17R24R25Keys; +import com.capgemini.reports.definition.r15r16r17reports.R15R16R17R24R25Keys.Page2; +import com.capgemini.reports.documentationobjects.DocNorm; +import com.capgemini.reports.documentationobjects.DocNormStandard; +import com.capgemini.reports.documentationobjects.DocTechnic; +import com.capgemini.reports.execution.mapconstructor.AbstractStaticTemplateMapConstructor; +import com.capgemini.reports.execution.mapconstructor.IMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.snecmaobjects.part.PartAeroRevision; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +/** + * This class is able to put the data gathered by an {@link ExecutionR25} into some {@link PrintParameters} for printing. + */ +@Slf4j +public class R25Printer extends AbstractStaticTemplateMapConstructor implements IMapConstructor { + private static final long serialVersionUID = -789205459094400840L; + + private static final String N_A = "N/A"; + + private static final String EMPTY_STRING = StringHelper.EMPTY; + private static final String UNKNOWN_STR = "???"; + private static final String SANS_OBJET = "Sans objet"; + private static final String NOT_APPLICABLE = "Not applicable "; + + private static String french(final String string) { + return LanguageHelper.french(string); + } + + private static String english(final String string) { + return LanguageHelper.english(string); + } + + /** + * Puts the data gathered by an {@link AbstractExecutionR15R16R17} into some {@link PrintParameters} for printing. + * + * @param execution the data-bearing {@link AbstractExecutionR15R16R17} + * @param mainReport the {@link PrintParameters} + */ + private void print(final ExecutionR25 execution, final PrintParameters mainReport) { + // first put generic data + DataReportPreparatorR25 preparator = (DataReportPreparatorR25) execution.getDataPreparator(); + mainReport.addReportParameters(setupStringParameters(execution)); + mainReport.addReportParameter(R15R16R17R24R25Keys.EMPTY_TABLE.toString(), preparator.isEmptyTable(execution)); + mainReport.addReportParameters(addDescriptifParameters(execution)); + mainReport.addReportDataFromEnum(setupData(execution)); + + // Now add the specific stuff + addOptionalParameters(execution, mainReport); + } + + private Map addDescriptifParameters(final ExecutionR25 execution) { + Map params = new EnumMap<>(Page2.class); + if (execution.descriptifRev != null) { + params.put(Page2.REF_DESCRIPTIF, execution.descriptifRev.getItemId()); + params.put(Page2.REV_DESCRIPTIF, execution.descriptifRev.getRevisionId()); + if (execution.descriptifRev.hasStatus(StatusEnum.J3B)) { + params.put(Page2.STATUS, StatusEnum.J3B.getIdentifier()); + } + else { + params.put(Page2.STATUS, StatusEnum.EFFECTIVITY.getIdentifier()); + } + if (execution.descriptifRev.hasStatus(StatusEnum.CREATED)) { + params.put(Page2.MATURITY_STATUS, StatusEnum.CREATED.getIdentifier()); + } + else if (execution.descriptifRev.hasStatus(StatusEnum.DEF_READY)) { + params.put(Page2.MATURITY_STATUS, StatusEnum.DEF_READY.getIdentifier()); + } + else if (execution.descriptifRev.hasStatus(StatusEnum.DEF_APPROVED)) { + params.put(Page2.MATURITY_STATUS, StatusEnum.DEF_APPROVED.getIdentifier()); + } + else { + params.put(Page2.MATURITY_STATUS, EMPTY_STRING); + } + } + else { + params.put(Page2.REF_DESCRIPTIF, EMPTY_STRING); + params.put(Page2.REV_DESCRIPTIF, EMPTY_STRING); + params.put(Page2.STATUS, EMPTY_STRING); + params.put(Page2.MATURITY_STATUS, EMPTY_STRING); + } + return params; + } + + private Map setupStringParameters(final ExecutionR25 execution) { + Map params = new EnumMap<>(R15R16R17R24R25Keys.class); + params.put(R15R16R17R24R25Keys.CLAUSE_PROPRIETE, execution.getClausePropriete()); + params.put(R15R16R17R24R25Keys.PRODUCT_TYPE, execution.getTypeProduit()); + params.put(R15R16R17R24R25Keys.REPORT_TITLE, getTitle()); + params.put(R15R16R17R24R25Keys.ITEM_REVISION_ID, execution.getRevisionArticle()); + String dateReleased = execution.getDateReleased(); + params.put(R15R16R17R24R25Keys.RELEASE_DATE, execution.isFrench() ? french(dateReleased) : english(dateReleased)); + return params; + } + + private List> setupData(final ExecutionR25 execution) { + List> dataTable = new ArrayList<>(); + boolean isFrench = execution.isFrench(); + for (DocNorm norm : execution.getDocNormList()) { + dataTable.add(getDocNormLine(norm, isFrench)); + + } + for (DocNormStandard normStd : execution.getDocNormStandardList()) { + dataTable.add(getDocNormStandardLine(normStd, isFrench)); + } + for (DocTechnic technic : execution.getDocTechnicList()) { + dataTable.add(getDocTechnicLine(technic, isFrench)); + } + + // If there are no documents, add an empty line to provoke band printing + if (dataTable.isEmpty()) { + Map line = new EnumMap<>(Page2.class); + line.put(Page2.DOC_NUMBER, "(No document found)"); + line.put(Page2.ISSUE, N_A); + line.put(Page2.DOC_TYPE, N_A); + line.put(Page2.DOC_TITLE, N_A); + dataTable.add(line); + } + return dataTable; + } + + private Map getDocNormLine(final DocNorm docNorm, final boolean isFrench) { + String idOrigine = docNorm.getIdOrigine(); + Map line = new EnumMap<>(Page2.class); + line.put(Page2.DOC_NUMBER, (idOrigine == null || idOrigine.isEmpty()) ? docNorm.getDocId() : idOrigine); + line.put(Page2.ISSUE, "-"); + String typeDocNorm = docNorm.getTypeDocNorm(); + line.put(Page2.DOC_TYPE, isFrench ? french(typeDocNorm) : english(typeDocNorm)); + line.put(Page2.DOC_TITLE, isFrench ? docNorm.getItemName() : docNorm.getDesignationEn()); + return line; + } + + private Map getDocNormStandardLine(final DocNormStandard normStd, final boolean isFrench) { + Map line = new EnumMap<>(Page2.class); + String idOrigine = normStd.getIdOrigine(); + line.put(Page2.DOC_NUMBER, (idOrigine == null || idOrigine.isEmpty()) ? normStd.getDocId() : idOrigine); + line.put(Page2.ISSUE, "-"); + line.put(Page2.DOC_TYPE, isFrench ? "Norme pour articles standards" : "Norm for standards items"); + line.put(Page2.DOC_TITLE, isFrench ? normStd.getItemName() : normStd.getDesignationEn()); + return line; + } + + private Map getDocTechnicLine(final DocTechnic technic, final boolean isFrench) { + Map line = new EnumMap<>(Page2.class); + String idOrigine = technic.getIdOrigine(); + line.put(Page2.DOC_NUMBER, (idOrigine == null || idOrigine.isEmpty()) ? technic.getDocId() : idOrigine); + line.put(Page2.ISSUE, technic.getIndice()); + + String typeDocTechnic1 = technic.getTypeDocTechnic1(); + String type1 = isFrench ? french(typeDocTechnic1) : english(typeDocTechnic1); + String typeDocTechnic2 = technic.getTypeDocTechnic2(); + String type2 = isFrench ? french(typeDocTechnic2) : english(typeDocTechnic2); + line.put(Page2.DOC_TYPE, type1 + " / " + type2); + + line.put(Page2.DOC_TITLE, isFrench ? technic.getName() : technic.getDesignationEn()); + return line; + } + + private void addOptionalParameters(final ExecutionR25 execution, final PrintParameters mainReport) { + Map params = new EnumMap<>(R15R16R17R24R25Keys.class); + List partNumberRevList = execution.getPartNumberRevList(); + if (partNumberRevList != null && !partNumberRevList.isEmpty()) { + Map map = new EnumMap<>(R15R16R17R24R25Keys.class); + if (partNumberRevList.size() == 1) { + map = partNumberRevList.get(0).accept(getVisitor(execution.isFrench())); + map.remove(R15R16R17R24R25Keys.PART_VERSION); + } + else { + map.put(R15R16R17R24R25Keys.ITEM_ID, UNKNOWN_STR); + map.put(R15R16R17R24R25Keys.PART_NUMBER, UNKNOWN_STR); + map.put(R15R16R17R24R25Keys.MANUFACTURER_CODE, UNKNOWN_STR); + map.put(R15R16R17R24R25Keys.FRENCH_DESIGNATION, UNKNOWN_STR); + map.put(R15R16R17R24R25Keys.ENGLISH_DESIGNATION, UNKNOWN_STR); + map.put(R15R16R17R24R25Keys.OBTURATION, execution.isFrench() ? SANS_OBJET : NOT_APPLICABLE); + map.put(R15R16R17R24R25Keys.CLASSIFICATION, "-"); + map.put(R15R16R17R24R25Keys.FIELD_OPN_SERIALISATION, UNKNOWN_STR); + map.put(R15R16R17R24R25Keys.LOG_DOCUMENT, execution.isFrench() ? SANS_OBJET : NOT_APPLICABLE); + } + map.put(R15R16R17R24R25Keys.PART_VERSION, EMPTY_STRING); + params.putAll(map); + } + else { + params.putAll(execution.getGenericRev().accept(getVisitor(execution.isFrench()))); + } + params.put(R15R16R17R24R25Keys.MT_NUMBER, EMPTY_STRING); + params.put(R15R16R17R24R25Keys.PREVIOUS_RELEASE_DATE, EMPTY_STRING); + params.put(R15R16R17R24R25Keys.ITEM_ID, execution.getGenericItem().get_item_id()); + mainReport.addReportParameters(params); + + Map map = new EnumMap<>(R15R16R17R24R25Keys.SpecificR15R16.class); + boolean isFrench = execution.isFrench(); + String frontiereAvion = execution.getFrontiereAvion(); + map.put(R15R16R17R24R25Keys.SpecificR15R16.INSTALLATION_INTERFACE, isFrench ? french(frontiereAvion) : english(frontiereAvion)); + String frontiereCooperant = execution.getFrontiereCooperant(); + map.put(R15R16R17R24R25Keys.SpecificR15R16.PARTNER_INTERFACE, isFrench ? french(frontiereCooperant) : english(frontiereCooperant)); + map.put(R15R16R17R24R25Keys.SpecificR15R16.PRODUCT_UNIT, execution.getProductUnit().toString()); + mainReport.addReportParameters(map); + mainReport.addReportParameter(R15R16R17R24R25Keys.SpecificR15R16.IS_PREVIOUS_DEF.toString(), false); + } + + private String getTitle() { + return StringHelper.EMPTY; + } + + private IComponentVisitor> getVisitor(final boolean isFrench) { + return new CommunR15R16R17ComponentVisitor(isFrench); + } + + @Override + public void constructDataMaps(TcSession session, final PrintParameters printParameters, final ExecutionR25 data) throws KurtException { + long start = System.currentTimeMillis(); + this.print(data, printParameters); + log.trace("Execution time : {} ms for {}", System.currentTimeMillis() - start, "data filtering"); + } +} \ No newline at end of file diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/DataReportPreparatorR26.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/DataReportPreparatorR26.java new file mode 100644 index 0000000..24d0868 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/DataReportPreparatorR26.java @@ -0,0 +1,232 @@ +package com.capgemini.reports.definition.r26report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.SnecmaObjectProperties; +import com.capgemini.framework.teamcenter.object.pom.status.TcEffectivity; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObjectFactory; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRule; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRuleProperties; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindow; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindowConfiguration; +import com.capgemini.framework.teamcenter.object.runtime.TcRevisionRulesConfiguration; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemQuery; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.definition.r26report.ExecutionR26.ReportDataR26; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.filter.AllIsGoodFilter; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.teamcenter.queries.TypeQuery; +import com.capgemini.reports.teamcenter.resolution.structureservice.SingleStructureServiceCaller; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.RevisionRule; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * This class will allow to prepare data and findAll back data for making report R26. + */ +public class DataReportPreparatorR26 implements IDataReportPreparator { + + private static final long serialVersionUID = -8429205549743626211L; + + private static final Logger LOGGER = LoggerFactory.getLogger(DataReportPreparatorR26.class); + + @Override + public String print(TcSession session, ExecutionR26 execution, IExecutionStrategy executionStrategy) throws KurtException { + PrintParameters printParameters = prepareData(session, execution); + executionStrategy.print(printParameters, execution); + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + } + + private PrintParameters prepareData(final TcSession session, final ExecutionR26 report) throws KurtException { + LOGGER.debug("PrepareData started on: {}", report.getReportIdentifier().getReportTitle()); + + String componentId = report.getComponent(); + + List items = new ItemQuery(session).searchID(componentId).findAll(); + if(items.isEmpty()){ + throw new InvalidUserInputException(UserInputErrorEnum.OBJECT_DOES_NOT_EXIST); + } + + Item item = null; + + // Depuis qu'il est possible d'avoir le meme item id sur une part et un document il faut parcourir la liste pour + // ne récuperer que l'objet part. + for(Item currentItem : items) { + if(SnecmaObjectTypes.isPart(currentItem.getTypeObject().getName())) { + item = currentItem; + break; + } + } + + if(item == null) { + throw new InvalidUserInputException(UserInputErrorEnum.THE_SELECTED_OBJECT_IS_NOT_PERMITTED_ON_THIS_REPORT); + } + + session.loadProperties(item, SnecmaObjectProperties.OBJECT_TYPE); + + List list = TypeQuery.getRevisionRule(session, report.getRevisionRule()); + RevisionRule reportRevisionRule = list.get(0); + + String revisionRuleNameForThisR26 = "R26_" + componentId + "_" + report.getReportTechnicalUid(); + try { + RevisionRuleManager revisionRuleManager = new RevisionRuleManager(session, reportRevisionRule, revisionRuleNameForThisR26); + LineManager lineManager = new LineManager(session, report, revisionRuleManager); + + session.setObjectPropPolicy(report.getFullPolicy()); + + EffectivityDate effectivityDate = report.getEffectivityDate(); + TcRevisionRuleProperties revisionRuleProperties = new TcRevisionRuleProperties(effectivityDate.isNow() ? null : effectivityDate.getDateTime()); + TcRevisionRule revisionRule = session.findRevRule(report.getRevisionRule()); + TcRevisionRulesConfiguration revRulesConfiguration = new TcRevisionRulesConfiguration(revisionRule, revisionRuleProperties); + List firstLevelParents = session.whereUsed(resolveGoodRevision(session, report, item, revRulesConfiguration), 1, reportRevisionRule); + + for (ItemRevision firstLevelParentRev : firstLevelParents) { + session.loadProperties(firstLevelParentRev, "object_name","item_revision_id","item_revision"); + LOGGER.info("=== Treating object at level 1: {}/{} ===",firstLevelParentRev.get_item_id(),firstLevelParentRev.get_item_revision_id()); + List secondLevelParents = session.whereUsed(firstLevelParentRev, 1, reportRevisionRule); + if (secondLevelParents.isEmpty()) { + LOGGER.debug("Second Level empty"); + if (SnecmaObjectTypes.isPartRevision(firstLevelParentRev.getTypeObject().getName())) { + // si il n'y a pas de second level alors pas d'effectivité, ni produit, ni module + // cf: SFD:5.8.3 Remontée de nomenclature + if (lineManager.bomLineExists(firstLevelParentRev, componentId)) { + // cas où plusieurs révisions disponibles: une seule est valide avec la règle de révision du R26 + lineManager.addLines(firstLevelParentRev, null, null, null, "", + false, false); + } + } + else { + // Le composant n'est pas lié à un RF à Date valide (donc lié à un RF à Date obsolète) -> la ligne de nomenclature n'est pas traitée + // Ou il est lié à un RF en PU -> la ligne de nomenclature est traitée + + Map tcEffectivities = EffectivityHelper.getEffectivitiesWithUnitRange(session, + firstLevelParentRev); + + // récupérer les effectivitées + for (Map.Entry currentTcEff : tcEffectivities.entrySet()) { + + int[] units = currentTcEff.getKey().unitNumbers(); + Item product = currentTcEff.getKey().endItem(); + String productItemId = product.get_item_id(); + + session.loadProperties(product, "revision_list", "item_revision"); + ProductRevision productRev = new ProductRevision(session, (ItemRevision) (product.get_revision_list()[0])); + + // remonter au Generic avec DMA Configuration Interface Product Unit + revisionRuleManager.setProductUnitRevisionRuleProperties(product.getUid(), units[0]); + secondLevelParents = session.whereUsed(firstLevelParentRev, 1, revisionRuleManager.getRevisionRule()); + + LOGGER.info("=== Launching DMA Configuration Interface Product Unit on part {}/{} with Product {}/{} Unit {} ",firstLevelParentRev.get_item_id(),firstLevelParentRev.get_item_revision(),product.get_item_id(),product.get_item_revision(),units[0]); + + LOGGER.info("We found {} parents", secondLevelParents.size()); + + Map> itemRangeMap = new HashMap<>(); + + for (ItemRevision currentParent : secondLevelParents) { + + LOGGER.info("checking parent {}/{}",currentParent.get_item_id(),currentParent.get_item_revision_id()); + + if (SnecmaObjectTypes.isGenericRevision(currentParent.getTypeObject().getName())) { + LOGGER.debug("Currently on generic {}/{} ",currentParent.get_item_id(),currentParent.get_item_revision_id()); + // récupère les effectivités valide + String effectivityRangeUnit = EffectivityHelper.calculateEffectivity(session, firstLevelParentRev, product, itemRangeMap); + + if (EffectivityHelper.isEffectivityMatches(session, currentTcEff.getKey(), currentParent)) { + // tester si le composant est non standard + if (!item.get_object_type().equals(SnecmaObjectTypes.STANDARD)) { + LOGGER.debug("Effectivity matches {} {} ", currentTcEff.getKey().endItem(), currentTcEff.getKey().unitNumbers()); + boolean productFound = lineManager.findProduct(revisionRuleManager.getRevisionRule(), productItemId, currentParent); + lineManager.addLines(currentParent, firstLevelParentRev, productRev, currentParent, + effectivityRangeUnit, productFound, true); + } else { + // The Component is a standard. We will not check that the product consume the component. + lineManager.addLines(currentParent, firstLevelParentRev, productRev, currentParent, + effectivityRangeUnit, false, true); + } + } else { + LOGGER.debug("Effectivity doesn't matches {} ", currentTcEff.getKey().unitNumbers()); + } + } else if(!SnecmaObjectTypes.isSuperModelRevision(currentParent.getTypeObject().getName())){ + // remonter au dernier Generic trouvé + Map generics = new HashMap<>(); + lineManager.addGenerics(generics, currentParent, currentTcEff.getKey(), productItemId, item); + + // récupère les effectivités valide + String effectivityRangeUnit = EffectivityHelper.calculateEffectivity(session, firstLevelParentRev, product, itemRangeMap); + + lineManager.manageGenerics(generics, firstLevelParentRev, currentParent, productRev, + effectivityRangeUnit, true); + } + } + } + } + } + else { + LOGGER.debug("Navigate second level"); + for (ItemRevision secondLevelParentRev : secondLevelParents) { + + List rfPUs = RfPUManager.getRfPURevisions(session, reportRevisionRule, secondLevelParentRev); + for (ItemRevision currentRfPU : rfPUs) { + lineManager.manageRfPU(firstLevelParentRev, secondLevelParentRev, currentRfPU, item); + } + + if (rfPUs.isEmpty() && SnecmaObjectTypes.isPartRevision(secondLevelParentRev.getTypeObject().getName()) + && lineManager.bomLineExists(secondLevelParentRev, firstLevelParentRev.get_item_id())) { + + if (SnecmaObjectTypes.isPartRevision(firstLevelParentRev.getTypeObject().getName())) { + // Pas de RF, le Récepteur est une Part + lineManager.addLines(firstLevelParentRev, null, null, null, + report.getEffectivityDate().formatAsInputCriteria(), false, false); + } + else { + // Le récepteur est une part et le RF est à date + lineManager.addLines(secondLevelParentRev, firstLevelParentRev, null, null, + report.getEffectivityDate().formatAsInputCriteria(), false, false); + } + } + } + } + } + + ReportDataR26 reportDataR26 = new ReportDataR26(lineManager.getR26BomLines()); + reportDataR26.setStandard(item.get_object_type().equals(SnecmaObjectTypes.STANDARD)); + LOGGER.debug("The component is a standard = {}", reportDataR26.isStandard()); + R26Printer printer = new R26Printer(); + PrintParameters printParameters = printer.makeMasterTemplate(report, reportDataR26); + printer.constructDataMaps(session, printParameters, reportDataR26); + LOGGER.debug("PrepareData ended on: {}", report.getReportIdentifier().getReportTitle()); + return printParameters; + } + finally { + // Suppression de la règle de révision créée pour ce Rapport R26 + List revisionRuleList = TypeQuery.getRevisionRule(session, revisionRuleNameForThisR26); + if (!revisionRuleList.isEmpty()) { + session.deleteObjects(revisionRuleList.get(0)); + } + } + } + + private ItemRevision resolveGoodRevision(TcSession session, ExecutionR26 report, Item item, TcRevisionRulesConfiguration revRulesConfiguration) throws KurtException { + TcBomObject topLineObject = new TcBomObjectFactory(session, item).create(); + TcBomWindowConfiguration tcBomWindowConfiguration = new TcBomWindowConfiguration(topLineObject, revRulesConfiguration); + try (TcBomWindow bomWindow = session.createBomWindow(tcBomWindowConfiguration)) { + session.setObjectPropPolicy(report.getFullPolicy()); + BOMLineHolder unbuiltTopLine = new SingleStructureServiceCaller(session).resolve(bomWindow.topLine(), new AllIsGoodFilter()); + return unbuiltTopLine.getItemRevision(); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/EffectivityHelper.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/EffectivityHelper.java new file mode 100644 index 0000000..63f88e7 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/EffectivityHelper.java @@ -0,0 +1,205 @@ +package com.capgemini.reports.definition.r26report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.pom.status.TcEffectivity; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Effectivity; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.ReleaseStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Helper for Effectivity for making report R26. + */ +class EffectivityHelper { + private static final int BORNE_SUP = 2147483646; + + private static final Logger LOGGER = LoggerFactory.getLogger(EffectivityHelper.class); + + /** + * Retourne true si l'effectivité "tcEffectivity" est comprise dans une des effectivités de l'item revision. + */ + static boolean isEffectivityMatches(TcSession session, TcEffectivity tcEffectivity, ItemRevision itemRevision) { + boolean effectivityMatches = false; + + Map tcEffectivities = getEffectivitiesWithUnitRange(session, itemRevision); + for (Map.Entry currentEff : tcEffectivities.entrySet()) { + int[] currentEffUnits = currentEff.getKey().unitNumbers(); + + LOGGER.debug(" Checking effectivity {} of {}",currentEffUnits ,itemRevision.get_item_id()); + + if (tcEffectivity.endItem().equals(currentEff.getKey().endItem())) { + int[] tcEffUnits = tcEffectivity.unitNumbers(); + if ((currentEffUnits.length == 1 && currentEffUnits[0] <= tcEffUnits[0]) + || + (currentEffUnits.length == 2 + && currentEffUnits[0] <= tcEffUnits[0] + && tcEffUnits[0] <= currentEffUnits[1])) { + effectivityMatches = true; + break; + } + } + } + + return effectivityMatches; + } + + /** + * Retourne la liste des effectivités trouvées sur les statuts avec les units concernés. + */ + static Map getEffectivitiesWithUnitRange(TcSession session, ItemRevision itemRevision) { + Map tcEffectivities = new HashMap<>(); + + // récuperer les effectivitées + Map statuses = getReleaseStatuses(session, itemRevision); + for (Map.Entry currentStatus : statuses.entrySet()) { + for (ModelObject currentEff : currentStatus.getKey().get_effectivities()) { + // pour chacune récupérer l'object tcEffectivity + TcEffectivity tcEffectivity = new TcEffectivity(session, (Effectivity) currentEff); + if (!tcEffectivity.unitRange().isEmpty()) { + tcEffectivities.put(tcEffectivity, currentStatus.getValue()); + } + } + } + return tcEffectivities; + } + + /** + * Retourne les status Effectivity de toutes les révisions de l'objet parent de la révision passée en paramètre. + * + * @param session, la session courante + * @param itemRevision, l'item révision courant + */ + private static Map getReleaseStatuses(TcSession session, ItemRevision itemRevision) { + Map statuses = new HashMap<>(); + + getReleaseStatus(session, itemRevision, statuses); + + return statuses; + } + + private static void getReleaseStatus(TcSession session, ItemRevision itemRevision, Map statuses) { + + session.loadProperties(itemRevision, "release_status_list"); + for (ReleaseStatus status : itemRevision.get_release_status_list()) { + + session.loadProperties(status, "name"); + if (status.get_name().equals("Effectivity")) { + statuses.put(status, itemRevision); + } + } + } + + /** + * Retourne true si au moins une des effectivités est en Produit-Unit, false sinon. + * + * @param session, session courante + * @param statuses, status + */ + static boolean isEffectivityWithUnitRange(TcSession session, ReleaseStatus[] statuses) { + // récuperer les effectivitées + for (ReleaseStatus currentStatus : statuses) { + for (ModelObject currentEff : currentStatus.get_effectivities()) { + // pour chacune récupérer le produit et la page de unit + Effectivity effectivity = (Effectivity) currentEff; + session.loadProperties(effectivity, "unit_range_text"); + String unitRange = effectivity.get_unit_range_text(); + + if (!unitRange.isEmpty()) { + return true; + } + } + } + return false; + } + + /** + * Retourne les effectivités des statuts Effectivity. + * + * @param statuses, status + */ + static ModelObject[] getEffectivities(ReleaseStatus[] statuses) { + for (ReleaseStatus releaseStatus : statuses) { + if (releaseStatus.get_name().equals("Effectivity")) { + return releaseStatus.get_effectivities(); + } + } + return new ModelObject[0]; + } + + private static List getEffectivitiesOfAllItemRev(TcSession session, ItemRevision itemRevision, Item product) { + List rangeList = new ArrayList<>(); + + // récuperer les effectivitées + for (ModelObject currentModelObject : itemRevision.get_revision_list()) { + ItemRevision currentItemRev = (ItemRevision) currentModelObject; + session.loadProperties(currentItemRev, "release_status_list"); + for (ReleaseStatus status : currentItemRev.get_release_status_list()) { + + for (ModelObject currentEff : status.get_effectivities()) { + // pour chacune récupérer l'object tcEffectivity + TcEffectivity tcEffectivity = new TcEffectivity(session, (Effectivity) currentEff); + + if (!tcEffectivity.unitRange().isEmpty() && tcEffectivity.endItem().equals(product)) { + int[] unitNumbers = tcEffectivity.unitNumbers(); + int end = (unitNumbers.length == 2) ? unitNumbers[1] : BORNE_SUP; + rangeList.add(new Range(currentItemRev, unitNumbers[0], end)); + } + } + } + } + + List newRangeList = new ArrayList<>(); + boolean found = false; + for (Range range_1 : rangeList) { + for (Range range_2 : rangeList) { + if (range_1 != range_2 && range_1.borneInf() == range_2.borneInf() && range_1.borneSup() == range_2.borneSup()) { + if (!RfPUManager.isLastReleasedRfPURev(session, range_1.getItemRevion())) { + found = true; + break; + } + } + } + if (!found) { + newRangeList.add(range_1); + } + found = false; + } + + return newRangeList; + } + + static String calculateEffectivity(TcSession session, ItemRevision itemRevision, Item product, Map> itemRangeMap) { + + List rangeList = itemRangeMap.get(itemRevision.get_item_id()); + if(rangeList == null) { + rangeList = new ArrayList<>(); + LOGGER.debug("Effectivities ranges: "); + for (Range eff : getEffectivitiesOfAllItemRev(session, itemRevision, product)) { + rangeList.add(new Range(eff.getItemRevion().get_item_revision_id(), eff.borneInf(), eff.borneSup())); + LOGGER.debug("range {}/{} {} {}",eff.getItemRevion().get_item_id(),eff.getItemRevion().get_item_revision_id(), eff.borneInf(), eff.borneSup()); + } + + Collections.sort(rangeList, new Comparator() { + public int compare(Range r1, Range r2) { + return Integer.compare(r1.borneInf(), r2.borneInf()); + } + }); + + itemRangeMap.put(itemRevision.get_item_id(),rangeList); + } + + + + return new Ranges(rangeList).toString(itemRevision.get_item_revision_id()); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/ExecutionR26.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/ExecutionR26.java new file mode 100644 index 0000000..cb4c4d4 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/ExecutionR26.java @@ -0,0 +1,167 @@ +package com.capgemini.reports.definition.r26report; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.builder.R26Builder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.definition.r26report.ExecutionR26.ReportDataR26; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.reports.parameters.checker.ObjectTypeChecker; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +/** + * Class responsible for executing a R26 report. + */ +@Getter +public class ExecutionR26 extends AbstractExecutionReport { + + private static final long serialVersionUID = -8662335546561586221L; + + // Policies parameters + private static final PolicyLocation R26_POLICY_XML_LIGHT = PolicyLocation.make("R26_policy_light", "/xml/policies/r26report/R26_policy_light.xml"); + private static final PolicyLocation R26_POLICY_XML_FULL = PolicyLocation.make("R26_policy_full", "/xml/policies/r26report/R26_policy_full.xml"); + + // Priority parameter + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R26); + + // Revision rule parameter + private static final String REPORT_REVISION_RULE = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R26", DEFAULT_REVISION_RULE); + + // Launch type parameter + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R26"); + + // Configuration + private static final String SEPARATOR = "-"; + private static final String PATTERN_DATE = "yyyy-MM-dd"; + + // Raw input parameters + private final String component; + private final EffectivityDate effectivityDate; + + /** + * Constructor. + * + * @param component {@link String} - the component + * @param effectivityDate {@link EffectivityDate} - the effectivity + */ + public ExecutionR26(final String component, final EffectivityDate effectivityDate) { + super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE); + this.component = component; + this.effectivityDate = effectivityDate; + } + + @Override + public List getLaunchData() { + List theCriteria = new ArrayList<>(); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PART_ID, component)); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.EFFECTIVITY_DATE, effectivityDate.formatAsInputCriteria())); + theCriteria.add(new CriteriaValue(ReportCriteriaEnum.REVISION_RULE, this.revisionRule)); + return theCriteria; + } + + @Override + public List getQuickChecks() { + ArrayList quickChecks = new ArrayList<>(); + quickChecks.add(new ObjectTypeChecker(component, SnecmaObjectTypes.ALTERNATE, SnecmaObjectTypes.DET, + SnecmaObjectTypes.PART_AERO, SnecmaObjectTypes.PART_ASSEMB, SnecmaObjectTypes.PART_MAT, + SnecmaObjectTypes.PART_NO_AERO, SnecmaObjectTypes.STANDARD)); + return quickChecks; + } + + @Override + public String getTemplateLocation() { + return JasperTemplate.TEMPLATE_R26_MASTER.getFilepath(); + } + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R26_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R26_POLICY_XML_FULL; + } + + @Override + public List getLongChecks() { + return new ArrayList<>(); + } + + @Override + public ReportEnum getReportIdentifier() { + return ReportEnum.REPORT_R26; + } + + /** + * Format file expected : R26-"Composant"-"Date effectivté".XLSX + */ + @Override + public String getSpecifiedFileName() { + StringBuilder filename = new StringBuilder("R26-"); + filename.append(component).append(SEPARATOR); + filename.append(TeamcenterDateFormatter.formatCalendarToPattern(Calendar.getInstance(), PATTERN_DATE)); + return filename.toString(); + } + + @Override + public PrintFormat getPrintingFormat() { + return PrintFormat.XLSX; + } + + @Override + public IDataReportPreparator getDataPreparator() { + return new DataReportPreparatorR26(); + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return new ExecutionR26(component, effectivityDate); + } + + @Override + public Class getReportBuilderClass() { + return R26Builder.class; + } + + + /** + * POJO container of all data required for this report. + */ + public static class ReportDataR26 { + private final List r26BomLines; + + private boolean isStandard = false; + + public boolean isStandard() { + return isStandard; + } + + public void setStandard(boolean standard) { + isStandard = standard; + } + + protected ReportDataR26(final List r26BomLines) { + this.r26BomLines = r26BomLines; + } + + public List getR26BomLines() { + return r26BomLines; + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/LineManager.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/LineManager.java new file mode 100644 index 0000000..8eb6e0b --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/LineManager.java @@ -0,0 +1,272 @@ +package com.capgemini.reports.definition.r26report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.status.TcEffectivity; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObjectFactory; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRule; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRuleProperties; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindow; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindowConfiguration; +import com.capgemini.framework.teamcenter.object.runtime.TcRevisionRulesConfiguration; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderFactory; +import com.capgemini.reports.bomlineholder.processor.DefaultAltOrDetBehaviour; +import com.capgemini.reports.filter.AllIsGoodFilter; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.teamcenter.resolution.structureservice.SingleStructureServiceCaller; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.BOMLine; +import com.teamcenter.soa.client.model.strong.Form; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.RevisionRule; +import com.teamcenter.soa.client.model.strong.WorkspaceObject; +import lombok.Getter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Manager for making lines in report R26. + */ +@Getter +class LineManager { + + private static final AllIsGoodFilter ACCEPT_ALL = new AllIsGoodFilter(); + + private static final Logger LOGGER = LoggerFactory.getLogger(LineManager.class); + + private TcSession session; + private ExecutionR26 report; + private String componentId; + private RevisionRule revisionRuleR26; + private EffectivityDate effectivityDate; + private List r26BomLines; + private TcRevisionRulesConfiguration revRulesConfiguration; + private RevisionRuleManager revisionRuleManager; + + LineManager(TcSession session, ExecutionR26 report, RevisionRuleManager revisionRuleManager) throws KurtException { + this.session = session; + this.report = report; + this.componentId = report.getComponent(); + this.r26BomLines = new ArrayList<>(); + this.revisionRuleR26 = revisionRuleManager.getRevisionRule(); + this.effectivityDate = report.getEffectivityDate(); + this.revisionRuleManager = revisionRuleManager; + + TcRevisionRuleProperties revisionRuleProperties = new TcRevisionRuleProperties(effectivityDate.getDateTime()); + TcRevisionRule revisionRule = session.findRevRule(report.getRevisionRule()); + revRulesConfiguration = new TcRevisionRulesConfiguration(revisionRule, revisionRuleProperties); + } + + /** + * Ajoute les lignes de nomenclature au rapport R26. + */ + void addLines(ItemRevision receptor, ItemRevision rf, ProductRevision product, ItemRevision module, String effectivity, + Boolean consumedByProduct, Boolean effectivityUnit) throws KurtException { + BOMLineHolder unBuiltTopLine = getBomLineHolder(rf == null ? receptor : rf); + if (unBuiltTopLine != null) { + for (BOMLineHolder currentChild : unBuiltTopLine.getBomChilds()) { + ItemRevision itemRev = currentChild.getItemRevision(); + if (currentChild.getBomChilds().isEmpty() && componentId.equals(itemRev.get_item_id())) { + addLineToR26(currentChild.getBomLineObject(), receptor, rf, product, module, + effectivity, consumedByProduct, effectivityUnit); + } + } + } + } + + /** + * Retourne la bom line générée avec l'objet topWo ou null si elle n'existe pas. + */ + private BOMLineHolder getBomLineHolder(WorkspaceObject topWo) throws KurtException { + BOMLineHolder unBuiltTopLine; + TcBomObject topLineObject = new TcBomObjectFactory(session, topWo).create(); + + try (TcBomWindow bomWindow = session.createBomWindow(new TcBomWindowConfiguration(topLineObject, revRulesConfiguration))) { + // Perform the job + try { + unBuiltTopLine = new SingleStructureServiceCaller(session).resolve(bomWindow.topLine(), new R26BOMLineExplorer()); + + List itemRevMaster = unBuiltTopLine.getAllItemRevMasters(); + session.loadProperties(itemRevMaster.toArray(new ModelObject[0])); + + BOMLineHolderFactory.buildTopBom(session, unBuiltTopLine, ACCEPT_ALL); + DefaultAltOrDetBehaviour aBOMLineHolderProcessor = new DefaultAltOrDetBehaviour<>(session, + effectivityDate.isNow() ? null : effectivityDate.getDateTime()); + unBuiltTopLine.process(aBOMLineHolderProcessor); + unBuiltTopLine.freeze(); + } + catch (EmptyNomenclatureException e) { + unBuiltTopLine = null; + } + } + return unBuiltTopLine; + } + + /** + * Ajoute la ligne de nomenclature aux lignes du rapport R26 si elle n'existe pas déjà. + */ + private void addLineToR26(BOMLine line, ItemRevision receptor, ItemRevision rf, ProductRevision product, ItemRevision module, + String effectivity, Boolean consumedByProduct, Boolean effectivityUnit) { + if (line != null) { + R26BomLine r26BomLine = new R26BomLine(line.get_bl_quantity(), line.get_bl_item_uom_tag(), + receptor, rf, product, module, effectivity, consumedByProduct, effectivityUnit); + consolidateR26BomLines(r26BomLine); + if (!isLineAlreadyAdded(r26BomLine)) { + r26BomLines.add(r26BomLine); + } + } + } + + /** + * Retourne true si la ligne existe déjà dans le rapport (toutes les valeurs sont identiques). + * Sinon si seule l'effectivté est différente et en Produit/Unit alors la ligne existante sera supprimée + * et une nouvelle ligne avec les effectivités cumulées sera ajoutée. + */ + private boolean isLineAlreadyAdded(R26BomLine r26BomLine) { + for (R26BomLine currentLine : r26BomLines) { + if (r26BomLine.equals(currentLine)) { + return true; + } + } + return false; + } + + private void consolidateR26BomLines(R26BomLine r26BomLine) { + List r26BomLinesToDelete = new ArrayList<>(); + for (R26BomLine currentLine : r26BomLines) { + if (r26BomLine.equals(currentLine) && r26BomLine.getConsumedByProduct() && !currentLine.getConsumedByProduct()) { + r26BomLinesToDelete.add(currentLine); + } + if (r26BomLine.equals(currentLine) && r26BomLine.equalsExceptEffectivity(currentLine) && r26BomLine.isEffectivityUnit()) { + // cumulate effectivities + String eff1 = currentLine.getEffectivity(); + String eff2 = r26BomLine.getEffectivity(); + r26BomLine.setEffectivity(eff1 + ";" + eff2); + r26BomLinesToDelete.add(currentLine); + } + } + for (R26BomLine r26BomLineToDelete : r26BomLinesToDelete) { + r26BomLines.remove(r26BomLineToDelete); + } + } + + /** + * Traitement des Generic/Generic Assemb. + * Pour chacun: ajout de la ligne de nomenclatures trouvée au rapport R26. + * Si aucun Generic/Generic Assemb: la ligne est ajoutée sans Module et sera visible en rouge car non consommée par un produit. + */ + void manageGenerics(Map generics, ItemRevision firstLevelParentRev, ItemRevision secondLevelParentRev, + ProductRevision productRev, String effectivity, Boolean effectivityUnit) throws KurtException { + + for (Map.Entry currentGenerics : generics.entrySet()) { + LOGGER.info("=== Treating Generic: {} ===",currentGenerics.getKey().get_item_revision_id()); + if (SnecmaObjectTypes.isPartRevision(firstLevelParentRev.getTypeObject().getName())) { + addLines(firstLevelParentRev, null, productRev, currentGenerics.getKey(), "", currentGenerics.getValue(), effectivityUnit); + } + else { + addLines(secondLevelParentRev, firstLevelParentRev, productRev, currentGenerics.getKey(), effectivity, + currentGenerics.getValue(), effectivityUnit); + } + } + + // produit à noté en rouge, le composant de la ligne n'est pas consommé + if (generics.isEmpty() && !SnecmaObjectTypes.isPartRevision(firstLevelParentRev.getTypeObject().getName())) { + addLines(secondLevelParentRev, firstLevelParentRev, productRev, null, effectivity, false, effectivityUnit); + } + } + + /** + * Récupère tous les Generic/Generic Assemb lors de la remontée via where used + */ + void addGenerics(Map generics, ItemRevision itemRev, TcEffectivity tcEffectivity, String productItemId, Item item) { + List parents = session.whereUsed(itemRev, 1, revisionRuleR26); + for (ItemRevision currentParent : parents) { + if (SnecmaObjectTypes.isGenericRevision(currentParent.getTypeObject().getName())) { + if (EffectivityHelper.isEffectivityMatches(session, tcEffectivity, currentParent)) { + // tester si le composant est non standard + if (!item.get_object_type().equals(SnecmaObjectTypes.STANDARD)) { + boolean productFound = findProduct(revisionRuleR26, productItemId, currentParent); + generics.put(currentParent, productFound); + } else { + generics.put(currentParent, false); + } + } + } else { + addGenerics(generics, currentParent, tcEffectivity, productItemId, item); + } + } + } + + /** + * Manage le RF en Produit/Unit (currentRfPU): + * Pour chaque effectivité trouvée sur le statut Effectivity: + * La règle de révision du rapport est mise à jour avec le produit et les units du statut + * Tous les Generic/Generic Assemb trouvés sont ensuite gérés + */ + void manageRfPU(ItemRevision firstLevelParentRev, ItemRevision secondLevelParentRev, ItemRevision currentRfPU, Item item) throws KurtException { + Map tcEffectivities = EffectivityHelper.getEffectivitiesWithUnitRange(session, currentRfPU); + // récuperer les effectivitées + for (Map.Entry currentEff : tcEffectivities.entrySet()) { + int[] units = currentEff.getKey().unitNumbers(); + Item product = currentEff.getKey().endItem(); + + revisionRuleManager.setProductUnitRevisionRuleProperties(product.getUid(), units[0]); + + // récupérer tous les Generic/Generic Assemb trouvés via le where used. + Map generics = new HashMap<>(); + addGenerics(generics, currentRfPU, currentEff.getKey(), product.get_item_id(), item); + + session.loadProperties(product, "revision_list"); + ProductRevision productRev = new ProductRevision(session, (ItemRevision) (product.get_revision_list()[0])); + + manageGenerics(generics, firstLevelParentRev, secondLevelParentRev, productRev, + effectivityDate.formatAsInputCriteria(), false); + } + } + + /** + * Retourne true si la ligne de nomenclature entre parentRev et childRev existe, false sinon. + */ + boolean bomLineExists(ItemRevision parentRev, String childRevId) throws KurtException { + session.loadProperties(parentRev, "items_tag"); + BOMLineHolder unBuiltTopLine = getBomLineHolder(parentRev.get_items_tag()); + if (unBuiltTopLine != null && unBuiltTopLine.getItemRevision().get_item_revision_id().equals(parentRev.get_item_revision_id())) { + for (BOMLineHolder currentChild : unBuiltTopLine.getBomChilds()) { + ItemRevision itemRev = currentChild.getItemRevision(); + if (childRevId.equals(itemRev.get_item_id())) { + return true; + } + } + } + return false; + } + + /** + * Retourne true si l'itemRev est consommé par un produit, false sinon. + */ + boolean findProduct(RevisionRule revRule, String productItemId, ItemRevision itemRev) { + List parents = session.whereUsed(itemRev, 1, revRule); + boolean productFound = false; + // remonter au produit: si trouvé alors true, false sinon + for (ItemRevision currentParent : parents) { + if (SnecmaObjectTypes.isProductRevision(currentParent.getTypeObject().getName()) && productItemId.equals(currentParent.get_item_id())) { + return true; + } + else { + productFound = productFound || findProduct(revRule, productItemId, currentParent); + } + } + return productFound; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/R26BOMLineExplorer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/R26BOMLineExplorer.java new file mode 100644 index 0000000..c0d987e --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/R26BOMLineExplorer.java @@ -0,0 +1,29 @@ +package com.capgemini.reports.definition.r26report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.framework.teamcenter.resolution.filtering.ITcTypeFilter; +import com.capgemini.framework.teamcenter.resolution.filtering.TcTypeInclusionFilter; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.teamcenter.resolution.IBOMLineExplorer; +import com.capgemini.reports.teamcenter.resolution.structureservice.SingleStructureServiceCaller; + +/** + * Explorer of {@link BOMLineHolder}s used in {@link SingleStructureServiceCaller} for R26report.
+ * Thanks to this class, the SINGLE resolution structure could carry on and the Part Number could be taken.
+ * The Rf Generic is returned, and its children Part Aero / RF Admin and Descriptif are loaded + */ +public class R26BOMLineExplorer implements IBOMLineExplorer { + + private static final ITcTypeFilter FILTER_DESCRIPTION = new TcTypeInclusionFilter(SnecmaObjectTypes.PART_AERO_REVISION, + SnecmaObjectTypes.PART_NO_AERO_REVISION, SnecmaObjectTypes.PART_ASSEMB_REVISION, SnecmaObjectTypes.PART_MAT_REVISION, + SnecmaObjectTypes.DET_REVISION, SnecmaObjectTypes.STANDARD_REVISION, SnecmaObjectTypes.ALTERNATE_REVISION, + SnecmaObjectTypes.RF_GENERIC_REVISION, SnecmaObjectTypes.RF_PART_ASSEMB_REVISION, SnecmaObjectTypes.RF_ADMIN_REVISION, + SnecmaObjectTypes.RF_PART_REVISION, SnecmaObjectTypes.RF_ADMIN_AG_REVISION, SnecmaObjectTypes.RF_ADMIN_AP_REVISION); + + public BOMLineHolder explore(TcSession session, final SingleStructureServiceCaller.SingleLevelExpander expander, + final BOMLineHolder genericBom) throws EmptyNomenclatureException { + return expander.expand(genericBom, FILTER_DESCRIPTION); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/R26BomLine.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/R26BomLine.java new file mode 100644 index 0000000..968c2dd --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/R26BomLine.java @@ -0,0 +1,78 @@ +package com.capgemini.reports.definition.r26report; + +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.Getter; + +@Getter +public class R26BomLine { + private String quantity; + private String unitOfMeasure; + private ItemRevision receptor; + private ItemRevision rf; + private ProductRevision productRev; + private ItemRevision module; + private String effectivity; + private Boolean consumedByProduct; + private Boolean effectivityUnit; + + R26BomLine(final String quantity, final String unitOfMeasure, final ItemRevision receptor, final ItemRevision rf, + final ProductRevision productRev, final ItemRevision module, final String effectivity, + final Boolean consumedByProduct, Boolean effectivityUnit) { + this.quantity = quantity; + this.unitOfMeasure = unitOfMeasure; + this.receptor = receptor; + this.rf = rf; + this.productRev = productRev; + this.module = module; + this.effectivity = effectivity; + this.consumedByProduct = consumedByProduct; + this.effectivityUnit = effectivityUnit; + } + + public boolean equals(R26BomLine r26BomLine) { + return ( + this.quantity.equals(r26BomLine.getQuantity()) + && this.unitOfMeasure.equals(r26BomLine.getUnitOfMeasure()) + && this.receptor == r26BomLine.getReceptor() + && this.rf == r26BomLine.getRf() + && isProductEquals(r26BomLine.getProductRev()) + && (this.module == null && r26BomLine.getModule() == null + || (this.module != null && r26BomLine.getModule() != null + && this.module.get_item_id().equals(r26BomLine.getModule().get_item_id()))) + && this.effectivity.contentEquals(r26BomLine.getEffectivity())); + } + + private boolean isProductEquals(ProductRevision productRev) { + boolean productEquals = false; + if (this.productRev == null && productRev == null) { + productEquals = true; + } + else if (this.productRev == null || productRev == null) { + productEquals = false; + } + else if (this.productRev.getItemId().equals(productRev.getItemId())) { + productEquals = true; + } + return productEquals; + } + + boolean equalsExceptEffectivity(R26BomLine r26BomLine) { + return ( + this.quantity.equals(r26BomLine.getQuantity()) + && this.unitOfMeasure.equals(r26BomLine.getUnitOfMeasure()) + && this.receptor == r26BomLine.getReceptor() + && this.rf == r26BomLine.getRf() + && isProductEquals(r26BomLine.getProductRev()) + && this.module == r26BomLine.getModule() + && !this.effectivity.contentEquals(r26BomLine.getEffectivity())); + } + + public void setEffectivity(String effectivity) { + this.effectivity = effectivity; + } + + Boolean isEffectivityUnit() { + return effectivityUnit; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/R26Keys.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/R26Keys.java new file mode 100644 index 0000000..b90c81a --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/R26Keys.java @@ -0,0 +1,28 @@ +package com.capgemini.reports.definition.r26report; + +/** + * Key attributes to the Jasper report content. + */ +public enum R26Keys { + SUBREPORT_P1, + SUBREPORT_P2, + MESSAGE_1, + MESSAGE_2, + MESSAGE_3, + MESSAGE_4, + RECEPTOR_ID, + RECEPTOR_REVISION, + RECEPTOR_NAME, + REPERE_ID, + REPERE_REVISION, + REPERE_NAME, + QUANTITY, + UNIT_OF_MEASURE, + PRODUCT, + PRODUCT_LINE, + EFFECTIVITY_UNIT, + MODULE_ID, + MODULE_NAME, + CONSUMED_BY_PRODUCT, + TYPE_STANDARD +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/R26Printer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/R26Printer.java new file mode 100644 index 0000000..d3d9c1f --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/R26Printer.java @@ -0,0 +1,165 @@ +package com.capgemini.reports.definition.r26report; + +import com.capgemini.framework.common.ResourceHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.definition.r26report.ExecutionR26.ReportDataR26; +import com.capgemini.reports.execution.mapconstructor.AbstractStaticTemplateMapConstructor; +import com.capgemini.reports.execution.mapconstructor.IMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Extracts the relevant data obtained from TC into the expected List of Maps for Jasper. + */ +@Slf4j +public class R26Printer extends AbstractStaticTemplateMapConstructor implements IMapConstructor { + + private static final long serialVersionUID = 4281716591716247163L; + + private static final String SUBREPORT_P1 = "SUBREPORT_P1"; + private static final String SUBREPORT_P2 = "SUBREPORT_P2"; + private static final String MESSAGE_PRODUIT_NON_CONSOMME = "Les produits notés en rouge ne consomment pas le composant de la ligne de nomenclature"; + private static final String MESSAGE_PRODUIT_COMPOSANT_STANDARD = "Pour le composant de type standard, il n'est pas vérifié que les produits en violet consomment le composant."; + private static final String MESSAGE_AUCUNE_DONNEE = "Aucune donnée n’a pu être extraite, aucune ligne de nomenclature trouvée pour le composant"; + private static final String MESSAGE_AUCUNE_DONNEE_ETUDE = "Aucune donnée Etude n’a pu être extraite, aucune ligne de nomenclature trouvée pour le composant"; + private static final String MESSAGE_AUCUNE_DONNEE_MONTAGE = "Aucune donnée Montage n’a pu être extraite, aucune ligne de nomenclature trouvée pour le composant"; + + /** + * Puts the data gathered by an {@link ExecutionR26} into some {@link PrintParameters} for printing. + * + * @param reportData the data-bearing {@link ReportDataR26} + * @param mainReport the {@link PrintParameters} + */ + private void print(final ReportDataR26 reportData, final PrintParameters mainReport) throws KurtException { + + boolean vueEtudeEmpty = setupPage1(reportData, mainReport); + boolean vueMontageEmpty = setupPage2(reportData, mainReport); + + Map map = new EnumMap<>(R26Keys.class); + if (vueEtudeEmpty && vueMontageEmpty) { + map.put(R26Keys.MESSAGE_1, MESSAGE_AUCUNE_DONNEE); + } + else { + map.put(R26Keys.MESSAGE_1, vueEtudeEmpty ? MESSAGE_AUCUNE_DONNEE_ETUDE : MESSAGE_PRODUIT_NON_CONSOMME); + map.put(R26Keys.MESSAGE_2, vueMontageEmpty ? MESSAGE_AUCUNE_DONNEE_MONTAGE : MESSAGE_PRODUIT_NON_CONSOMME); + map.put(R26Keys.MESSAGE_3, vueEtudeEmpty ? "" : MESSAGE_PRODUIT_COMPOSANT_STANDARD); + map.put(R26Keys.MESSAGE_4, vueMontageEmpty ? "" : MESSAGE_PRODUIT_COMPOSANT_STANDARD); + } + List> test = new ArrayList<>(); + test.add(map); + mainReport.addReportDataFromEnum(test); + + // Setup main report + mainReport.addReportData(setupEmptyData()); + } + + private static List> setupEmptyData() { + List> list = new ArrayList<>(); + list.add(new HashMap()); + return list; + } + + private static boolean setupPage1(final ReportDataR26 reportData, final PrintParameters mainReport) + throws KurtException { + boolean emptySubReport = true; + try (InputStream page1Stream = ResourceHelper.getResourceAsStream(JasperTemplate.TEMPLATE_R26_SUBREPORT.getFilepath())) { + List> vueEtudeList = setupPage1Data(reportData); + + if (!vueEtudeList.isEmpty()) { + emptySubReport = false; + } + + mainReport.addSubReport(SUBREPORT_P1, page1Stream, vueEtudeList, new EnumMap<>(R26Keys.class)); + } + catch (IOException e) { + log.error("Unable to close template of the R26 report", e); + } + return emptySubReport; + } + + private static boolean setupPage2(final ReportDataR26 reportData, final PrintParameters mainReport) + throws KurtException { + boolean emptySubReport = true; + try (InputStream page2Stream = ResourceHelper.getResourceAsStream(JasperTemplate.TEMPLATE_R26_SUBREPORT.getFilepath())) { + List> vueMontageList = setupPage2Data(reportData); + + if (!vueMontageList.isEmpty()) { + emptySubReport = false; + } + + mainReport.addSubReport(SUBREPORT_P2, page2Stream, vueMontageList, new EnumMap<>(R26Keys.class)); + } + catch (IOException e) { + log.error("Unable to close template of the R26 report", e); + } + return emptySubReport; + } + + private static List> setupPage1Data(ReportDataR26 reportData) { + List> vueEtudeList = new ArrayList<>(); + for (R26BomLine currentLine : reportData.getR26BomLines()) { + if (currentLine.getModule() == null || currentLine.getModule().getTypeObject().getName().equals(SnecmaObjectTypes.GENERIC_REVISION)) { + Map map = getR26KeysStringMap(currentLine, reportData.isStandard()); + vueEtudeList.add(map); + } + } + return vueEtudeList; + } + + private static List> setupPage2Data(ReportDataR26 reportData) { + List> vueMontageList = new ArrayList<>(); + for (R26BomLine currentLine : reportData.getR26BomLines()) { + if (currentLine.getModule() != null && currentLine.getModule().getTypeObject().getName().equals(SnecmaObjectTypes.GENERIC_ASSEMB_REVISION)) { + Map map = getR26KeysStringMap(currentLine, reportData.isStandard()); + vueMontageList.add(map); + } + } + return vueMontageList; + } + + private static Map getR26KeysStringMap(R26BomLine currentLine, boolean isStandard) { + Map map = new EnumMap<>(R26Keys.class); + + map.put(R26Keys.RECEPTOR_ID, currentLine.getReceptor() == null ? "" : currentLine.getReceptor().get_item_id()); + map.put(R26Keys.RECEPTOR_REVISION, currentLine.getReceptor() == null ? "" : currentLine.getReceptor().get_item_revision_id()); + map.put(R26Keys.RECEPTOR_NAME, currentLine.getReceptor() == null ? "" : currentLine.getReceptor().get_object_name()); + + map.put(R26Keys.REPERE_ID, currentLine.getRf() == null ? "" : currentLine.getRf().get_item_id()); + map.put(R26Keys.REPERE_REVISION, currentLine.getRf() == null ? "" : currentLine.getRf().get_item_revision_id()); + map.put(R26Keys.REPERE_NAME, currentLine.getRf() == null ? "" : currentLine.getRf().get_object_name()); + + map.put(R26Keys.QUANTITY, currentLine.getQuantity()); + map.put(R26Keys.UNIT_OF_MEASURE, currentLine.getUnitOfMeasure()); + + map.put(R26Keys.PRODUCT, currentLine.getProductRev() == null ? "" : currentLine.getProductRev().getItemId()); + map.put(R26Keys.PRODUCT_LINE, currentLine.getProductRev() == null ? "" : currentLine.getProductRev().getProductLine()); + map.put(R26Keys.EFFECTIVITY_UNIT, currentLine.getEffectivity() == null ? "" : currentLine.getEffectivity()); + + map.put(R26Keys.MODULE_ID, currentLine.getModule() == null ? "" : currentLine.getModule().get_item_id()); + map.put(R26Keys.MODULE_NAME, currentLine.getModule() == null ? "" : currentLine.getModule().get_object_name()); + + map.put(R26Keys.CONSUMED_BY_PRODUCT, String.valueOf(currentLine.getConsumedByProduct())); + map.put(R26Keys.TYPE_STANDARD, String.valueOf(isStandard)); + return map; + } + + @Override + public void constructDataMaps(final TcSession session, final PrintParameters printParameters, final ReportDataR26 reportData) throws KurtException { + long start = System.currentTimeMillis(); + print(reportData, printParameters); + log.trace("Execution time : {} ms for {}", System.currentTimeMillis() - start, "data filtering"); + + log.info("Browsing the Snecma Objects"); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/Range.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/Range.java new file mode 100644 index 0000000..fb62ea0 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/Range.java @@ -0,0 +1,59 @@ +package com.capgemini.reports.definition.r26report; + +import com.google.common.base.Joiner; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +public class Range { + private int borneInf; + private int borneSup; + private ItemRevision itemRevion; + private String revision; + + Range(ItemRevision revision, int borneInf, int borneSup) { + this.itemRevion = revision; + this.revision = revision.get_item_revision_id(); + this.borneInf = borneInf; + this.borneSup = borneSup; + } + + Range(String revision, int borneInf, int borneSup) { + this.itemRevion = null; + this.revision = revision; + this.borneInf = borneInf; + this.borneSup = borneSup; + } + + @Override + public String toString() { + if (borneInf == borneSup) { + return Integer.toString(borneInf); + } + else { + return Joiner.on("-").join(Integer.toString(borneInf), Integer.toString(borneSup)); + } + } + + ItemRevision getItemRevion() { + return itemRevion; + } + + public String getRevision() { + return revision; + } + + public void setRevision(String revision) { + this.revision = revision; + } + + int borneSup() { + return borneSup; + } + + int borneInf() { + return borneInf; + } + + public boolean isUp() { + return borneSup == 2147483646; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/Ranges.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/Ranges.java new file mode 100644 index 0000000..cd5e163 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/Ranges.java @@ -0,0 +1,190 @@ +package com.capgemini.reports.definition.r26report; + +import com.google.common.base.Joiner; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +public class Ranges { + + private final List ranges; + + Ranges(List ranges) { + this.ranges = ranges; + } + + public String toString(final String revId) { + List newRanges = new LinkedList<>(); + for (int index = 0; index < ranges.size(); index++) { + Range currentRange = ranges.get(index); + if (index == 0) { + newRanges.add(currentRange); + } + else { + int borneInfIndex = indexForIncludedBorne(newRanges, currentRange.borneInf()); + int borneSupIndex = indexForIncludedBorne(newRanges, currentRange.borneSup()); + + if (borneInfIndex == -1 && borneSupIndex == -1) { + int excludedBorneInfIndex = indexForExcludedBorne(newRanges, currentRange.borneInf()); + int excludedBorneSupIndex = indexForExcludedBorne(newRanges, currentRange.borneSup()); + + if (excludedBorneInfIndex == excludedBorneSupIndex) { + newRanges.add(excludedBorneInfIndex, new Range(currentRange.getRevision(), currentRange.borneInf(), currentRange.borneSup())); + } + else { + newRanges.set(excludedBorneInfIndex, new Range(currentRange.getRevision(), currentRange.borneInf(), currentRange.borneSup())); + } + } + else if (borneInfIndex <= newRanges.size() && borneSupIndex == -1) { + Range previousRange = newRanges.get(borneInfIndex); + newRanges.set(borneInfIndex, new Range(previousRange.getRevision(), previousRange.borneInf(), currentRange.borneInf() - 1)); + newRanges.add(new Range(currentRange.getRevision(), currentRange.borneInf(), currentRange.borneSup())); + } + else if (borneInfIndex == borneSupIndex) { + Range previousRange = newRanges.get(borneInfIndex); + if (currentRange.borneInf() == previousRange.borneInf() && currentRange.borneSup() == previousRange.borneSup()) { + newRanges.set(borneInfIndex, new Range(currentRange.getRevision(), currentRange.borneInf(), currentRange.borneSup())); + } + else if (currentRange.borneInf() == previousRange.borneInf()) { + newRanges.set(borneInfIndex, new Range(previousRange.getRevision(), currentRange.borneInf(), currentRange.borneSup())); + newRanges.add(borneInfIndex + 1, new Range(previousRange.getRevision(), currentRange.borneSup() + 1, previousRange.borneSup())); + } + else if (currentRange.borneSup() == previousRange.borneSup()) { + newRanges.set(borneInfIndex, new Range(previousRange.getRevision(), previousRange.borneInf(), currentRange.borneInf() - 1)); + newRanges.add(borneInfIndex + 1, new Range(currentRange.getRevision(), currentRange.borneInf(), currentRange.borneSup())); + } + else { + newRanges.set(borneInfIndex, new Range(previousRange.getRevision(), previousRange.borneInf(), currentRange.borneInf() - 1)); + newRanges.add(borneInfIndex + 1, new Range(currentRange.getRevision(), currentRange.borneInf(), currentRange.borneSup())); + newRanges.add(borneInfIndex + 2, new Range(previousRange.getRevision(), currentRange.borneSup() + 1, previousRange.borneSup())); + } + } + else { + for (int i = borneInfIndex; i <= borneSupIndex; i = i + 2) { + Range nextRange = newRanges.get(i); + if (i == borneInfIndex) { + if (currentRange.borneInf() == nextRange.borneInf()) { + newRanges.set(i, new Range(nextRange.getRevision(), nextRange.borneInf(), currentRange.borneInf())); + newRanges.add(i + 1, new Range(currentRange.getRevision(), currentRange.borneInf() + 1, nextRange.borneSup())); + } + else { + newRanges.set(i, new Range(nextRange.getRevision(), nextRange.borneInf(), currentRange.borneInf() - 1)); + newRanges.add(i + 1, new Range(currentRange.getRevision(), currentRange.borneInf(), nextRange.borneSup())); + } + borneSupIndex = borneSupIndex + 1; + } + else { + if (!currentRange.isUp()) { + newRanges.set(i, new Range(nextRange.getRevision(), nextRange.borneInf(), currentRange.borneSup())); + newRanges.add(i + 1, new Range(currentRange.getRevision(), currentRange.borneSup() + 1, nextRange.borneSup())); + borneSupIndex = borneSupIndex + 1; + } + else { + newRanges.set(i, new Range(currentRange.getRevision(), nextRange.borneInf(), currentRange.borneSup())); + } + } + } + } + } + } + + List validRevs = filterValidRevs(revId, newRanges); + return Joiner.on(";").join(consolidateRevs(validRevs)).replace("2147483646", "UP"); + } + + private List filterValidRevs(String revId, List newRanges) { + List validRevs = new ArrayList<>(); + for (Range range : newRanges) { + if (revId.equals(range.getRevision())) { + validRevs.add(range); + } + } + return validRevs; + } + + private List consolidateRevs(List validRevs) { + List consolidatedRanges = new ArrayList<>(); + if (validRevs.size() == 1) { + consolidatedRanges.add(validRevs.get(0)); + } + else if (validRevs.size() == 2) { + Range previousRange = validRevs.get(0); + Range currentRange = validRevs.get(1); + if (previousRange.borneSup() + 1 == currentRange.borneInf()) { + Range consolidatedRange = new Range(currentRange.getRevision(), previousRange.borneInf(), currentRange.borneSup()); + consolidatedRanges.add(consolidatedRange); + } + else { + consolidatedRanges.addAll(validRevs); + } + } + else { + for (int i = 0; i < validRevs.size(); i++) { + int indexToConsolidate = indexToConsolidate(validRevs, i); + if (indexToConsolidate != -1) { + Range previousRange = validRevs.get(i); + Range nextRange = validRevs.get(indexToConsolidate); + Range consolidatedRange = new Range(nextRange.getRevision(), previousRange.borneInf(), nextRange.borneSup()); + consolidatedRanges.add(consolidatedRange); + i = indexToConsolidate; + } + else { + consolidatedRanges.add(validRevs.get(i)); + } + } + } + return consolidatedRanges; + } + + private int indexForExcludedBorne(List newRanges, int borne) { + if (borne < newRanges.get(0).borneInf()) { + return 0; + } + if (borne > newRanges.get(newRanges.size() - 1).borneSup()) { + return newRanges.size(); + } + + for (int i = 1; i < newRanges.size(); i++) { + Range previousRange = newRanges.get(i - 1); + Range range = newRanges.get(i); + if (borne >= previousRange.borneSup() && borne <= range.borneInf()) { + return i; + } + } + return -1; + } + + private int indexForIncludedBorne(List newRanges, int borne) { + for (int i = 0; i < newRanges.size(); i++) { + Range range = newRanges.get(i); + if (borne >= range.borneInf() && borne <= range.borneSup()) { + return i; + } + } + return -1; + } + + private int indexToConsolidate(List newRanges, int startIndex) { + for (int i = startIndex; i < newRanges.size(); i++) { + Range currentRange = newRanges.get(i); + if (i == 0 && i < newRanges.size() - 1) { + Range nextRange = newRanges.get(i + 1); + if (currentRange.borneSup() + 1 != nextRange.borneInf()) { + return -1; + } + } + else if (i > 0 && i < newRanges.size() - 1) { + Range previousRange = newRanges.get(i - 1); + Range nextRange = newRanges.get(i + 1); + if (previousRange.borneSup() + 1 == currentRange.borneInf() && currentRange.borneSup() + 1 != nextRange.borneInf()) { + return i; + } + else if (currentRange.borneSup() + 1 == nextRange.borneInf() && nextRange.isUp()) { + return i + 1; + } + } + } + return -1; // not found + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/RevisionRuleManager.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/RevisionRuleManager.java new file mode 100644 index 0000000..9d8c9c3 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/RevisionRuleManager.java @@ -0,0 +1,57 @@ +package com.capgemini.reports.definition.r26report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRule; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.teamcenter.queries.TypeQuery; +import com.teamcenter.soa.client.model.strong.RevisionRule; +import lombok.Getter; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Manager for Revision Rule for making report R26. + */ +@Getter +class RevisionRuleManager { + + private RevisionRule revisionRule; + private String revisionRuleName; + private TcRevisionRule tcRevisionRule; + + RevisionRuleManager(TcSession session, RevisionRule reportRevRule, String newRevRuleName) throws InvalidUserInputException { + try { + session.cloneRevisionRule(reportRevRule, newRevRuleName); + } + catch (Exception e) { + throw new InvalidUserInputException(UserInputErrorEnum.UNABLE_TO_USE_REVISION_RULE); + } + + List list = TypeQuery.getRevisionRule(session, newRevRuleName); + + if (list.isEmpty()) { + throw new InvalidUserInputException(UserInputErrorEnum.UNABLE_TO_USE_REVISION_RULE); + } + else { + revisionRule = list.get(0); + tcRevisionRule = new TcRevisionRule(session, revisionRule); + session.loadProperties(revisionRule, "object_name"); + revisionRuleName = revisionRule.get_object_name(); + } + } + + /** + * Mise à jour des valeurs Article et Produit de la règle de révision du rapport R26. + */ + void setProductUnitRevisionRuleProperties(String productUid, int unit) { + Map map = new HashMap<>(); + map.put("rule_unit", String.valueOf(unit)); + map.put("rule_end_item", productUid); + + tcRevisionRule.setProperties(map); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/RfPUManager.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/RfPUManager.java new file mode 100644 index 0000000..2be5d67 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r26report/RfPUManager.java @@ -0,0 +1,108 @@ +package com.capgemini.reports.definition.r26report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.*; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +/** + * Manager for RF PU for making report R26. + */ +public class RfPUManager { + + /** + * A partir de l'item revision passé en paramètre, retourne tous les RF en Produit/Unit trouvés via where used. + */ + static List getRfPUs(TcSession session, RevisionRule revRule, ItemRevision itemRev) { + List rfPUs = new ArrayList<>(); + List parents = session.whereUsed(itemRev, 1, revRule); + if (parents.isEmpty() && isRfPU(session, itemRev) && isLastReleasedRfPURev(session, itemRev)) { + rfPUs.add(itemRev); + } + for (ItemRevision parent : parents) { + addRfPUs(session, revRule, parent, rfPUs); + } + return rfPUs; + } + + /** + * Récupère tous les RF en PU trouvé récursivement. + */ + private static void addRfPUs(TcSession session, RevisionRule revRule, ItemRevision itemRev, List rfPUs) { + List parents = session.whereUsed(itemRev, 1, revRule); + + if (parents.isEmpty() && isRfPU(session, itemRev) && isLastReleasedRfPURev(session, itemRev)) { + rfPUs.add(itemRev); + return; + } + for (ItemRevision currentParent : parents) { + addRfPUs(session, revRule, currentParent, rfPUs); + } + } + + /** + * Récupère tous les RF en PU. + */ + static List getRfPURevisions(TcSession session, RevisionRule reportRevisionRule, ItemRevision secondLevelParentRev) { + List rfPUs = new ArrayList<>(); + if (isRfPU(session, secondLevelParentRev)) { + // si l'object courant est un RF et a une effectivité en PU + rfPUs.add(secondLevelParentRev); + } else { + rfPUs.addAll(getRfPUs(session, reportRevisionRule, secondLevelParentRev)); + } + return rfPUs; + } + + /** + * Retourne true si l'itemRev est un RF en PU. + */ + static boolean isRfPU(TcSession session, ItemRevision itemRev) { + return SnecmaObjectTypes.isRFRevision(itemRev.getTypeObject().getName()) + && EffectivityHelper.isEffectivityWithUnitRange(session, itemRev.get_release_status_list()); + } + + /** + * Si une autre révision de l'objet courant possède la même effectivité, seule la révision la plus récente (last released) sera traitée. + * Retourne true si c'est la révision la plus récente, false sinon. + */ + static boolean isLastReleasedRfPURev(TcSession session, ItemRevision rfRev) { + ReleaseStatus[] statuses = rfRev.get_release_status_list(); + + session.loadProperties(rfRev, "items_tag"); + Item item = rfRev.get_items_tag(); + session.loadProperties(item, "revision_list"); + ModelObject[] revisions = item.get_revision_list(); + + Calendar releaseDate1 = rfRev.get_date_released(); + + for (ModelObject currentEffectivity : EffectivityHelper.getEffectivities(statuses)) { + Effectivity effectivity = (Effectivity) currentEffectivity; + session.loadProperties(effectivity, "unit_range_text"); + String effText1 = effectivity.get_unit_range_text(); + + for (ModelObject currentRev: revisions) { + ItemRevision itemRev = (ItemRevision) currentRev; + if (!rfRev.equals(itemRev)) { + Calendar releaseDate2 = itemRev.get_date_released(); + ReleaseStatus[] statuses2 = itemRev.get_release_status_list(); + + for (ModelObject currentEffectivity2 : EffectivityHelper.getEffectivities(statuses2)) { + Effectivity effectivity2 = (Effectivity) currentEffectivity2; + session.loadProperties(effectivity2, "unit_range_text"); + String effText2 = effectivity2.get_unit_range_text(); + + if (effText1.equals(effText2) && releaseDate1.before(releaseDate2)) { + return false; + } + } + } + } + } + return true; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r27report/DataReportPreparatorR27.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r27report/DataReportPreparatorR27.java new file mode 100644 index 0000000..16d0642 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r27report/DataReportPreparatorR27.java @@ -0,0 +1,53 @@ +package com.capgemini.reports.definition.r27report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemQuery; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.printing.PrintParameters; +import com.teamcenter.soa.client.model.strong.Item; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * This class will allow to prepare data and findAll back data for making report R27. + */ +class DataReportPreparatorR27 implements IDataReportPreparator { + private static final long serialVersionUID = 1758410914529352674L; + private static final Logger LOGGER = LoggerFactory.getLogger(DataReportPreparatorR27.class); + + + @Override + public String print(final TcSession session, ExecutionR27 execution, IExecutionStrategy executionStrategy) throws KurtException { + PrintParameters printParameters = prepareData(session, execution); + executionStrategy.print(printParameters, execution); + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + } + + + private PrintParameters prepareData(final TcSession session, final ExecutionR27 report) throws KurtException { + LOGGER.debug("PrepareData started on: {}", report.getReportIdentifier().getReportTitle()); + + session.setObjectPropPolicy(report.getFullPolicy()); + ItemQuery query = new ItemQuery(session); + query.searchType("Alternate;DET;Part Aero;Part Mat;Part No Aero;Standard"); + List results = query.findAll(); + session.loadObjects(); + + ExecutionR27.ReportDataR27 reportDataR27 = new ExecutionR27.ReportDataR27(results); + R27Printer r27Printer = new R27Printer(); + PrintParameters printParameters = r27Printer.makeMasterTemplate(report, reportDataR27); + r27Printer.constructDataMaps(session, printParameters, reportDataR27); + LOGGER.debug("PrepareData ended on: {}", report.getReportIdentifier().getReportTitle()); + return printParameters; + } + +} + + + + + diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r27report/ExecutionR27.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r27report/ExecutionR27.java new file mode 100644 index 0000000..ae27b92 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r27report/ExecutionR27.java @@ -0,0 +1,151 @@ +package com.capgemini.reports.definition.r27report; + +import com.capgemini.framework.common.ReportFolderOutputHelper; +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.builder.R27Builder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.printing.Printer; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.reports.parameters.IChecker; +import com.teamcenter.soa.client.model.strong.Item; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +import java.util.Calendar; +import java.util.Collections; +import java.util.List; + +/** + * Obtain data for report R27.
+ * Contain {@link IChecker} for a report's construction + */ +@Getter +@EqualsAndHashCode(callSuper = true) +public class ExecutionR27 extends AbstractExecutionReport { + /** + * Policy for inspecting Alternates and DETs more closely (i.e. looking into their pseudo-folders for alternative parts). + */ + public static final PolicyLocation R27_POLICY_XML_ALT = PolicyLocation.make("R27_policy_alt", "/xml/policies/r27report/R27_policy_alt.xml"); + private static final long serialVersionUID = 2659767774930642547L; + private static final IDataReportPreparator DATA_REPORT_PREPARATOR_R27 = new DataReportPreparatorR27(); + // Policies parameters + private static final PolicyLocation R27_POLICY_XML_LIGHT = PolicyLocation.make("R27_policy_light", "/xml/policies/r27report/R27_policy_light.xml"); + private static final PolicyLocation R27_POLICY_XML_FULL = PolicyLocation.make("R27_policy_full", "/xml/policies/r27report/R27_policy_full.xml"); + // Launch type parameter + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R27"); + + // Priority parameter + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R27); + + private static final String FILE_SEPARATOR = "_"; + private static final String TITLE = "Export_Articles"; + private static final String PATTERN_DATE = "dd-MM-yyyy"; + + /** + * Constructor. + */ + public ExecutionR27(List queryObjects) { + super(REPORT_PRIORITY, REPORT_LAUNCH_TYPE); + } + + + /** + * Empty constructor. + */ + public ExecutionR27() { + super(REPORT_PRIORITY, REPORT_LAUNCH_TYPE); + } + + + @Override + public String getSpecifiedFileName() { + StringBuilder builder = new StringBuilder("R27").append(FILE_SEPARATOR).append(TITLE).append(FILE_SEPARATOR); + builder.append(TeamcenterDateFormatter.formatCalendarToPattern(Calendar.getInstance(), PATTERN_DATE)); + return builder.toString(); + } + + @Override + public PrintFormat getPrintingFormat() { + return PrintFormat.CSV; + } + + @Override + public List getLaunchData() { + return Collections.emptyList(); + } + + @Override + public ReportEnum getReportIdentifier() { + return ReportEnum.REPORT_R27; + } + + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R27_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R27_POLICY_XML_FULL; + } + + @Override + public List getLongChecks() { + return Collections.emptyList(); + } + + @Override + public String getTemplateLocation() { + return JasperTemplate.TEMPLATE_R27.getFilepath(); + } + + @Override + public IDataReportPreparator getDataPreparator() { + return DATA_REPORT_PREPARATOR_R27; + } + + @Override + public List getQuickChecks() { + return Collections.emptyList(); + } + + @Override + public Class getReportBuilderClass() { + return R27Builder.class; + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return null; + } + + public PrintParameters reportParameters() { + return new PrintParameters(PrintFormat.CSV, getFileNameOnDisc(), ReportFolderOutputHelper.getStorageFolderLocation(getLaunchType())); + } + + /** + * POJO container of all data required for this report. + */ + static class ReportDataR27 { + private final List parts; + + public ReportDataR27(List parts) { + this.parts = parts; + } + + public List getParts() { + return parts; + } + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r27report/R27Keys.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r27report/R27Keys.java new file mode 100644 index 0000000..7285e8e --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r27report/R27Keys.java @@ -0,0 +1,8 @@ +package com.capgemini.reports.definition.r27report; + +/** + * Enumeration of all the columns of the R27 report. + */ +public enum R27Keys { + ITEM_ID, +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r27report/R27Printer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r27report/R27Printer.java new file mode 100644 index 0000000..e07b7e4 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r27report/R27Printer.java @@ -0,0 +1,57 @@ +package com.capgemini.reports.definition.r27report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.definition.r27report.ExecutionR27.ReportDataR27; +import com.capgemini.reports.execution.mapconstructor.AbstractStaticTemplateMapConstructor; +import com.capgemini.reports.execution.mapconstructor.IMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import com.teamcenter.soa.client.model.strong.Item; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Extracts the relevant data obtained from TC into the expected List of Maps for Jasper. + */ +@Slf4j +public class R27Printer extends AbstractStaticTemplateMapConstructor implements IMapConstructor { + + private static final long serialVersionUID = 4281716591716247163L; + + /** + * Puts the data gathered by an {@link ExecutionR27} into some {@link PrintParameters} for printing. + * + * @param reportData the data-bearing {@link ReportDataR27} + * @param mainReport the {@link PrintParameters} + */ + private void print(final ReportDataR27 reportData, final PrintParameters mainReport) { + List parts = reportData.getParts(); + if (parts.isEmpty()) { + mainReport.addReportData(setupEmptyData()); + } + else { + List> reportDataMap = new ArrayList<>(); + for (Item part : parts) { + Map map = new EnumMap<>(R27Keys.class); + map.put(R27Keys.ITEM_ID, part.get_item_id()); + reportDataMap.add(map); + } + mainReport.addReportDataFromEnum(reportDataMap); + } + } + + private static List> setupEmptyData() { + List> list = new ArrayList<>(); + list.add(new HashMap()); + return list; + } + + @Override + public void constructDataMaps(TcSession session, PrintParameters printParameters, ReportDataR27 reportData) { + print(reportData, printParameters); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r28report/DataReportPreparatorR28.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r28report/DataReportPreparatorR28.java new file mode 100644 index 0000000..1985d5d --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r28report/DataReportPreparatorR28.java @@ -0,0 +1,53 @@ +package com.capgemini.reports.definition.r28report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemQuery; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.printing.PrintParameters; +import com.teamcenter.soa.client.model.strong.Item; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * This class will allow to prepare data and findAll back data for making report R28. + */ +class DataReportPreparatorR28 implements IDataReportPreparator { + private static final long serialVersionUID = 1758410914529352674L; + private static final Logger LOGGER = LoggerFactory.getLogger(DataReportPreparatorR28.class); + + + @Override + public String print(final TcSession session, ExecutionR28 execution, IExecutionStrategy executionStrategy) throws KurtException { + PrintParameters printParameters = prepareData(session, execution); + executionStrategy.print(printParameters, execution); + return executionStrategy.getReportFileName(execution) + printParameters.getOuputFileExtension(); + } + + + private PrintParameters prepareData(final TcSession session, final ExecutionR28 report) throws KurtException { + LOGGER.debug("PrepareData started on: {}", report.getReportIdentifier().getReportTitle()); + + session.setObjectPropPolicy(report.getFullPolicy()); + ItemQuery query = new ItemQuery(session); + query.searchType("RF Part"); + List results = query.findAll(); + session.loadObjects(); + + ExecutionR28.ReportDataR28 reportDataR28 = new ExecutionR28.ReportDataR28(results); + R28Printer r28Printer = new R28Printer(); + PrintParameters printParameters = r28Printer.makeMasterTemplate(report, reportDataR28); + r28Printer.constructDataMaps(session, printParameters, reportDataR28); + LOGGER.debug("PrepareData ended on: {}", report.getReportIdentifier().getReportTitle()); + return printParameters; + } + +} + + + + + diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r28report/ExecutionR28.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r28report/ExecutionR28.java new file mode 100644 index 0000000..de27fdc --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r28report/ExecutionR28.java @@ -0,0 +1,151 @@ +package com.capgemini.reports.definition.r28report; + +import com.capgemini.framework.common.ReportFolderOutputHelper; +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.JasperTemplate; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.builder.R28Builder; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.printing.Printer; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.reports.parameters.IChecker; +import com.teamcenter.soa.client.model.strong.Item; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +import java.util.Calendar; +import java.util.Collections; +import java.util.List; + +/** + * Obtain data for report R28.
+ * Contain {@link IChecker} for a report's construction + */ +@Getter +@EqualsAndHashCode(callSuper = true) +public class ExecutionR28 extends AbstractExecutionReport { + /** + * Policy for inspecting Alternates and DETs more closely (i.e. looking into their pseudo-folders for alternative parts). + */ + public static final PolicyLocation R28_POLICY_XML_ALT = PolicyLocation.make("R28_policy_alt", "/xml/policies/r28report/R28_policy_alt.xml"); + private static final long serialVersionUID = -5027358935089122516L; + private static final IDataReportPreparator DATA_REPORT_PREPARATOR_R28 = new DataReportPreparatorR28(); + // Policies parameters + private static final PolicyLocation R28_POLICY_XML_LIGHT = PolicyLocation.make("R28_policy_light", "/xml/policies/r28report/R28_policy_light.xml"); + private static final PolicyLocation R28_POLICY_XML_FULL = PolicyLocation.make("R28_policy_full", "/xml/policies/r28report/R28_policy_full.xml"); + // Launch type parameter + private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R28"); + + // Priority parameter + private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R28); + + private static final String FILE_SEPARATOR = "_"; + private static final String TITLE = "Export_Repere_fonctionnel"; + private static final String PATTERN_DATE = "dd-MM-yyyy"; + + /** + * Constructor. + */ + public ExecutionR28(List queryObjects) { + super(REPORT_PRIORITY, REPORT_LAUNCH_TYPE); + } + + + /** + * Empty constructor. + */ + public ExecutionR28() { + super(REPORT_PRIORITY, REPORT_LAUNCH_TYPE); + } + + + @Override + public String getSpecifiedFileName() { + StringBuilder builder = new StringBuilder("R28").append(FILE_SEPARATOR).append(TITLE).append(FILE_SEPARATOR); + builder.append(TeamcenterDateFormatter.formatCalendarToPattern(Calendar.getInstance(), PATTERN_DATE)); + return builder.toString(); + } + + @Override + public PrintFormat getPrintingFormat() { + return PrintFormat.CSV; + } + + @Override + public List getLaunchData() { + return Collections.emptyList(); + } + + @Override + public ReportEnum getReportIdentifier() { + return ReportEnum.REPORT_R28; + } + + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return R28_POLICY_XML_LIGHT; + } + + @Override + public PolicyLocation getFullPolicy() { + return R28_POLICY_XML_FULL; + } + + @Override + public List getLongChecks() { + return Collections.emptyList(); + } + + @Override + public String getTemplateLocation() { + return JasperTemplate.TEMPLATE_R28.getFilepath(); + } + + @Override + public IDataReportPreparator getDataPreparator() { + return DATA_REPORT_PREPARATOR_R28; + } + + @Override + public List getQuickChecks() { + return Collections.emptyList(); + } + + @Override + public Class getReportBuilderClass() { + return R28Builder.class; + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + return null; + } + + public PrintParameters reportParameters() { + return new PrintParameters(PrintFormat.CSV, getFileNameOnDisc(), ReportFolderOutputHelper.getStorageFolderLocation(getLaunchType())); + } + + /** + * POJO container of all data required for this report. + */ + static class ReportDataR28 { + private final List parts; + + public ReportDataR28(List parts) { + this.parts = parts; + } + + public List getParts() { + return parts; + } + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r28report/R28Keys.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r28report/R28Keys.java new file mode 100644 index 0000000..5e6918a --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r28report/R28Keys.java @@ -0,0 +1,10 @@ +package com.capgemini.reports.definition.r28report; + +/** + * Enumeration of all the columns of the R27 report. + */ +public enum R28Keys { + ITEM_ID, + ITEM_NAME, + ITEM_EFFECTIVITY, +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/definition/r28report/R28Printer.java b/kurt-utility/src/main/java/com/capgemini/reports/definition/r28report/R28Printer.java new file mode 100644 index 0000000..640355c --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/definition/r28report/R28Printer.java @@ -0,0 +1,79 @@ +package com.capgemini.reports.definition.r28report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.definition.r28report.ExecutionR28.ReportDataR28; +import com.capgemini.reports.execution.mapconstructor.AbstractStaticTemplateMapConstructor; +import com.capgemini.reports.execution.mapconstructor.IMapConstructor; +import com.capgemini.reports.printing.PrintParameters; +import com.teamcenter.soa.client.model.strong.Item; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV4_TYPE_EFFECTIVITY; +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV4_TYPE_MODIFICATION; + +/** + * Extracts the relevant data obtained from TC into the expected List of Maps for Jasper. + */ +@Slf4j +public class R28Printer extends AbstractStaticTemplateMapConstructor implements IMapConstructor { + + private static final long serialVersionUID = 4281716591716247163L; + private static final Logger LOGGER = LoggerFactory.getLogger(TcSession.class); + + /** + * Puts the data gathered by an {@link ExecutionR28} into some {@link PrintParameters} for printing. + * + * @param reportData the data-bearing {@link ReportDataR28} + * @param mainReport the {@link PrintParameters} + */ + private void print(final ReportDataR28 reportData, final PrintParameters mainReport, final TcSession session) { + List parts = reportData.getParts(); + if (parts.isEmpty()) { + mainReport.addReportData(setupEmptyData()); + } + else { + + List> reportDataMap = new ArrayList<>(); + for (Item part : parts) { + Map map = new EnumMap<>(R28Keys.class); + map.put(R28Keys.ITEM_ID, part.get_item_id()); + map.put(R28Keys.ITEM_NAME, part.get_object_name()); + // if (part.get_IMAN_master_form()[0].) + if (part.get_IMAN_master_form().length != 0){ + session.loadProperties(part.get_IMAN_master_form()[0], PV4_TYPE_EFFECTIVITY); + // LOGGER.trace("Property is ", part.get_IMAN_master_form()[0].getPropertyObject(PV4_TYPE_EFFECTIVITY).getDisplayableValue()); + if (part.get_IMAN_master_form()[0].getPropertyObject(PV4_TYPE_EFFECTIVITY).getDisplayableValue() == "") { + LOGGER.trace("Object ID " + part.get_item_id() + " does not have any effectivity type"); + map.put(R28Keys.ITEM_EFFECTIVITY, ""); + } else { + map.put(R28Keys.ITEM_EFFECTIVITY, part.get_IMAN_master_form()[0].getPropertyObject(PV4_TYPE_EFFECTIVITY).getDisplayableValue()); + } + } else { + LOGGER.trace("Object ID " + part.get_item_id() + " does not have any form"); + map.put(R28Keys.ITEM_EFFECTIVITY, ""); + } + reportDataMap.add(map); + } + mainReport.addReportDataFromEnum(reportDataMap); + } + } + + private static List> setupEmptyData() { + List> list = new ArrayList<>(); + list.add(new HashMap()); + return list; + } + + @Override + public void constructDataMaps(TcSession session, PrintParameters printParameters, ReportDataR28 reportData) { + print(reportData, printParameters, session); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/AbstractEmailTemplate.java b/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/AbstractEmailTemplate.java new file mode 100644 index 0000000..2b7ca9a --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/AbstractEmailTemplate.java @@ -0,0 +1,133 @@ +package com.capgemini.reports.emailing.templates; + +import com.capgemini.framework.common.FileTemplate; +import com.capgemini.framework.common.MailHelper; +import com.capgemini.framework.common.ResourceHelper; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.exceptions.FileLoadingException; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; + +/** + * Template class for generating email content when a report has been scheduled, posted in the queue, has failed or is completed.
+ * This class provides a way to replace tags (found in the email template) by some provided content. + */ +@Slf4j +public abstract class AbstractEmailTemplate extends FileTemplate { + + @Getter + private final String subject; + + /** + * Constructor. + * + * @param subject the email's Subject + */ + public AbstractEmailTemplate(final String subject) { + super(); + this.subject = subject; + try { + // Select the corresponding template content + String theTemplateContent = ResourceHelper.getResourceContent("/html/email/" + getEmailTemplate()); + // Assign the expected template + setTemplateContent(theTemplateContent); + } + catch (FileLoadingException e) { + log.warn("Could not load the email template file", e); + } + } + + protected abstract String getEmailTemplate(); + + /** + * Assign a tag value in the template. + * + * @param aTag Tag identifier + * @param aTagValue Tag value + */ + protected void setTagValue(final EmailTagEnum aTag, final String aTagValue) { + setTagValue(aTag.toString(), aTagValue); + } + + /** + * Sends this mail to the provided list of users. + * + * @param users a list of users, each of them having potentially several comma-separated email addresses + */ + public void send(final List users) { + List validEmails = new ArrayList<>(); + List invalidUsers = new ArrayList<>(); + for (DbUser user : users) { + String email = user.getEmail(); + if (email == null || email.isEmpty() || user.isGuest()) { + invalidUsers.add(user); + } + else { + validEmails.add(email); + } + } + + sendToAdresses(validEmails); + if (users.isEmpty() || !invalidUsers.isEmpty()) { // no users, or at least one invalid user --> send to admins + log.debug("Some User(s) do not have an email address in ActiveDirectory."); + } + } + + /** + * Sends this mail to this user. + * + * @param user the user + */ + public void send(final DbUser user) { + String email = user.getEmail(); + if (email == null || email.isEmpty() || user.isGuest()) { + log.debug("User {} does not have an email address in ActiveDirectory. Sending email to default address(es).", user.getLogin()); + } + else { + List asList = new ArrayList<>(); + asList.add(email); + sendToAdresses(asList); + } + } + + /** + * Sends this mail to the users that required the report. + * + * @param destinators the email addresses for all receivers + */ + public void sendToAdresses(final List destinators) { + // Generate content using parameters and template + String content = this.generateCode(); + + // Send the email + MailHelper.sendAll(destinators, subject, content); + } + + /** + * This Enum contains specific tags constants.
+ * These tags exist whithin the eMail template files, and can be replaced by any String thanks to the {@link AbstractEmailTemplate} class. + */ + protected enum EmailTagEnum { + // Common tag + REPORT_NAME, + + // Required when report state is: SCHEDULED + QUEUE_NAME, + ESTIMATED_COMPLETION_TIME, + + // Required when report state is: BAD PARAMETERS | FINISHED | FAILED + POSTING_TIME, + START_TIME, + END_TIME, + + // Required when report state is FINISHED + REPORT_LOCATION, + + // Required when report state is: BAD PARAMETERS | FAILED + ERROR_MESSAGE + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/BadParamEmailTemplate.java b/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/BadParamEmailTemplate.java new file mode 100644 index 0000000..44a7439 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/BadParamEmailTemplate.java @@ -0,0 +1,39 @@ +package com.capgemini.reports.emailing.templates; + +import com.capgemini.reports.exceptions.InvalidInputException; + +/** + * Represents a mail to warn the destinator that the report has some invalid parameters and will not be executed.
+ */ +public class BadParamEmailTemplate extends AbstractEmailTemplate { + + private static final String SUCCESSFUL_FR = " terminé avec succès"; + private static final String TEMPLATE_LOCATION = "template_email_bad_parameters.html"; + + /** + * Represents a mail to warn the destinator that the report has some invalid parameters and will not be executed.
+ * + * @param completeReportName the name of the report (e.g. R01 report "BOM Assemblage PU") + * @param postingTime a String describing he time at which this report was posted in the queues + * @param startTime a String describing he time at which this report's execution has started + * @param failureTime a String describing he time at which this report failed + * @param iie the specific Exception that contains the explanation + */ + public BadParamEmailTemplate(final String completeReportName, final String postingTime, final String startTime, final String failureTime, + final InvalidInputException iie) { + super(completeReportName + SUCCESSFUL_FR); + + // Assign parameters + this.setTagValue(EmailTagEnum.REPORT_NAME, completeReportName); + this.setTagValue(EmailTagEnum.POSTING_TIME, postingTime); + this.setTagValue(EmailTagEnum.START_TIME, startTime); + this.setTagValue(EmailTagEnum.END_TIME, failureTime); + this.setTagValue(EmailTagEnum.ERROR_MESSAGE, iie.getErrorMessageForUser()); + } + + @Override + protected String getEmailTemplate() { + return TEMPLATE_LOCATION; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/EmailReportHelper.java b/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/EmailReportHelper.java new file mode 100644 index 0000000..d5c57f7 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/EmailReportHelper.java @@ -0,0 +1,146 @@ +package com.capgemini.reports.emailing.templates; + +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.framework.common.activedirectory.ActiveDirectory; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.execution.AbstractExecutionReport; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +/** + * This class will allow to send different types of mail to the user. + */ +@Slf4j +public final class EmailReportHelper { + + private EmailReportHelper() { + // Cannot be called + } + + /** + * Sends a mail to warn the user that his report has successfully completed and may be retrieved. + * + * @param downloadLink the Location where the file has been stored + * @param aAbstractExecutionReport will provide the report concerned + * @param users the {@link List} of {@link DbUser} that have subscribed to this report + */ + public static void sendEndEmail(final String downloadLink, final AbstractExecutionReport aAbstractExecutionReport, + final List users) { + // Register current time as the posting time + aAbstractExecutionReport.setEndTime(TeamcenterDateFormatter.getCurrentTime()); + String completeReportName = aAbstractExecutionReport.getReportIdentifier().buildCompleteReportName().toString(); + new SuccessfulEmailTemplate(completeReportName, aAbstractExecutionReport.getPostingTime(), aAbstractExecutionReport.getStartTime(), + aAbstractExecutionReport.getEndTime(), downloadLink).send(users); + } + + /** + * Sends a mail to warn the user that his SCHEDULED report has successfully completed and may be retrieved. + * + * @param downloadLink the Location where the file has been stored + * @param aAbstractExecutionReport will provide the report concerned + * @param users the {@link List} of {@link DbUser} that have subscribed to this report + * @param schedulingName String - the scheduling name of the SCHEDULED report + */ + public static void sendScheduledEndEmail(final String downloadLink, final AbstractExecutionReport aAbstractExecutionReport, + final List users, final String schedulingName) { + // Register current time as the posting time + aAbstractExecutionReport.setEndTime(TeamcenterDateFormatter.getCurrentTime()); + String completeReportName = aAbstractExecutionReport.getReportIdentifier().buildCompleteReportName().toString(); + new SuccessfulEmailTemplate(completeReportName, aAbstractExecutionReport.getPostingTime(), aAbstractExecutionReport.getStartTime(), + aAbstractExecutionReport.getEndTime(), downloadLink, schedulingName).send(users); + } + + /** + * Sends a mail to warn the user that his report has failed to complete. + * + * @param errorMessage the error message to include for the user + * @param aAbstractExecutionReport will provide the report concerned + * @param users the {@link List} of {@link DbUser} that have subscribed to this report + */ + public static void sendErrorEmail(final String errorMessage, final AbstractExecutionReport aAbstractExecutionReport, + final List users) { + // Register current time as the error time + aAbstractExecutionReport.setFailureTime(TeamcenterDateFormatter.getCurrentTime()); + String completeReportName = aAbstractExecutionReport.getReportIdentifier().buildCompleteReportName().toString(); + new FailedEmailTemplate(completeReportName, aAbstractExecutionReport.getPostingTime(), aAbstractExecutionReport.getStartTime(), + aAbstractExecutionReport.getFailureTime(), errorMessage).send(users); + } + + /** + * Sends a mail to warn to the report admins that his report has failed to complete. + * + * @param errorMessage the error message to include for the admin report + * @param aAbstractExecutionReport will provide the report concerned + */ + public static void sendErrorEmailToAdminsReport(final String errorMessage, final AbstractExecutionReport aAbstractExecutionReport) { + // Register current time as the error time + aAbstractExecutionReport.setFailureTime(TeamcenterDateFormatter.getCurrentTime()); + String completeReportName = aAbstractExecutionReport.getReportIdentifier().buildCompleteReportName().toString(); + List adminsReport = ActiveDirectory.getAdminsReportUpdateDatabase(); + if (adminsReport.isEmpty()) { + log.error("The request for recovery of the admins report from active directory of SNECMA has returned nothing, on fail {} ", + aAbstractExecutionReport.getReportIdentifier()); + } else { + new FailedEmailTemplateAdmin(completeReportName, aAbstractExecutionReport.getPostingTime(), aAbstractExecutionReport.getStartTime(), + aAbstractExecutionReport.getFailureTime(), errorMessage).send(adminsReport); + } + } + + /** + * Sends a mail to warn the user that his report, launched by a workflow, has failed to complete. + * + * @param errorMessage the error message to include for the user + * @param aAbstractExecutionReport will provide the report concerned + * @param users the {@link List} of {@link DbUser} that have subscribed to this report + * @param relaunchURL the URL to launch this report again + */ + public static void sendWorkflowErrorEmail(final String errorMessage, final AbstractExecutionReport aAbstractExecutionReport, + final List users, final String relaunchURL) { + String reportName = aAbstractExecutionReport.getReportIdentifier().buildCompleteReportName().toString(); + String postingTime = aAbstractExecutionReport.getPostingTime(); + String startTime = aAbstractExecutionReport.getStartTime(); + String failureTime = aAbstractExecutionReport.getFailureTime(); + new FailedWorkflowEmailTemplate(reportName, postingTime, startTime, failureTime, errorMessage, relaunchURL).send(users); + } + + /** + * Sends a mail to warn to the report admin that his report (launched by workflow) has failed to complete. + * + * @param errorMessage the error message to include for the admin report + * @param aAbstractExecutionReport will provide the report concerned + * @param adminsReport the {@link List} of {@link DbUser} that have subscribed to this report + * @param relaunchURL the URL to use to re-launch the report + */ + public static void sendWorkflowErrorEmailToAdminsReport(final String errorMessage, final AbstractExecutionReport aAbstractExecutionReport, + final List adminsReport, final String relaunchURL) { + String reportName = aAbstractExecutionReport.getReportIdentifier().buildCompleteReportName().toString(); + String postingTime = aAbstractExecutionReport.getPostingTime(); + String startTime = aAbstractExecutionReport.getStartTime(); + String failureTime = aAbstractExecutionReport.getFailureTime(); + FailedWorkflowEmailTemplateAdmin emailTemplate = new FailedWorkflowEmailTemplateAdmin(reportName, postingTime, startTime, failureTime, errorMessage, relaunchURL); + emailTemplate.send(adminsReport); + } + + public static void sendScheduledErrorEmailToAdminsReport(String errorMessage, AbstractExecutionReport aAbstractExecutionReport) { + // Register current time as the error time + aAbstractExecutionReport.setFailureTime(TeamcenterDateFormatter.getCurrentTime()); + String completeReportName = aAbstractExecutionReport.getReportIdentifier().buildCompleteReportName().toString(); + List adminsReport = ActiveDirectory.getAdminsReportUpdateDatabase(); + if (adminsReport.isEmpty()) { + log.error("The request for recovery of the admins report from active directory of SNECMA has returned nothing, on fail {} ", + aAbstractExecutionReport.getReportIdentifier()); + } else { + new FailedEmailTemplateAdmin(completeReportName, aAbstractExecutionReport.getPostingTime(), aAbstractExecutionReport.getStartTime(), + aAbstractExecutionReport.getFailureTime(), errorMessage, aAbstractExecutionReport.getSchedulingName()).send(adminsReport); + } + } + + public static void sendScheduledErrorEmail(String errorMessage, AbstractExecutionReport aAbstractExecutionReport, List users) { + // Register current time as the error time + aAbstractExecutionReport.setFailureTime(TeamcenterDateFormatter.getCurrentTime()); + String completeReportName = aAbstractExecutionReport.getReportIdentifier().buildCompleteReportName().toString(); + new FailedEmailTemplate(completeReportName, aAbstractExecutionReport.getPostingTime(), aAbstractExecutionReport.getStartTime(), + aAbstractExecutionReport.getFailureTime(), errorMessage, aAbstractExecutionReport.getSchedulingName()).send(users); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/FailedEmailTemplate.java b/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/FailedEmailTemplate.java new file mode 100644 index 0000000..7144bfd --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/FailedEmailTemplate.java @@ -0,0 +1,54 @@ +package com.capgemini.reports.emailing.templates; + +import lombok.extern.slf4j.Slf4j; + +/** Represents a mail to warn the user that his report has failed. */ +@Slf4j +public class FailedEmailTemplate extends AbstractEmailTemplate { + + private static final String FAILED_FR = " terminé en erreur"; + private static final String TEMPLATE_LOCATION = "template_email_failed.html"; + + /** + * Represents a mail to warn the user that his report has failed. + * @param completeReportName the name of the report (e.g. R01 report "BOM Assemblage PU") + * @param postingTime a String describing he time at which this report was posted in the queues + * @param startTime a String describing he time at which this report's execution has started + * @param failureTime a String describing he time at which this report caused an error + * @param errorMessage the error message to include for the user + * @param schedulingName + */ + public FailedEmailTemplate(final String completeReportName, final String postingTime, final String startTime, final String failureTime, + final String errorMessage, final String schedulingName) { + super(completeReportName + " - planification " + schedulingName + FAILED_FR); + this.setTagValue(EmailTagEnum.POSTING_TIME, postingTime); + this.setTagValue(EmailTagEnum.REPORT_NAME, completeReportName); + this.setTagValue(EmailTagEnum.START_TIME, startTime); + this.setTagValue(EmailTagEnum.END_TIME, failureTime); + this.setTagValue(EmailTagEnum.ERROR_MESSAGE, errorMessage); + } + + /** + * Represents a mail to warn the user that his report has failed. + * @param completeReportName the name of the report (e.g. R01 report "BOM Assemblage PU") + * @param postingTime a String describing he time at which this report was posted in the queues + * @param startTime a String describing he time at which this report's execution has started + * @param failureTime a String describing he time at which this report caused an error + * @param errorMessage the error message to include for the user + */ + public FailedEmailTemplate(final String completeReportName, final String postingTime, final String startTime, final String failureTime, + final String errorMessage) { + super(completeReportName + FAILED_FR); + this.setTagValue(EmailTagEnum.POSTING_TIME, postingTime); + this.setTagValue(EmailTagEnum.REPORT_NAME, completeReportName); + this.setTagValue(EmailTagEnum.START_TIME, startTime); + this.setTagValue(EmailTagEnum.END_TIME, failureTime); + this.setTagValue(EmailTagEnum.ERROR_MESSAGE, errorMessage); + } + + @Override + protected String getEmailTemplate() { + return TEMPLATE_LOCATION; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/FailedEmailTemplateAdmin.java b/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/FailedEmailTemplateAdmin.java new file mode 100644 index 0000000..94fcd1d --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/FailedEmailTemplateAdmin.java @@ -0,0 +1,35 @@ +package com.capgemini.reports.emailing.templates; + +/** + * Email template when a report execution has failed (with a TECHNICAL ERROR) and an email must be sent to the admin. + */ +public class FailedEmailTemplateAdmin extends FailedEmailTemplate { + + private static final String TEMPLATE_LOCATION = "template_email_failed_admin.html"; + + /** + * Prepares an email to be sent to the admins, if a report failed (with a TECHNICAL ERROR). + * + * @param completeReportName the full report's name + * @param postingTime the time at which the report has been posted + * @param startTime the time at which the report qstarted to execute + * @param failureTime the time at which the report execution failed + * @param errorMessage the error message for the user + * @param schedulingName + */ + public FailedEmailTemplateAdmin(final String completeReportName, final String postingTime, final String startTime, final String failureTime, + final String errorMessage, final String schedulingName) { + super(completeReportName, postingTime, startTime, failureTime, errorMessage, schedulingName); + } + + public FailedEmailTemplateAdmin(final String completeReportName, final String postingTime, final String startTime, final String failureTime, + final String errorMessage) { + super(completeReportName, postingTime, startTime, failureTime, errorMessage); + } + + @Override + protected String getEmailTemplate() { + return TEMPLATE_LOCATION; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/FailedWorkflowEmailTemplate.java b/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/FailedWorkflowEmailTemplate.java new file mode 100644 index 0000000..ef8d1d0 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/FailedWorkflowEmailTemplate.java @@ -0,0 +1,27 @@ +package com.capgemini.reports.emailing.templates; + +/** + * Represents a mail to warn the user that this report, launched by a Workflow, has failed. + */ +public class FailedWorkflowEmailTemplate extends FailedEmailTemplate { + + /** + * Represents a mail to warn the user that this report, launched by a Workflow, has failed. + * + * @param completeReportName the name of the report (e.g. R01 report "BOM Assemblage PU") + * @param postingTime a String describing he time at which this report was posted in the queues + * @param startTime a String describing he time at which this report's execution has started + * @param failureTime a String describing he time at which this report caused an error + * @param errorMessage the error message to include for the user + * @param relaunchURL an URL that can be used to re-launch this report + */ + public FailedWorkflowEmailTemplate(final String completeReportName, final String postingTime, final String startTime, final String failureTime, + final String errorMessage, final String relaunchURL) { + super(completeReportName, postingTime, startTime, failureTime, makeErrorMessageFromFailure(errorMessage, relaunchURL)); + } + + private static String makeErrorMessageFromFailure(final String errorMessage, final String relaunchURL) { + return "Description de l'erreur : " + errorMessage + "

" + "Lien de relance : " + relaunchURL + ""; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/FailedWorkflowEmailTemplateAdmin.java b/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/FailedWorkflowEmailTemplateAdmin.java new file mode 100644 index 0000000..2684f27 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/FailedWorkflowEmailTemplateAdmin.java @@ -0,0 +1,26 @@ +package com.capgemini.reports.emailing.templates; + +/** + * In case report triggered by a workflow fails, this email is sent to the administrators. + */ +public class FailedWorkflowEmailTemplateAdmin extends FailedEmailTemplateAdmin { + + /** + * Constructor. + * + * @param completeReportName the complete report name (like 'R22 - BOM Par Date') + * @param postingTime the time at which the report has been posted + * @param startTime the time at which the report has started to execute + * @param failureTime the he time at which the report has failed + * @param errorMessage the error message + * @param relaunchURL a URL that the admins may use to re-launch this report with the same parameters + */ + public FailedWorkflowEmailTemplateAdmin(final String completeReportName, final String postingTime, final String startTime, + final String failureTime, final String errorMessage, final String relaunchURL) { + super(completeReportName, postingTime, startTime, failureTime, makeErrorMessageFromFailure(errorMessage, relaunchURL)); + } + + private static String makeErrorMessageFromFailure(final String errorMessage, final String relaunchURL) { + return "Description de l'erreur : " + errorMessage + "

" + "Lien de relance : " + relaunchURL + ""; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/SuccessfulEmailTemplate.java b/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/SuccessfulEmailTemplate.java new file mode 100644 index 0000000..56f86a6 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/emailing/templates/SuccessfulEmailTemplate.java @@ -0,0 +1,59 @@ +package com.capgemini.reports.emailing.templates; + + +/** + * Represents a mail to warn the user that his report has successfully completed and may be retrieved. + */ +public class SuccessfulEmailTemplate extends AbstractEmailTemplate { + + private static final String SUCCESSFUL_FR = " terminé avec succès"; + private static final String TEMPLATE_LOCATION = "template_email_finished.html"; + + /** + * Represents a mail to warn the user that his report has successfully completed and may be retrieved. + * + * @param completeReportName String - the name of the report (e.g. R01 report "BOM Assemblage PU") + * @param postingTime String - the time at which this report was posted in the queues + * @param startTime String - the time at which this report's execution has started + * @param endTime String - the time at which this report was completed + * @param reportLocation String - the location at which the user may retrieve this report + */ + public SuccessfulEmailTemplate(final String completeReportName, final String postingTime, final String startTime, final String endTime, + final String reportLocation) { + super(completeReportName + SUCCESSFUL_FR); + assignParameters(completeReportName, postingTime, startTime, endTime, reportLocation); + } + + /** + * Represents a mail to warn the user that his SCHEDULED report has successfully completed and may be retrieved. + * + * @param completeReportName String - the name of the report (e.g. R01 report "BOM Assemblage PU") + * @param postingTime String - the time at which this report was posted in the queues + * @param startTime String - the time at which this report's execution has started + * @param endTime String - the time at which this report was completed + * @param reportLocation String - the location at which the user may retrieve this report + * @param schedulingName String - the scheduling mane of the SCHEDULED report + */ + public SuccessfulEmailTemplate(final String completeReportName, final String postingTime, final String startTime, final String endTime, + final String reportLocation, final String schedulingName) { + super(completeReportName + " - planification " + schedulingName + SUCCESSFUL_FR); + assignParameters(completeReportName, postingTime, startTime, endTime, reportLocation); + } + + private void assignParameters(final String completeReportName, final String postingTime, final String startTime, final String endTime, + final String reportLocation) { + String hyperLink = "" + reportLocation + ""; + + this.setTagValue(EmailTagEnum.POSTING_TIME, postingTime); + this.setTagValue(EmailTagEnum.REPORT_NAME, completeReportName); + this.setTagValue(EmailTagEnum.START_TIME, startTime); + this.setTagValue(EmailTagEnum.END_TIME, endTime); + this.setTagValue(EmailTagEnum.REPORT_LOCATION, hyperLink); + } + + @Override + protected String getEmailTemplate() { + return TEMPLATE_LOCATION; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/exceptions/DuplicateReportEntryFound.java b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/DuplicateReportEntryFound.java new file mode 100644 index 0000000..6ed193a --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/DuplicateReportEntryFound.java @@ -0,0 +1,28 @@ +package com.capgemini.reports.exceptions; + +/** + * Exception used in the event of a report request received, that matches an already-waiting report.
+ * The former report is in this case not executed, and the user is directed to the latter report execution. + */ +public class DuplicateReportEntryFound extends InvalidUserInputException { + + private static final long serialVersionUID = -7724360531026615817L; + + /** + * Exception used in the event of a report request received, that matches an already-waiting report.
+ * Throw this exception if the user himself owns an identical execution request that predates this request. + */ + public DuplicateReportEntryFound() { + super(UserInputErrorEnum.DUPLICATE_REPORT_LAUNCHED_RECENTLY_BY_SELF); + } + + /** + * Exception used in the event of a report request received, that matches an already-waiting report.
+ * Throw this exception if an other user owns an identical execution request that predates this request. + * + * @param userName the user name of the person who requested the report again. + */ + public DuplicateReportEntryFound(final String userName) { + super(UserInputErrorEnum.DUPLICATE_REPORT_LAUNCHED_RECENTLY, userName); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/exceptions/DuplicateSchedulingEntryFound.java b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/DuplicateSchedulingEntryFound.java new file mode 100644 index 0000000..efb2248 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/DuplicateSchedulingEntryFound.java @@ -0,0 +1,33 @@ +package com.capgemini.reports.exceptions; + +/** + * Exception Thrown if two schedulings with the same name exist. + */ +public class DuplicateSchedulingEntryFound extends InvalidInputException { + + private static final long serialVersionUID = -7724360531026615817L; + + private final String messageToUser; + + /** + * Simple constructor. + * + * @param messageToUser a message for the user + */ + public DuplicateSchedulingEntryFound(final String messageToUser) { + super(UserInputErrorEnum.DUPLICATE_REPORT_LAUNCHED_RECENTLY_BY_SELF); + this.messageToUser = messageToUser; + } + + /** + * Returns the message to be sent to the user. + * + * @return the message + */ + @Override + public String getErrorMessageForUser() { + return messageToUser; + } + + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/exceptions/FileLoadingException.java b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/FileLoadingException.java new file mode 100644 index 0000000..eefdc32 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/FileLoadingException.java @@ -0,0 +1,32 @@ +package com.capgemini.reports.exceptions; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; + +/** + * Exception générée lors d'une erreur d'ouverture / lecture de fichier. + * + */ +public class FileLoadingException extends KurtException { + + private static final long serialVersionUID = 5516185489090268051L; + + /** + * Constructor. + * + * @param aMessage Error message + */ + public FileLoadingException(String aMessage) { + super(aMessage); + } + + /** + * Constructor. + * + * @param aMessage Error message + * @param anException Original exception + */ + public FileLoadingException(String aMessage, Throwable anException) { + super(aMessage, anException); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/exceptions/InsufficientParametersException.java b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/InsufficientParametersException.java new file mode 100644 index 0000000..6370490 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/InsufficientParametersException.java @@ -0,0 +1,32 @@ +package com.capgemini.reports.exceptions; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; + +/** + * Exception générée lorsqu'il manque des paramètres à une requète. + * + */ +public class InsufficientParametersException extends KurtException { + + private static final long serialVersionUID = 148136358620949560L; + + /** + * Constructor. + * + * @param aMessage Error message + */ + public InsufficientParametersException(String aMessage) { + super(aMessage); + } + + /** + * Constructor. + * + * @param aMessage Error message + * @param anException Original exception + */ + public InsufficientParametersException(String aMessage, Throwable anException) { + super(aMessage, anException); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/exceptions/InvalidActiveDirectoryInputException.java b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/InvalidActiveDirectoryInputException.java new file mode 100644 index 0000000..850b08c --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/InvalidActiveDirectoryInputException.java @@ -0,0 +1,19 @@ +package com.capgemini.reports.exceptions; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; + +/** Custom error occurring when the search is rejected by the ActiveDirectory (search might be ill-formed). */ +public class InvalidActiveDirectoryInputException extends KurtException { + + private static final long serialVersionUID = -1697080676771636361L; + + /** + * Creates a custom {@link InvalidActiveDirectoryInputException} wrapper around an exception thrown by the ActiveDirectory. + * + * @param aMessage custom error message + * @param anException original exception + */ + public InvalidActiveDirectoryInputException(final String aMessage, final Throwable anException) { + super(aMessage, anException); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/exceptions/InvalidActiveDirectorySearchException.java b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/InvalidActiveDirectorySearchException.java new file mode 100644 index 0000000..4dc2f94 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/InvalidActiveDirectorySearchException.java @@ -0,0 +1,19 @@ +package com.capgemini.reports.exceptions; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; + +/** Custom error occurring when the search is rejected by the ActiveDirectory (search might be ill-formed). */ +public class InvalidActiveDirectorySearchException extends KurtException { + + private static final long serialVersionUID = -1697080676771636361L; + + /** + * Creates a custom {@link InvalidActiveDirectorySearchException} wrapper around an exception thrown by the ActiveDirectory. + * + * @param aMessage custom error message + * @param anException original exception + */ + public InvalidActiveDirectorySearchException(final String aMessage, final Throwable anException) { + super(aMessage, anException); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/exceptions/InvalidCredentialsException.java b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/InvalidCredentialsException.java new file mode 100644 index 0000000..e35d66b --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/InvalidCredentialsException.java @@ -0,0 +1,32 @@ +package com.capgemini.reports.exceptions; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; + +/** + * Représente les erreurs de login (username / mot de passe). + * + */ +public class InvalidCredentialsException extends KurtException { + + private static final long serialVersionUID = 1364013468727766676L; + + /** + * Constructor. + * + * @param aMessage Error message + */ + public InvalidCredentialsException(String aMessage) { + super(aMessage); + } + + /** + * Constructor. + * + * @param aMessage Error message + * @param anException Original exception + */ + public InvalidCredentialsException(String aMessage, Throwable anException) { + super(aMessage, anException); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/exceptions/InvalidDatasetException.java b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/InvalidDatasetException.java new file mode 100644 index 0000000..8c4e7db --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/InvalidDatasetException.java @@ -0,0 +1,30 @@ +package com.capgemini.reports.exceptions; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; + +/** Exception obtained when a Dataset could not be created because of invalid parameters. */ +public class InvalidDatasetException extends KurtException { + + private static final long serialVersionUID = 6936261014709390652L; + + /** + * Constructor. + * + * @param aMessage Error message + */ + public InvalidDatasetException(String aMessage) { + super(aMessage); + } + + /** + * Constructor. + * + * @param aMessage Error message + * @param anException Original exception + */ + public InvalidDatasetException(String aMessage, Throwable anException) { + super(aMessage, anException); + } + + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/exceptions/NoConnectionToActiveDirectoryException.java b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/NoConnectionToActiveDirectoryException.java new file mode 100644 index 0000000..c451b82 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/NoConnectionToActiveDirectoryException.java @@ -0,0 +1,29 @@ +package com.capgemini.reports.exceptions; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; + +/** Custom error occurring when no connection could be set up to the ActiveDirectory (appli might not be in the same domain as AD?). */ +public class NoConnectionToActiveDirectoryException extends KurtException { + + private static final long serialVersionUID = 8900355250902392135L; + + /** + * Creates a custom {@link NoConnectionToActiveDirectoryException} wrapper around an exception thrown by the ActiveDirectory. + * + * @param aMessage custom error message + * @param anException original exception + */ + public NoConnectionToActiveDirectoryException(final String aMessage, final Throwable anException) { + super(aMessage, anException); + } + + + /** + * Creates a custom {@link NoConnectionToActiveDirectoryException} exception when Active Directory connection could not be made. + * + * @param aMessage custom error message + */ + public NoConnectionToActiveDirectoryException(final String aMessage) { + super(aMessage); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/exceptions/NothingToBeShownException.java b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/NothingToBeShownException.java new file mode 100644 index 0000000..0202f88 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/NothingToBeShownException.java @@ -0,0 +1,24 @@ +package com.capgemini.reports.exceptions; + +/** Exception thrown in HMI when there is no data to be shown. */ +public class NothingToBeShownException extends InvalidInputException { + + private static final long serialVersionUID = 6401523061302777316L; + + final String niceMessageForUser; + + /** + * Creates an instance. + * @param aTechnicalErrorMessage a technical error message for debugging + * @param userMessage a friendly user message for displaying + */ + public NothingToBeShownException(String aTechnicalErrorMessage, String userMessage) { + super(aTechnicalErrorMessage, UserInputErrorEnum.NOTHING_TO_BE_SHOWN); + this.niceMessageForUser = userMessage; + } + + public String getErrorMessageForUser() { + return niceMessageForUser; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/exceptions/ReportPrintException.java b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/ReportPrintException.java new file mode 100644 index 0000000..a94c8b6 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/exceptions/ReportPrintException.java @@ -0,0 +1,32 @@ +package com.capgemini.reports.exceptions; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; + +/** + * Générée lorsqu'une impression ne s'est pas deroulee correctement. + * + */ +public class ReportPrintException extends KurtException { + + private static final long serialVersionUID = 1499768115472984402L; + + /** + * Constructor. + * + * @param aMessage Error message + */ + public ReportPrintException(String aMessage) { + super(aMessage); + } + + /** + * Constructor. + * + * @param aMessage Error message + * @param anException Original exception + */ + public ReportPrintException(String aMessage, Throwable anException) { + super(aMessage, anException); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/AbstractExecutionReport.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/AbstractExecutionReport.java new file mode 100644 index 0000000..8a2b86f --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/AbstractExecutionReport.java @@ -0,0 +1,348 @@ +package com.capgemini.reports.execution; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.execution.mapconstructor.IMapConstructor; +import com.capgemini.reports.execution.strategies.DelayedExecutionStrategy; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import com.capgemini.reports.execution.strategies.ScheduledExecutionStrategy; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.printing.Printer; +import com.capgemini.reports.printing.Printer.AvailablePrinter; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.queuing.ReportPriority; +import com.capgemini.reports.reports.parameters.IChecker; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import net.lingala.zip4j.exception.ZipException; + +import java.io.Serializable; +import java.util.List; +import java.util.UUID; + +/** + * Abstract class for the execution of each report.
+ * The main method, {@link #doStart(TcSession)}, is called by the queuing system and executes (and prints) a report.
+ * It uses in that order the following objects for processing: + *

    + *
  1. Obtain the data from the Tc servers
  2. + *
  3. Create the template
  4. + *
  5. Printing
  6. + *
+ *

+ * If any of these steps fail, then a mail is Sent. + * + * @param Generic object about type of report + * @param A custom (POJO) object to carry data from the data preparator to the printer + */ +@Slf4j +@Getter +@Setter +@EqualsAndHashCode +public abstract class AbstractExecutionReport, U> implements Serializable { + // Configuration + protected static final String DEFAULT_REVISION_RULE = SettingsHelper.getDefaultRevisionRule(); + private static final long serialVersionUID = 5813503218626640137L; + private static final String LINE_BREAKER = "==========================================="; + protected final int priorityCode; + protected final String revisionRule; + protected String reportTechnicalUid = UUID.randomUUID().toString(); + // Scheduling parameters (default null if it is not a scheduling and it shoudn't be called). Setter is specifically added for both values + @Setter(value = AccessLevel.NONE) + protected String schedulingName; + @Setter(value = AccessLevel.NONE) + protected Long schedulingId; + @Getter(value = AccessLevel.NONE) + protected Boolean wkf = Boolean.FALSE; // By default, not launched by a WKF + // Times parameters + private String postingTime; + private String startTime; + @Setter(value = AccessLevel.NONE) + private String endTime; + @Setter(value = AccessLevel.NONE) + private String failureTime; + /** + * The strategy which defines immediate, delayed or scheduled behaviors during the execution of a report. Set up during constructor, but can be overwritten by scheduling servlet to force scheduling behaviour. + */ + private IExecutionStrategy executionStrategy; + + /** + * Constructor for DELAYEd / IMMEDIATE / SCHEDULED launches. + * + * @param priorityCode int - the priority code found in the reporting.properties file associated to a report. + * @param reportLaunchType the type of launch required.ccan be {@link ReportLaunchTypeEnum#IMMEDIATE} or {@link ReportLaunchTypeEnum#DELAYED} + */ + protected AbstractExecutionReport(final int priorityCode, final String revisionRule, final ReportLaunchTypeEnum reportLaunchType) { + this.priorityCode = priorityCode; + this.revisionRule = revisionRule; + switch (reportLaunchType) { + case DELAYED: + this.executionStrategy = new DelayedExecutionStrategy(); + break; + case IMMEDIATE: + this.executionStrategy = new ImmediateExecutionStrategy(); + break; + case SCHEDULED: + this.executionStrategy = new ScheduledExecutionStrategy(); + break; + default: + break; + } + } + + + /** + * Constructor for DELAYEd / IMMEDIATE / SCHEDULED launches. + * + * @param priorityCode int - the priority code found in the reporting.properties file associated to a report. + * @param reportLaunchType the type of launch required.ccan be {@link ReportLaunchTypeEnum#IMMEDIATE} or {@link ReportLaunchTypeEnum#DELAYED} + */ + + public AbstractExecutionReport (final int priorityCode, ReportLaunchTypeEnum reportLaunchType) { + this.priorityCode = priorityCode; + this.revisionRule = null; + switch (reportLaunchType) { + case DELAYED: + this.executionStrategy = new DelayedExecutionStrategy(); + break; + case IMMEDIATE: + this.executionStrategy = new ImmediateExecutionStrategy(); + break; + case SCHEDULED: + this.executionStrategy = new ScheduledExecutionStrategy(); + break; + default: + break; + } + } + + /* ******************************************/ + /* *************** EXECUTION ****************/ + /* ******************************************/ + + /** + * Defines the backbone of report creation.
+ *

    + * In order of execution: + *
  1. : Extracts all the raw data from Teamcenter
  2. + *
  3. {@link IMapConstructor#makeMasterTemplate(AbstractExecutionReport, Object) constructDataMaps}: Creates a {@link PrintParameters} objec
  4. + *
  5. {@link IMapConstructor#constructDataMaps(TcSession, PrintParameters, Object) constructDataMaps}: Filters and maps the data to some tokens from the report template
  6. + *
  7. Gives {@link PrintParameters} to that {@link Printer}
  8. + *
  9. {@link Printer#print(PrintParameters) Print}s the report
  10. + *
+ * Also, whenever any {@link KurtException} generated is caught here and will send an error email to the user. + *

+ * + * @param session the Teamcenter {@link com.capgemini.framework.teamcenter.authent.TcSession} used to perform the work. + * @throws KurtException something goes wrong internally (database not in line, problems in TC communication, problems in repor generation, etc.) + */ + public void doStart(final TcSession session) throws KurtException, ZipException { + @SuppressWarnings("unchecked") + T thisReport = (T) this; + + // Register the start of the report + log.info("Job started on: " + getReportIdentifier().buildCompleteReportName()); + + // Perform pre-execution steps + executionStrategy.preExecutionStep(thisReport, session); + + String fileNameWithExtension = getDataPreparator().print(session, thisReport, executionStrategy); + + // All the users who requested this report, at this time of the execution: END + executionStrategy.postExecutionStep(thisReport, fileNameWithExtension, session); + + log.info("Execution complete on: {}", this.getReportIdentifier().getReportTitle()); + } + + /** + * Fills the scheduling data in case this report was created from a scheduling template. + * + * @param schedulingId the Identifier of the scheduling + * @param schedulingName the name of the scheduling + */ + public void setScheduling(final Long schedulingId, final String schedulingName) { + this.schedulingId = schedulingId; + this.schedulingName = schedulingName; + } + + /** + * Get the data preparator.
+ * This object is responsible for recovering TC data and trnsforming it into report data. + * + * @return the {@link IDataReportPreparator} corresponding to the report + */ + public abstract IDataReportPreparator getDataPreparator(); + + /** + * Returns a list containing every {@link IChecker} used to verify report parameters BEFORE posting it to the queues. + * + * @return a {@link List}<{@link IChecker}> + */ + public abstract List getQuickChecks(); + + /** + * This method provides the {@link PolicyLocation} of the property policy to be used during the long checks. + * + * @return the location of the file as a String + */ + public abstract PolicyLocation getPropertyPolicyForLongChecks(); + + /** + * The identifier of the {@link PolicyLocation} for the resolution of nomenclature. + * + * @return identifier of the xml file + */ + public abstract PolicyLocation getFullPolicy(); + + /** + * Returns a list containing every {@link IChecker} used for to verify report parameters AFTER posting it to the queues, but BEFORE the full execution begins. + * + * @return a {@link List}<{@link IChecker}> + */ + public abstract List getLongChecks(); + + /* ******************************************/ + /* **************** PRINTING ****************/ + /* ******************************************/ + + /** + * Returns some Printer. + * + * @return the available printer + */ + public Printer getPrinter() { + return new Printer(AvailablePrinter.JASPER); + } + + /** + * Returns the report priority (to know which queue to join). + * + * @return a {@link ReportPriority} + */ + public ReportPriority getReportPriority() { + return ReportPriority.getReportPriority(priorityCode); + } + + /** + * Returns the location to the JASPER template file to be used. + * + * @return the path (within src/main/resources) + */ + public abstract String getTemplateLocation(); + + /* ======================================== */ + /* = REPORT IDENTIFIERS, NAMES AND TITLES = */ + /* ======================================== */ + + /** + * Returns the report identifier.
+ * Exemple with Report R01: "REPORT_R01". + * + * @return the report code + */ + public abstract ReportEnum getReportIdentifier(); + + /** + * Set true if this report has been launched by a workflow. + */ + public void isWkf() { + this.wkf = Boolean.TRUE; + } + + /* ================ */ + /* = PRINT PARAMS = */ + /* ================ */ + + /** + * Returns the file name required to save this report, as per the specifications. + * + * @return the file name + */ + public abstract String getSpecifiedFileName(); + + /** + * Returns the file name as it will be saved to disc locally. + * + * @return the file name + */ + public String getFileNameOnDisc() { + return getSpecifiedFileName() + "_" + reportTechnicalUid; + } + + /** + * Returns a structure of print parameters, initialised with the required output format for the report (xlsx, .pdf etc). + * + * @return some {@link PrintParameters} + */ + public abstract PrintFormat getPrintingFormat(); + + /** + * Prepare criteria values list of report. + * + * @return a {@link List} of every {@link CriteriaValue}. + */ + public abstract List getLaunchData(); + + /** + * Returns the name of a {@link ReportBuilder} implementation that is able to instantiate a report of the right type. + * + * @return the full class name + */ + public final String getReportBuilderClassName() { + Class builderClass = getReportBuilderClass(); + return builderClass.getName(); + } + + /** + * Returns the {@link Class} of a {@link ReportBuilder} implementation that is able to instantiate a report of the right type. + * + * @return the Class object. Must have a no-args constructor + */ + public abstract Class getReportBuilderClass(); + + /** + * Sets the time at which this report execution failed. + * + * @param aFailure the Time at which it failed as a String + */ + public void setFailureTime(final String aFailure) { + this.failureTime = aFailure; + } + + /** + * Sets the time at which this report execution completed. + * + * @param aEndtime the Time at which it failed as a String + */ + public void setEndTime(final String aEndtime) { + this.endTime = aEndtime; + } + + /** + * Clone a report execution from a scheduling template.
+ * Give him all the same criteria but a different uid. Also, reset the default launch type. + * + * @return the cloned report + */ + public abstract AbstractExecutionReport cloneTemplateToExecution(); + + /** + * Returns the {@link ReportLaunchTypeEnum} planned for this report. + * + * @return the {@link ReportLaunchTypeEnum} + */ + public final ReportLaunchTypeEnum getLaunchType() { + return getExecutionStrategy().getLaunchType(); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/IDataReportPreparator.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/IDataReportPreparator.java new file mode 100644 index 0000000..9b1ed01 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/IDataReportPreparator.java @@ -0,0 +1,31 @@ +package com.capgemini.reports.execution; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import net.lingala.zip4j.exception.ZipException; + +import java.io.Serializable; + +/** + * This interface will allow to prepare data for the reports. + * + * @param The type of the report this is preparing data for + */ +public interface IDataReportPreparator extends Serializable { + + /** + * Message to display execution time. + */ + String EXECUTION_TIME_XXX_MS_FOR_YYY = "Execution time : {} ms for {}"; + + /** + * Print the data by extracting it from Teamcenter. + * + * @param session + * @param execution will provide the report which is executing + * @param executionStrategy + * @throws KurtException when an internal error occurred + */ + String print(TcSession session, T execution, IExecutionStrategy executionStrategy) throws KurtException, ZipException; +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/AbstractPostExecutionStep.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/AbstractPostExecutionStep.java new file mode 100644 index 0000000..d6e9f69 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/AbstractPostExecutionStep.java @@ -0,0 +1,57 @@ +package com.capgemini.reports.execution.actions; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +/** + * This abstract class makes it easy do define a report-specific action, with strong typing.
+ * Intercepts the default (weakly-typed)
+ * {@link IPostExecutionStep#performPostAction(TcSession, AbstractExecutionReport, DbReport, String) performPostAction}
+ * And forwards it to this class's (strongly-typed)
+ * {@link AbstractPostExecutionStep#performPostActionOnReport(TcSession, AbstractExecutionReport, DbReport, String)} + * + * @param the exact report type + * @param Return type. Use {@link Void} for nothing. + */ +@AllArgsConstructor +@EqualsAndHashCode +public abstract class AbstractPostExecutionStep, R> implements IPostExecutionStep { + private static final long serialVersionUID = -1817048657143927445L; + + @Getter(value = AccessLevel.PROTECTED) + private final Class reportClass; + + @Override + public > void performPostAction(TcSession session, K reportRaw, DbReport theExecutingReport, + String fileNameWithExtension) throws KurtException { + try { + T report = reportClass.cast(reportRaw); + performPostActionOnReport(session, report, theExecutingReport, fileNameWithExtension); + } catch (ClassCastException e) { + throw new KurtException( + "Unable to perform Specialized action because input report is not of the right type, UID=" + reportRaw.getReportTechnicalUid(), + e); + } + } + + /** + * Performs a specific action on a particular report type to perform after the report execution. + * + * @param session a Teamcenter session (active) + * @param reportRaw the report which has just finished printing + * @param dbReport the Db object + * @param fileNameWithExtension the filename of the report (includes extension) + * @throws KurtException anything that happens must be a {@link KurtException} so it can be caught and dealt with appropriately.
+ * Particularly, if the error is a functional error, do throw an {@link InvalidUserInputException} + */ + protected abstract R performPostActionOnReport(TcSession session, T reportRaw, DbReport dbReport, + String fileNameWithExtension) throws KurtException; + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/AbstractPreExecutionStep.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/AbstractPreExecutionStep.java new file mode 100644 index 0000000..de56da3 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/AbstractPreExecutionStep.java @@ -0,0 +1,53 @@ +package com.capgemini.reports.execution.actions; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; + +/** + * This abstract class makes it easy do define a report-specific action, with strong typing.
+ * Intercepts the default (weakly-typed)
+ * {@link IPreExecutionStep#performPreAction(AbstractExecutionReport, DbReport, TcSession) performPreAction}
+ * And forwards it to this class's (strongly-typed)
+ * {@link AbstractPreExecutionStep#performPreActionOnReport(AbstractExecutionReport, DbReport, TcSession) performPreActionOnReport} + * @param the exact report type + */ +@AllArgsConstructor +@EqualsAndHashCode +public abstract class AbstractPreExecutionStep> implements IPreExecutionStep { + + private static final long serialVersionUID = -1516821856454786852L; + + private final Class reportClass; + + @Override + public > void performPreAction(K reportRaw, DbReport dbReport, TcSession session) + throws KurtException { + try { + T report = reportClass.cast(reportRaw); + performPreActionOnReport(report, dbReport, session); + } catch (ClassCastException e) { + throw new KurtException( + "Unable to perform Specialized action because input report is not of the right type, UID=" + reportRaw.getReportTechnicalUid(), + e); + } + } + + /** + * Performs a specific action on a particular report type before the report execution. + * + * @param reportRaw + * @param dbReport the report which has just finished printing + * @param session + * + * @throws KurtException anything that happens must be a {@link KurtException} so it can be caught and dealt with appropriately.
+ * Particularly, if the error is a functional error, do throw an {@link InvalidUserInputException} + */ + protected abstract void performPreActionOnReport(T reportRaw, DbReport dbReport, TcSession session) throws KurtException; + +} + diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/CompositeErrorAction.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/CompositeErrorAction.java new file mode 100644 index 0000000..88be028 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/CompositeErrorAction.java @@ -0,0 +1,53 @@ +package com.capgemini.reports.execution.actions; + +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.NoConfChangesException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import lombok.EqualsAndHashCode; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * If you need to perform several {@link IErrorExecutionStep}s, use this class to execute them orderly. + */ +@EqualsAndHashCode +public class CompositeErrorAction implements IErrorExecutionStep { + + private static final long serialVersionUID = -7228217924123134048L; + + private final List actions = new ArrayList<>(); + + /** + * Creates a composite error handler, capable of executing several actions in series. + * + * @param inputActions the actions to be carried out sequentially. + */ + public CompositeErrorAction(IErrorExecutionStep... inputActions) { + Collections.addAll(this.actions, inputActions); + } + + @Override + public void performFunctionalErrorAction(AbstractExecutionReport report, List owners, NoConfChangesException theOrginalException) { + for (IErrorExecutionStep action : actions) { + action.performFunctionalErrorAction(report, owners, theOrginalException); + } + } + + @Override + public void performFunctionalErrorAction(AbstractExecutionReport report, List owners, InvalidInputException theOrginalException) { + for (IErrorExecutionStep action : actions) { + action.performFunctionalErrorAction(report, owners, theOrginalException); + } + } + + @Override + public void performTechnicalErrorAction(AbstractExecutionReport report, List owners, Throwable theOrginalException) { + for (IErrorExecutionStep action : actions) { + action.performTechnicalErrorAction(report, owners, theOrginalException); + } + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/CompositePostAction.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/CompositePostAction.java new file mode 100644 index 0000000..f23ecbb --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/CompositePostAction.java @@ -0,0 +1,40 @@ +package com.capgemini.reports.execution.actions; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.execution.AbstractExecutionReport; +import lombok.EqualsAndHashCode; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * If you need to perform several {@link IPostExecutionStep}s, use this class to execute them orderly. + */ +@EqualsAndHashCode +public class CompositePostAction implements IPostExecutionStep { + + private static final long serialVersionUID = -7228217924123134048L; + + private final List actions; + + /** + * Creates a composite post execution action, capable of executing several actions in series. + * + * @param inputActions the actions to be carried out sequentially. + */ + public CompositePostAction(IPostExecutionStep... inputActions) { + this.actions = new ArrayList<>(); + Collections.addAll(this.actions, inputActions); + } + + @Override + public > void performPostAction(TcSession session, T report, DbReport theExecutingReport, + String fileNameWithExtension) throws KurtException { + for (IPostExecutionStep iPostExecutionStep : actions) { + iPostExecutionStep.performPostAction(session, report, theExecutingReport, fileNameWithExtension); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/CompositePreAction.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/CompositePreAction.java new file mode 100644 index 0000000..7669937 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/CompositePreAction.java @@ -0,0 +1,38 @@ +package com.capgemini.reports.execution.actions; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.execution.AbstractExecutionReport; +import lombok.EqualsAndHashCode; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** If you need to perform several {@link IPreExecutionStep}s, use this class to execute them orderly. */ +@EqualsAndHashCode +public class CompositePreAction implements IPreExecutionStep { + + private static final long serialVersionUID = -7228217924123134048L; + + private final List actions; + + /** + * Creates a composite pre execution action, capable of executing several actions in series. + * + * @param inputActions the actions to be carried out sequentially. + */ + public CompositePreAction(IPreExecutionStep... inputActions) { + this.actions = new ArrayList<>(); + Collections.addAll(this.actions, inputActions); + } + + @Override + public > void performPreAction(T abstractExecutionReport, DbReport dbReport, TcSession session) + throws KurtException { + for (IPreExecutionStep iPostExecutionStep : actions) { + iPostExecutionStep.performPreAction(abstractExecutionReport, dbReport, session); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/DoNothingAction.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/DoNothingAction.java new file mode 100644 index 0000000..15d6fd8 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/DoNothingAction.java @@ -0,0 +1,48 @@ +package com.capgemini.reports.execution.actions; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.exceptions.InvalidDatasetException; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.NoConfChangesException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import lombok.EqualsAndHashCode; + +import java.util.List; + +/** + * This action does nothing. Useful if an action Object is required by an API, but nothing needs to be done.
+ * Can be used as a {@link IPreExecutionStep}, a {@link IPostExecutionStep}, and/or a {@link IErrorExecutionStep}. + */ +@EqualsAndHashCode +public class DoNothingAction implements IPreExecutionStep, IPostExecutionStep, IErrorExecutionStep { + private static final long serialVersionUID = 8222229264738863306L; + + @Override + public > void performPreAction(T abstractExecutionReport, DbReport dbReport, TcSession session) { + // Let's happily do nothing at all, here. Yay! + } + + @Override + public > void performPostAction(TcSession session, T report, DbReport theExecutingReport, + String fileNameWithExtension) throws NotFoundException, InvalidDatasetException { + // Let's happily do nothing at all, here. Yay! + } + + @Override + public void performTechnicalErrorAction(AbstractExecutionReport report, List owners, Throwable theOrginalException) { + // Let's happily do nothing at all, here. Yay! + } + + @Override + public void performFunctionalErrorAction(AbstractExecutionReport report, List owners, NoConfChangesException theOriginalException) { + // Let's happily do nothing at all, here. Yay! + } + + @Override + public void performFunctionalErrorAction(AbstractExecutionReport report, List owners, InvalidInputException theOriginalException) { + // Let's happily do nothing at all, here. Yay! + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/IErrorExecutionStep.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/IErrorExecutionStep.java new file mode 100644 index 0000000..5a7e5d8 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/IErrorExecutionStep.java @@ -0,0 +1,41 @@ +package com.capgemini.reports.execution.actions; + +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.NoConfChangesException; +import com.capgemini.reports.execution.AbstractExecutionReport; + +import java.io.Serializable; +import java.util.List; + +/** Interface for ations to be taken in case of functional/technical error encountered during a report execution. */ +public interface IErrorExecutionStep extends Serializable { + + /** + * Action to be performed in case of Technical error.
+ * Note these actions may never fail, please do catch and handle any exception. + * + * @param report the report whose execution failed + * @param owners the owners of the failed report + */ + void performTechnicalErrorAction(AbstractExecutionReport report, List owners, Throwable theOriginalException); + + /** + * Action to be performed in case of Functional error.
+ * Note these actions may never fail, please do catch and handle any exception. + * + * @param report the report whose execution failed + * @param owners the owners of the failed report + * @param theOriginalException the exception that cause mayhem + */ + void performFunctionalErrorAction(AbstractExecutionReport report, List owners, NoConfChangesException theOriginalException); + + /** + * Action to be performed in case of Functional error.
+ * Note these actions may never fail, please do catch and handle any exception. + * @param report the report whose execution failed + * @param owners the owners of the failed report + * @param theOriginalException the exception that cause mayhem + */ + void performFunctionalErrorAction(AbstractExecutionReport report, List owners, InvalidInputException theOriginalException); +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/IPostExecutionStep.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/IPostExecutionStep.java new file mode 100644 index 0000000..c558442 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/IPostExecutionStep.java @@ -0,0 +1,30 @@ +package com.capgemini.reports.execution.actions; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.execution.AbstractExecutionReport; + +import java.io.Serializable; + +/** + * Interface for an action to be taken after a report has been printed. + */ +public interface IPostExecutionStep extends Serializable { + + /** + * The action to perform after the report execution. + * + * @param the type of report which failed + * @param session a Teamcenter session (active) + * @param report the report which has just finished printing + * @param dbReport the Db object + * @param fileNameWithExtension the filename of the report (includes extension) + * @throws KurtException anything that happens must be a {@link KurtException} so it can be caught and dealt with appropriately.
+ * Particularly, if the error is a functional error, do throw an {@link InvalidUserInputException} + */ + > void performPostAction(TcSession session, T report, DbReport dbReport, + String fileNameWithExtension) throws KurtException; + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/IPreExecutionStep.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/IPreExecutionStep.java new file mode 100644 index 0000000..3b899b2 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/IPreExecutionStep.java @@ -0,0 +1,26 @@ +package com.capgemini.reports.execution.actions; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.execution.AbstractExecutionReport; + +import java.io.Serializable; + +/** Interface for an action to be taken right before a report begins its execution. */ +public interface IPreExecutionStep extends Serializable { + + /** + * The action to perform before the report execution. + * + * @param session a Teamcenter session (active) + * @param report the report which has just finished printing + * @param dbReport the Db object + * @param the type of report which failed + * @throws KurtException anything that happens must be a {@link KurtException} so it can be caught and dealt with appropriately.
+ * Particularly, if the error is a functional error, do throw an {@link InvalidUserInputException} + */ + > void performPreAction(T report, DbReport dbReport, TcSession session) throws KurtException; + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/InteractiveEmailAction.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/InteractiveEmailAction.java new file mode 100644 index 0000000..11d5eab --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/InteractiveEmailAction.java @@ -0,0 +1,58 @@ +package com.capgemini.reports.execution.actions; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.database.manager.MngUser; +import com.capgemini.reports.emailing.templates.EmailReportHelper; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.NoConfChangesException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +import java.util.List; + +/** + * This action sends the typical email when normal reports begin execution, end their execution, or fail. + */ +public class InteractiveEmailAction implements IPostExecutionStep, IErrorExecutionStep { + private static final long serialVersionUID = -2216273173886557249L; + + private static final String DOWNLOAD_URL_SERVLET = "kurt-web/downloadServlet?reportUid="; + private static final String DOWNLOAD_URL_ROOT = SettingsHelper.getDownloadUrlRoot(); + private static final String INTERNAL_ERROR_MESSAGE = "An internal error occurred while performing the report
"; + + @Override + public > void performPostAction(TcSession tcSession, T report, DbReport dbReport, String fileNameWithExtension) throws NotFoundException { + // All the users who requested this report, at this time of the execution: END + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + List ownersAtReportEnd = new MngUser().searchReportOwners(session, dbReport); + EmailReportHelper.sendEndEmail(DOWNLOAD_URL_ROOT + DOWNLOAD_URL_SERVLET + dbReport.getReportUid(), report, ownersAtReportEnd); + } + finally { + session.close(); + } + } + + @Override + public void performTechnicalErrorAction(AbstractExecutionReport report, List owners, Throwable theOriginalException) { + EmailReportHelper.sendErrorEmail(INTERNAL_ERROR_MESSAGE, report, owners); + EmailReportHelper.sendErrorEmailToAdminsReport(INTERNAL_ERROR_MESSAGE, report); + } + + @Override + public void performFunctionalErrorAction(AbstractExecutionReport report, List owners, NoConfChangesException theOriginalException) { + // Nothing to do in this case + } + + @Override + public void performFunctionalErrorAction(AbstractExecutionReport report, List owners, InvalidInputException theOriginalException) { + EmailReportHelper.sendErrorEmail(theOriginalException.getErrorMessageForUser(), report, owners); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/LoggingAction.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/LoggingAction.java new file mode 100644 index 0000000..5e778e2 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/LoggingAction.java @@ -0,0 +1,48 @@ +package com.capgemini.reports.execution.actions; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.NoConfChangesException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.logging.ReportLoggerHelper; +import lombok.EqualsAndHashCode; + +import java.util.List; + +/** + * Logs typical report events (begin/end/error) to a special Logger setup in JBoss (using {@link ReportLoggerHelper}). + */ +@EqualsAndHashCode +public class LoggingAction implements IPostExecutionStep, IPreExecutionStep, IErrorExecutionStep { + + private static final long serialVersionUID = -2216273173886557249L; + + @Override + public > void performPreAction(T report, DbReport dbReport, TcSession session) { + // Log this event in the events log + ReportLoggerHelper.logStart(dbReport, report); + } + + @Override + public > void performPostAction(TcSession session, T report, DbReport dbReport, + String fileNameWithExtension) { + ReportLoggerHelper.logCompletion(dbReport, fileNameWithExtension, report); + } + + @Override + public void performTechnicalErrorAction(AbstractExecutionReport report, List owners, Throwable theOrginalException) { + ReportLoggerHelper.logError(theOrginalException.getMessage(), theOrginalException, report); + } + + @Override + public void performFunctionalErrorAction(AbstractExecutionReport report, List owners, NoConfChangesException theOrginalException) { + ReportLoggerHelper.logError(theOrginalException.getMessage(), theOrginalException, report); + } + + @Override + public void performFunctionalErrorAction(AbstractExecutionReport report, List owners, InvalidInputException theOrginalException) { + ReportLoggerHelper.logError(theOrginalException.getMessage(), theOrginalException, report); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/QuickCheckAction.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/QuickCheckAction.java new file mode 100644 index 0000000..9286461 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/QuickCheckAction.java @@ -0,0 +1,28 @@ +package com.capgemini.reports.execution.actions; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.checkdata.CheckingDataHelper; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.exceptions.FileLoadingException; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +/** This class is an {@link IPreExecutionStep} which performs 'quick checks' on a report. */ +@Slf4j +@EqualsAndHashCode +public class QuickCheckAction implements IPreExecutionStep { + + private static final long serialVersionUID = 8658242340621050777L; + + @Override + public > void performPreAction(T report, DbReport dbReport, TcSession session) + throws InvalidUserInputException, FileLoadingException { + // Do a quick Check. If it fails, the exception thrown will interrupt this execution + log.debug("Beggining quick checks of the scheduled {} report {}.", report.getReportIdentifier().getReportCode(), + report.getReportTechnicalUid()); + CheckingDataHelper.doQuickCheck(session, report); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ReLaunchEmailAction.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ReLaunchEmailAction.java new file mode 100644 index 0000000..b9e04d7 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ReLaunchEmailAction.java @@ -0,0 +1,55 @@ +package com.capgemini.reports.execution.actions; + +import com.capgemini.framework.common.activedirectory.ActiveDirectory; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.emailing.templates.EmailReportHelper; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.NoConfChangesException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +/** An {@link IErrorExecutionStep} that sends an email containing a link for re-launching the report. */ +@Slf4j +@AllArgsConstructor +@EqualsAndHashCode +public class ReLaunchEmailAction implements IErrorExecutionStep { + + private static final long serialVersionUID = 4317516668621824636L; + + private static final String INTERNAL_ERROR_MESSAGE = "An internal error occurred while performing the report
"; + + private final String requestURL; + + @Override + public void performTechnicalErrorAction(final AbstractExecutionReport report, List owners, Throwable theOrginalException) { + EmailReportHelper.sendWorkflowErrorEmail(INTERNAL_ERROR_MESSAGE, report, owners, requestURL); + + // Send email to all admins report + List adminReports = ActiveDirectory.getAdminsReportUpdateDatabase(); + + if (adminReports == null || adminReports.isEmpty()) { + log.error("The request for recovery of the admins report from active directory of SNECMA has returned nothing, on fail {} ", + report.getReportIdentifier()); + } else { + EmailReportHelper.sendWorkflowErrorEmailToAdminsReport(INTERNAL_ERROR_MESSAGE, report, adminReports, requestURL); + } + } + + @Override + public void performFunctionalErrorAction(AbstractExecutionReport report, List owners, NoConfChangesException theOriginalException) { + // This is a workflow execution, there are no 'functional' errors. + // Forward email handling to Technical error handler: + performTechnicalErrorAction(report, owners, theOriginalException); + } + + @Override + public void performFunctionalErrorAction(AbstractExecutionReport report, List owners, InvalidInputException theOriginalException) { + // This is a workflow execution, there are no 'functional' errors. + // Forward email handling to Technical error handler: + performTechnicalErrorAction(report, owners, theOriginalException); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ScheduledEmailAction.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ScheduledEmailAction.java new file mode 100644 index 0000000..943dcc9 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ScheduledEmailAction.java @@ -0,0 +1,49 @@ +package com.capgemini.reports.execution.actions; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.common.activedirectory.ActiveDirectory; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.emailing.templates.EmailReportHelper; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.NoConfChangesException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * This action is similar to {@link InteractiveEmailAction}, but for scheduled reports, where mail title etc. are slightly different.
+ * PArticularly, owners of a report are not considered, the emails are sent to the administrators. + */ +public class ScheduledEmailAction implements IPostExecutionStep, IErrorExecutionStep { + private static final long serialVersionUID = -2216273173886557249L; + + private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledEmailAction.class); + private static final String INTERNAL_ERROR_MESSAGE = "An internal error occurred while performing the report
"; + + @Override + public > void performPostAction(TcSession session, T report, DbReport dbReport, String fileNameWithExtension) { + String downloadURLroot = SettingsHelper.getDownloadUrlRoot(); + List ownersAtReportEnd = ActiveDirectory.getAdminsReportUpdateDatabase(); + EmailReportHelper.sendScheduledEndEmail(downloadURLroot + "kurt-web/downloadServlet?reportUid=" + report.getReportTechnicalUid(), report, ownersAtReportEnd, report.getSchedulingName()); + } + + @Override + public void performTechnicalErrorAction(AbstractExecutionReport report, List owners, Throwable theOriginalException) { + LOGGER.error("A Technical error occured", theOriginalException); + EmailReportHelper.sendScheduledErrorEmailToAdminsReport(INTERNAL_ERROR_MESSAGE, report); + } + + @Override + public void performFunctionalErrorAction(AbstractExecutionReport report, List owners, NoConfChangesException theOriginalException) { + // Nothing to do in this case + } + + @Override + public void performFunctionalErrorAction(AbstractExecutionReport report, List owners, InvalidInputException theOriginalException) { + EmailReportHelper.sendScheduledErrorEmail(theOriginalException.getErrorMessageForUser(), report, owners); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/UpdateReportAction.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/UpdateReportAction.java new file mode 100644 index 0000000..836b815 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/UpdateReportAction.java @@ -0,0 +1,52 @@ +package com.capgemini.reports.execution.actions; + +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.NoConfChangesException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import lombok.EqualsAndHashCode; + +import java.util.List; + +/** + * This action updates the {@link AbstractExecutionReport}'s internal state (primarily event times) according to events on the report lifecycle. + */ +@EqualsAndHashCode +public class UpdateReportAction implements IPreExecutionStep, IPostExecutionStep, IErrorExecutionStep { + + private static final long serialVersionUID = -5967051491832029054L; + + @Override + public > void performPreAction(T abstractExecutionReport, DbReport dbReport, TcSession session) { + // Register current time as the posting time + abstractExecutionReport.setStartTime(TeamcenterDateFormatter.getCurrentTime()); + } + + @Override + public > void performPostAction(TcSession session, T report, DbReport theExecutingReport, + String fileNameWithExtension) { + // Register current time as the end time + report.setEndTime(TeamcenterDateFormatter.getCurrentTime()); + } + + @Override + public void performTechnicalErrorAction(AbstractExecutionReport report, List owners, Throwable theOriginalException) { + // Register current time as the failure time + report.setFailureTime(TeamcenterDateFormatter.getCurrentTime()); + } + + @Override + public void performFunctionalErrorAction(AbstractExecutionReport report, List owners, NoConfChangesException theOriginalException) { + // Register current time as the failure time + report.setFailureTime(TeamcenterDateFormatter.getCurrentTime()); + } + + @Override + public void performFunctionalErrorAction(AbstractExecutionReport report, List owners, InvalidInputException theOriginalException) { + // Register current time as the failure time + report.setFailureTime(TeamcenterDateFormatter.getCurrentTime()); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/UpdateReportInDbAction.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/UpdateReportInDbAction.java new file mode 100644 index 0000000..7cb9065 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/UpdateReportInDbAction.java @@ -0,0 +1,59 @@ +package com.capgemini.reports.execution.actions; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.database.DataBaseReportHelper; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.database.javabean.enumeration.ReportErrorTypeEnum; +import com.capgemini.reports.database.manager.MngReport; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.NoConfChangesException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import lombok.EqualsAndHashCode; + +import java.util.List; + +/** + * This class manages typical interaction with DB during a report lifecycle.
+ * Can be used for: + *

    + *
  • Before executing the report: set the state as STARTED & register the report start generation date in DB
  • + *
  • After executing the report: set the state as FINISHED & register the report end generation date in DB, as well as its filename
  • + *
  • When an error occurs during execution: set the state as FAILED & register the report failure date in DB, as well as failure message
  • + *
+ */ +@EqualsAndHashCode +public class UpdateReportInDbAction implements IPreExecutionStep, IPostExecutionStep, IErrorExecutionStep { + + private static final long serialVersionUID = -5967051491832029054L; + + @Override + public > void performPreAction(T report, DbReport dbReport, TcSession session) + throws NotFoundException { + DataBaseReportHelper.registerStart(new MngReport(), report.getReportTechnicalUid()); + } + + @Override + public > void performPostAction(TcSession session, T report, DbReport theExecutingReport, + String fileNameWithExtension) throws KurtException { + MngReport theReportManager = new MngReport(); + DataBaseReportHelper.registerCompletion(theExecutingReport, fileNameWithExtension, theReportManager); + } + + @Override + public void performTechnicalErrorAction(AbstractExecutionReport report, List owners, Throwable theOriginalException) { + DataBaseReportHelper.registerError(theOriginalException.getMessage(), ReportErrorTypeEnum.TECHNICAL, report.getReportTechnicalUid()); + } + + @Override + public void performFunctionalErrorAction(AbstractExecutionReport report, List owners, NoConfChangesException theOriginalException) { + DataBaseReportHelper.registerError(theOriginalException.getMessage(), ReportErrorTypeEnum.FUNCTIONAL, report.getReportTechnicalUid()); + } + + @Override + public void performFunctionalErrorAction(AbstractExecutionReport report, List owners, InvalidInputException theOriginalException) { + DataBaseReportHelper.registerError(theOriginalException.getMessage(), ReportErrorTypeEnum.FUNCTIONAL, report.getReportTechnicalUid()); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ondataset/CreateDatasetAction.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ondataset/CreateDatasetAction.java new file mode 100644 index 0000000..39dc8e8 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ondataset/CreateDatasetAction.java @@ -0,0 +1,92 @@ +package com.capgemini.reports.execution.actions.ondataset; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.ConnectionMisconguredException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.MalformedDataSetException; +import com.capgemini.framework.teamcenter.files.FileManagement; +import com.capgemini.framework.teamcenter.files.FileManagement.FileType; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.exceptions.InvalidDatasetException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.actions.AbstractPostExecutionStep; +import com.teamcenter.services.loose.core._2006_03.FileManagement.GetDatasetWriteTicketsInputData; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import javax.inject.Provider; +import java.io.File; +import java.io.Serializable; + +/** + * This class is an action of creating a dataset, and can be performed automatically upon a report execution completion. + * + * @param the Class of the caller report + */ +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class CreateDatasetAction> extends AbstractPostExecutionStep { + + private static final long serialVersionUID = -1516821856454786852L; + + private static final PolicyLocation POLICY_XML_DATASET = PolicyLocation.make("policy_dataset", "xml/policies/common/policy_dataset.xml"); + + private final SerializableProvider fileProvider; + private final SerializableProvider datasetNameProvider; + + /** + * Creates a {@link CreateDatasetAction} to be executed when a report completes. + * + * @param Name Provider class. Must be both {@link Serializable} and a {@link String} {@link Provider}. + * @param File Provider class. Must be both {@link Serializable} and a {@link File} {@link Provider}. + * @param reportClass the caller report Class + * @param datasetNameProvider a {@link Provider} which will eventually {@link Provider#get() provide} a dataset name + * @param fileProvider a {@link Provider} which will eventually {@link Provider#get() provide} a file + */ + public & Serializable, FP extends Provider & Serializable> CreateDatasetAction(final Class reportClass, + final NP datasetNameProvider, FP fileProvider) { + super(reportClass); + // Cast is OK, because the cast interface extends both input classes + this.datasetNameProvider = (SerializableProvider) datasetNameProvider; + this.fileProvider = (SerializableProvider) fileProvider; + } + + /** + * Creates a dataset, with a file in it. + * + * @param session an active tc session + * @param datasetName the desired dataset name + * @param file the file to add to the dataset + * @param report the requesting report + * @return a Token registering the dataset request data + * @throws InvalidDatasetException if something occurred + */ + public static GetDatasetWriteTicketsInputData createDataset(final TcSession session, final String datasetName, final File file, + final AbstractExecutionReport report) throws InvalidDatasetException { + String dataSetDescription = report.getReportIdentifier().getReportTitle(); + + // Perform the upload + GetDatasetWriteTicketsInputData data; + try { + data = FileManagement.addSingleDataSet(session, datasetName, dataSetDescription, file, FileType.FICHE_ARTICLE); + } catch (MalformedDataSetException | ConnectionMisconguredException e) { + throw new InvalidDatasetException("Unable to create the dataset for the report " + report.getReportIdentifier().getReportCode() + " UID=" + report.getReportTechnicalUid(), e); + } + return data; + } + + @Override + public GetDatasetWriteTicketsInputData performPostActionOnReport(final TcSession session, final T report, + final DbReport theExecutingReport, final String fileNameWithExtension) throws KurtException { + session.setObjectPropPolicy(POLICY_XML_DATASET); + + String datasetName = datasetNameProvider.get(); + + // Create a new dataset + log.debug("Wokflow launch: Creating dataset {}", datasetName); + return createDataset(session, datasetName, fileProvider.get(), report); + } + +} + diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ondataset/DestroyRelationshipsAction.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ondataset/DestroyRelationshipsAction.java new file mode 100644 index 0000000..8733a1e --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ondataset/DestroyRelationshipsAction.java @@ -0,0 +1,81 @@ +package com.capgemini.reports.execution.actions.ondataset; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.FailedRelationshipActionException; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.IMANRelationQuery; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.actions.AbstractPostExecutionStep; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.ImanRelation; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import javax.inject.Provider; +import java.io.Serializable; +import java.util.List; + +/** + * This {@link AbstractPostExecutionStep} can destroy a Relationship between a Part and some of its datasets. + * + * @param the report class + */ +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class DestroyRelationshipsAction> extends AbstractPostExecutionStep { + + private static final long serialVersionUID = -3343435909197113891L; + + private final SerializableProvider targetIdProvider; + private final SerializableProvider datasetNameProvider; + + /** + * Constructs an action to be executed after the report generation is done. + * + * @param a name provider class. Must be both {@link Serializable} and a {@link String} {@link Provider}. + * @param reportClass the report {@link Class} + * @param targetIdProvider a {@link Provider} which will eventually {@link Provider#get() provide} the partId (target) + * @param datasetNameProvider a {@link Provider} which will eventually {@link Provider#get() provide} the dataset name + */ + public & Serializable> DestroyRelationshipsAction(Class reportClass, NP targetIdProvider, + NP datasetNameProvider) { + super(reportClass); + // Both casts are safe because a SerializableProvider is both Serializable... and a Provider + this.targetIdProvider = (SerializableProvider) targetIdProvider; + this.datasetNameProvider = (SerializableProvider) datasetNameProvider; + } + + /** + * Destroys all relationship between a part and all dataset with specific name. + * + * @param session an active Tc session + * @param datasetName the name of the dataset + * @param targetID the name of the part which holds the dataset + * @throws FailedRelationshipActionException in case the relationship could not be destroyed + */ + public static void destroyConflictingDatasets(final TcSession session, final String datasetName, final String targetID) + throws FailedRelationshipActionException { + List existingRelations = new IMANRelationQuery(session).find(targetID, datasetName); + log.debug("Wokflow launch: destroying conflicting datasets: {} relations found", existingRelations.size()); + // Let's browse all conflicting datasets + for (ImanRelation relation : existingRelations) { + ModelObject datasetMO = relation.get_secondary_object(); + + // Let's destroy the relation first + log.debug(" - Wokflow launch: destroying relation between Item {} and dataset {}", targetID, datasetMO.getUid()); + session.deleteObjects(relation); + + // Let's destroy the Dataset now that it is free from relationships + log.debug(" - Wokflow launch: destroying dataset {}", datasetMO.getUid()); + session.deleteObjects(datasetMO); + } + } + + @Override + protected Void performPostActionOnReport(final TcSession session, T reportRaw, DbReport theExecutingReport, + String fileNameWithExtension) throws FailedRelationshipActionException { + destroyConflictingDatasets(session, targetIdProvider.get(), datasetNameProvider.get()); + return null; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ondataset/LinkFicheArticleAction.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ondataset/LinkFicheArticleAction.java new file mode 100644 index 0000000..0423314 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ondataset/LinkFicheArticleAction.java @@ -0,0 +1,75 @@ +package com.capgemini.reports.execution.actions.ondataset; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.FailedRelationshipActionException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.actions.AbstractPostExecutionStep; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Item; +import lombok.EqualsAndHashCode; + +import javax.inject.Provider; +import java.io.Serializable; + +import static com.capgemini.framework.teamcenter.TeamcenterObjectTypes.IMAN_REFERENCE; + +/** + * This class is an action that may be performed after a report execution has completed. + * + * @param the class of the calling report + */ +@EqualsAndHashCode(callSuper = true) +public class LinkFicheArticleAction> extends AbstractPostExecutionStep { + + private static final long serialVersionUID = 2717496737388126196L; + + private final SerializableProvider partProvider; + private final SerializableProvider datasetProvider; + + /** + * Create a {@link LinkFicheArticleAction} that can be triggered after a report has completed its execution. + * + * @param class of the part provider. Must be both {@link Serializable} and an {@link Item} {@link Provider} + * @param class of the dataset provider. Must be both {@link Serializable} and an {@link ModelObject} {@link Provider} + * @param reportClass the Class of the report. + * @param partProvider an {@link Item} {@link Provider} which can eventually {@link Provider#get() provide} a part + * @param datasetProvider a {@link ModelObject} {@link Provider} which can eventually {@link Provider#get() provide} a dataset + */ + public & Serializable, DSP extends Provider & Serializable> LinkFicheArticleAction( + Class reportClass, PP partProvider, final DSP datasetProvider) { + super(reportClass); + // Both casts are safe because a Serializable Provider is both Serializable... and a Provider + this.partProvider = (SerializableProvider) partProvider; + this.datasetProvider = (SerializableProvider) datasetProvider; + } + + /** + * Links a Part to a dataset.
+ * If successful, a Relationship is created between the Part and the Dataset.
+ * If unsuccessful, the provided dataset will be deleted, to make sure it is not left orphaned (attached to nothing) + * + * @param session an active session + * @param thePart the target part + * @param dataset the dataset to attach + * @throws FailedRelationshipActionException whenever something fails (in which case the provided dataset is destroyed) + */ + public static void linkDatasetToPart(final TcSession session, final Item thePart, final ModelObject dataset) + throws FailedRelationshipActionException { + try { + session.createRelation(thePart, dataset, IMAN_REFERENCE); + } catch (FailedRelationshipActionException e) { + // Unable to link back the dataset to the part. Let's cleanup behind us and destroy that orphan dataset! + session.deleteObjects(dataset); + throw e; + } + } + + @Override + protected Void performPostActionOnReport(TcSession session, T reportRaw, DbReport theExecutingReport, + String fileNameWithExtension) throws KurtException { + linkDatasetToPart(session, partProvider.get(), datasetProvider.get()); + return null; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ondataset/SerializableProvider.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ondataset/SerializableProvider.java new file mode 100644 index 0000000..5049a97 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ondataset/SerializableProvider.java @@ -0,0 +1,8 @@ +package com.capgemini.reports.execution.actions.ondataset; + +import javax.inject.Provider; +import java.io.Serializable; + +interface SerializableProvider extends Provider, Serializable { + // Nothing special to add, this is just an interface fusion +} \ No newline at end of file diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ondataset/SetStatusAction.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ondataset/SetStatusAction.java new file mode 100644 index 0000000..b3b7996 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/actions/ondataset/SetStatusAction.java @@ -0,0 +1,75 @@ +package com.capgemini.reports.execution.actions.ondataset; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.UnableToCreateStatusException; +import com.capgemini.framework.teamcenter.statuating.StatusSetter; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.actions.AbstractPostExecutionStep; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.ReleaseStatus; +import com.teamcenter.soa.client.model.strong.WorkspaceObject; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import javax.inject.Provider; +import java.io.Serializable; + +/** + * This class is an action that can be used to set a {@link ReleaseStatus} on a {@link ModelObject} with a given name. + * + * @param the class of the calling report + */ +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class SetStatusAction> extends AbstractPostExecutionStep { + + private static final long serialVersionUID = -1516821856454786852L; + + private final SerializableProvider targetProvider; + private final SerializableProvider statusNameProvider; + + /** + * Creates a {@link SetStatusAction} to be executed when the report has completed its execution. + * + * @param the class of the target provider. Must be both {@link Serializable} and a {@link ModelObject} {@link Provider}. + * @param the class of the name provider. Must be both {@link Serializable} and a {@link String} {@link Provider}. + * @param targetProvider a {@link Provider} which will eventually {@link Provider#get() provide} a target {@link ModelObject}. + * @param nameProvider a {@link Provider} which will eventually {@link Provider#get() provide} a status name. + * @param reportClass the Class of the calling report. + */ + public & Serializable, NP extends Provider & Serializable> SetStatusAction(TP targetProvider, + NP nameProvider, Class reportClass) { + super(reportClass); + // Both casts are safe because a Serializable Provider is both Serializable... and a Provider + this.targetProvider = (SerializableProvider) targetProvider; + this.statusNameProvider = (SerializableProvider) nameProvider; + } + + /** + * Sets a status on a {@link ModelObject}. + * + * @param session an active Tc session + * @param target the target ModelObject + * @param statusName the desired status name + * @return the newly created status + * @throws UnableToCreateStatusException thrown if unable to create the status. + */ + public static ReleaseStatus setStatus(final TcSession session, final ModelObject target, String statusName) + throws UnableToCreateStatusException { + return new StatusSetter(session).putStatus((WorkspaceObject) target, statusName); + } + + @Override + public Void performPostActionOnReport(final TcSession session, final T report, final DbReport theExecutingReport, + final String fileNameWithExtension) throws UnableToCreateStatusException { + // Get the target + ModelObject target = targetProvider.get(); + + // Set the TcReleaseStatus on the dataset + log.debug("Wokflow launch: Adding 'Frozen' status to the object {}", target.getUid()); + setStatus(session, target, statusNameProvider.get()); + return null; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/mapconstructor/AbstractStaticTemplateMapConstructor.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/mapconstructor/AbstractStaticTemplateMapConstructor.java new file mode 100644 index 0000000..73fcb78 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/mapconstructor/AbstractStaticTemplateMapConstructor.java @@ -0,0 +1,40 @@ +package com.capgemini.reports.execution.mapconstructor; + +import com.capgemini.framework.common.ReportFolderOutputHelper; +import com.capgemini.framework.common.ResourceHelper; +import com.capgemini.reports.exceptions.FileLoadingException; +import com.capgemini.reports.exceptions.ReportPrintException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.printing.PrintReportHelper; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Simple class that will generate a {@link PrintParameters} using a fixed template file. + * + * @param the report Type + * @param the type that holds the relevant report data between the data preparator and the printer + */ +@Slf4j +@EqualsAndHashCode +public abstract class AbstractStaticTemplateMapConstructor, U> implements IMapConstructor { + + private static final long serialVersionUID = 2006289510760058068L; + + @Override + public PrintParameters makeMasterTemplate(final T report, final U optionalData) throws ReportPrintException, FileLoadingException { + String storageFolder = ReportFolderOutputHelper.getStorageFolderLocation(report.getLaunchType()); + String fileName = report.getFileNameOnDisc(); + String templateLocation = report.getTemplateLocation(); + try (InputStream templateStream = ResourceHelper.getResourceAsStream(templateLocation)) { + return PrintReportHelper.setupPrintParameters(templateStream, storageFolder, fileName, report); + } catch (IOException e) { + log.error("Unable to close the template file properly from " + templateLocation, e); + return null; // IOException is only thrown by close() which, if it ever fails, means you have much bigger problems! + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/mapconstructor/IMapConstructor.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/mapconstructor/IMapConstructor.java new file mode 100644 index 0000000..c06be56 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/mapconstructor/IMapConstructor.java @@ -0,0 +1,53 @@ +package com.capgemini.reports.execution.mapconstructor; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.exceptions.FileLoadingException; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.ReportPrintException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.printing.PrintParameters; +import net.sf.jasperreports.engine.JRException; + +import java.io.IOException; +import java.io.Serializable; +import java.util.Map; + +/** + * This interface will allow to construct data map for the reports. + * + * @param generic object for reports + * @param An intermediate Type object that contains all generated data + */ +public interface IMapConstructor, U> extends Serializable { + + /** Message to display execution time. */ + String EXECUTION_TIME_XXX_MS_FOR_YYY = "Execution time : {} ms for {}"; + + /** + * Creates the main report template.
+ * If a simple template should be loaded from the disc, use {@link AbstractStaticTemplateMapConstructor}. + * + * @param report the report to build the template for + * @param optionalData optionally, some additonal data might be required + * @return the {@link PrintParameters} with the template on board + * @throws ReportPrintException + * @throws FileLoadingException + * @throws InvalidInputException + */ + PrintParameters makeMasterTemplate(final T report, final U optionalData) throws ReportPrintException, FileLoadingException, InvalidInputException; + + /** + * Constructs some data {@link Map}s from the Tc data, and puts them into the provided PrintParameters. + * + * + * @param session + * @param printParameters the {@link PrintParameters} that must be set up + * @param reportdata will provide informations for the report which is executing + * @throws KurtException + * @throws IOException + * @throws JRException + */ + void constructDataMaps(TcSession session, final PrintParameters printParameters, final U reportdata) throws KurtException, JRException, IOException; + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/strategies/AbstractExecutionStrategy.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/strategies/AbstractExecutionStrategy.java new file mode 100644 index 0000000..87f6365 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/strategies/AbstractExecutionStrategy.java @@ -0,0 +1,212 @@ +package com.capgemini.reports.execution.strategies; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.database.manager.MngReport; +import com.capgemini.reports.database.manager.MngUser; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NoConfChangesException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.exceptions.ReportPrintException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.actions.*; +import com.capgemini.reports.printing.PrintParameters; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * This class is an abstract class which is used to manage execution behaviors to reports.
+ * There are two different behaviors for now :
+ *
    + *
  • The immediate or delayed strategy. + *
  • The scheduled strategy. + *
+ */ +@AllArgsConstructor +@EqualsAndHashCode +public abstract class AbstractExecutionStrategy implements IExecutionStrategy, Serializable { + private static final long serialVersionUID = -4156807152530226260L; + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractExecutionStrategy.class); + + private final IPreExecutionStep preAction; + private final IPostExecutionStep postAction; + private final IErrorExecutionStep errorAction; + + /** + * Constructs a default strategy, with default pre/post/error actions. + */ + AbstractExecutionStrategy() { + this.preAction = defaultPreAction(); + this.postAction = defaultPostAction(); + this.errorAction = defaultErrorAction(); + } + + /** + * Default pre-execution action. + *
    + *
  1. Update AbstractExecutionReport state (start generation date).
  2. + *
  3. Register report execution start in the DB.
  4. + *
  5. Send start email to report owners
  6. + *
  7. Log report Start event in special log file
  8. + *
  9. log effective start in technical log
  10. + *
+ */ + private static CompositePreAction defaultPreAction() { + return new CompositePreAction(new UpdateReportAction(), new UpdateReportInDbAction(), new LoggingAction()); + } + + /** + * Default post-execution action. + *
    + *
  1. Update AbstractExecutionReport state (end generation date).
  2. + *
  3. Register report execution end in the DB.
  4. + *
  5. Send end email to report owners (include the location where the report can be retrieved as a download link)
  6. + *
  7. Log report End event in special log file
  8. + *
  9. log effective end in technical log
  10. + *
+ */ + private static CompositePostAction defaultPostAction() { + return new CompositePostAction(new UpdateReportAction(), new UpdateReportInDbAction(), new InteractiveEmailAction(), new LoggingAction()); + } + + /** + * Default Error action. + *
    + *
  1. Update AbstractExecutionReport state (error date).
  2. + *
  3. Register report execution failure in the DB.
  4. + *
  5. Send end email to report owners and administrators
  6. + *
  7. Log report Failure event in special log file
  8. + *
  9. log effective end in technical log
  10. + *
+ */ + private static CompositeErrorAction defaultErrorAction() { + return new CompositeErrorAction(new UpdateReportAction(), new UpdateReportInDbAction(), new InteractiveEmailAction(), new LoggingAction()); + } + + @Override + public > void preExecutionStep(T report, TcSession tcSession) throws KurtException { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + MngReport mngReport = new MngReport(); + DbReport dbReport = mngReport.searchByUid(report.getReportTechnicalUid(), session); + preAction.performPreAction(report, dbReport, tcSession); + } + finally { + session.close(); + } + } + + @Override + public > void postExecutionStep(final T report, final String fileNameWithExtension, + TcSession tcSession) throws KurtException { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + MngReport mngReport = new MngReport(); + DbReport dbReport = mngReport.searchByUid(report.getReportTechnicalUid(), session); + postAction.performPostAction(tcSession, report, dbReport, fileNameWithExtension); + } + finally { + session.close(); + } + } + + @Override + public File print(final PrintParameters printParameters, final AbstractExecutionReport report) throws KurtException { + // Only print the report + // No need to add specific behaviors contrary to ScheduledStrategy + return printReport(printParameters, report); + } + + @Override + public String getReportFileName(final AbstractExecutionReport report) { + return report.getSpecifiedFileName(); + } + + File printReport(final PrintParameters printParameters, final AbstractExecutionReport report) throws KurtException { + try { + return report.getPrinter().print(printParameters); + } + catch (ReportPrintException e) { + throw new KurtException("JASPER print failed ", e); + } + } + + /** + * Takes care of any technical (unexpected) error.
+ * Searches the DB for report owners, then lets the on-board {@link IErrorExecutionStep} deal with it. + * + * @param report the report which just crashed + * @param theThrowable the exception that caused all the turmoil + */ + @Override + public void handleTechnicalError(final AbstractExecutionReport report, final Throwable theThrowable) { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + DbReport dbReport = new MngReport().searchByUid(report.getReportTechnicalUid(), session); + List owners = new MngUser().searchReportOwners(session, dbReport); + errorAction.performTechnicalErrorAction(report, owners, theThrowable); + } + catch (NotFoundException e) { + LOGGER.warn("Handling a prior technical error, could not find the original owners UID=" + report.getReportTechnicalUid(), e); + } + finally { + session.close(); + } + } + + /** + * Takes care of any functional (unexpected) error.
+ * Searches the DB for report owners, then lets the on-board {@link IErrorExecutionStep} deal with it. + * + * @param report the report which just crashed + * @param error the exception that caused all the turmoil + */ + @Override + public void handleFunctionalError(final AbstractExecutionReport report, final NoConfChangesException error) { + LOGGER.info(error.getMessage()); + errorAction.performFunctionalErrorAction(report, owners(report), error); + } + + /** + * Takes care of any functional (unexpected) error.
+ * Searches the DB for report owners, then lets the on-board {@link IErrorExecutionStep} deal with it. + * + * @param report the report which just crashed + * @param error the exception that caused all the turmoil + */ + @Override + public void handleFunctionalError(final AbstractExecutionReport report, final InvalidUserInputException error) { + errorAction.performFunctionalErrorAction(report, owners(report), error); + } + + protected List owners(AbstractExecutionReport report) { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + DbReport dbReport = new MngReport().searchByUid(report.getReportTechnicalUid(), session); + return new MngUser().searchReportOwners(session, dbReport); + } + catch (NotFoundException e) { + LOGGER.warn("Handling a prior technical error, could not find the original owners of report with UID=" + report.getReportTechnicalUid(), e); + return new ArrayList<>(); + } + finally { + session.close(); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/strategies/AutomaticExecutionStrategy.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/strategies/AutomaticExecutionStrategy.java new file mode 100644 index 0000000..eac1981 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/strategies/AutomaticExecutionStrategy.java @@ -0,0 +1,76 @@ +package com.capgemini.reports.execution.strategies; + +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.execution.actions.*; +import lombok.EqualsAndHashCode; + +/** + * Strategy for reports launched automatically, via a workflow.
+ * In this strategy, no email are sent except on error cases, in which case a re-launch URL is provided. + */ +@EqualsAndHashCode(callSuper = true) +public class AutomaticExecutionStrategy extends AbstractExecutionStrategy { + + private static final long serialVersionUID = -476263626956824427L; + + /** + * Prepares a strategy for automatic execution. + * @param requestURL a URL that allows the process to be executed again in case of an error + */ + public AutomaticExecutionStrategy(String requestURL) { + super(makePreAction(new DoNothingAction()), makePostAction(new DoNothingAction()), makeErrorActionPlan(requestURL)); + } + + /** + * Prepares a strategy for automatic execution. + * @param requestURL a URL that allows the process to be executed again in case of an error + * @param specializedPreAction a special action to perform before anything is done on this report + * @param specializedPostAction a special action to perform right after the report has been generated + */ + public AutomaticExecutionStrategy(String requestURL, final IPreExecutionStep specializedPreAction, + final IPostExecutionStep specializedPostAction) { + super(makePreAction(specializedPreAction), makePostAction(specializedPostAction), makeErrorActionPlan(requestURL)); + } + + /** + * Pre-execution action for reports launched automatically by workflow. + *
    + *
  1. Update AbstractExecutionReport state (startDate).
  2. + *
  3. Register report execution start in the DB.
  4. + *
  5. Log report Start event i special log file
  6. + *
  7. log effective start in technical log
  8. + *
+ * Note: no email sent in normal execution flow + */ + private static CompositePreAction makePreAction(final IPreExecutionStep specializedPreAction) { + // Be sure to NOT include mails of any kind in normal report execution actions + return new CompositePreAction(specializedPreAction, new UpdateReportAction(), new UpdateReportInDbAction(), new LoggingAction()); + } + + /** + * post-execution action for reports launched automatically by workflow. + *
    + *
  1. Update AbstractExecutionReport state (endDate).
  2. + *
  3. Register report execution end in the DB.
  4. + *
  5. Send end email to report owners (include the location where the report can be retrieved as a download link)
  6. + *
  7. log effective end in technical log
  8. + *
+ * + * @param report the report which has been completed + */ + private static CompositePostAction makePostAction(final IPostExecutionStep specializedPostAction) { + // Be sure to NOT include mails of any kind in normal report execution actions + return new CompositePostAction(specializedPostAction, new UpdateReportAction(), new UpdateReportInDbAction(), new LoggingAction()); + } + + private static IErrorExecutionStep makeErrorActionPlan(String requestURL) { + return new CompositeErrorAction(new UpdateReportAction(), new UpdateReportInDbAction(), new LoggingAction(), + new ReLaunchEmailAction(requestURL)); + } + + @Override + public ReportLaunchTypeEnum getLaunchType() { + return ReportLaunchTypeEnum.AUTOMATIC; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/strategies/DelayedExecutionStrategy.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/strategies/DelayedExecutionStrategy.java new file mode 100644 index 0000000..f3c0968 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/strategies/DelayedExecutionStrategy.java @@ -0,0 +1,16 @@ +package com.capgemini.reports.execution.strategies; + +import com.capgemini.reports.ReportLaunchTypeEnum; +import lombok.EqualsAndHashCode; + +/** Execution flow for report that is requested but must be postponed until later this day. */ +@EqualsAndHashCode(callSuper = true) +public class DelayedExecutionStrategy extends AbstractExecutionStrategy { + + private static final long serialVersionUID = -7625339402185787331L; + + @Override + public final ReportLaunchTypeEnum getLaunchType() { + return ReportLaunchTypeEnum.DELAYED; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/strategies/IExecutionStrategy.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/strategies/IExecutionStrategy.java new file mode 100644 index 0000000..36f657a --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/strategies/IExecutionStrategy.java @@ -0,0 +1,102 @@ +package com.capgemini.reports.execution.strategies; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NoConfChangesException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.printing.PrintParameters; + +import java.io.File; +import java.io.Serializable; + +/** + * This interface represents a strategy of report's execution.
+ * According to the launch type, we have different strategies :
+ *
    + *
  • A strategy for immediate reports. + *
  • A strategy for delayed reports. + *
  • A strategy for scheduled report. + *
+ */ +public interface IExecutionStrategy extends Serializable { + + /** + * Perform the printing step of a report : the generation of the file and the folders output.
+ *
    + *
  • An IMMEDIATE or DELAYED report just print its report. + *
  • A SCHEDULED report must manage its two output folders and print the report inside both of them.
    + * There is one folder of output an another of history.
    + * In the history folder, we can find all the generated scheduled report.
    + * In the scheduled output folder, we just find the last generated report of each scheduling. + *
+ * + * @param printParameters {@link PrintParameters} - the parameters used in the template Jasper to do a report + * @param report {@link AbstractExecutionReport} - the report with his own specificities + * @return the printed {@link File} + * @throws KurtException + */ + File print(final PrintParameters printParameters, final AbstractExecutionReport report) throws KurtException; + + /** + * Defines what is to be done before the report starts to execute. + * + * @param report the report instance + * @param the exact report type + * @throws KurtException + */ + > void preExecutionStep(final T report, TcSession session) throws KurtException; + + /** + * Defines what is to be done after the report has completed its execution. + * + * @param the exact report type + * @param report the report instance + * @param fileNameWithExtension the file name + * @throws KurtException + */ + > void postExecutionStep(final T report, final String fileNameWithExtension, + TcSession session) throws KurtException; + + /** + * Construct the name of the file.
+ * For IMMEDIATE or DELAYED report, each report has its own name.
+ * For SCHEDULED report, the name is specific to the report code, the scheduling and the execution date. + * + * @param report {@link AbstractExecutionReport} - the report which his specificities (code, file name,...) + * @return the file name + */ + String getReportFileName(final AbstractExecutionReport report); + + /** + * The type of launch (as a {@link ReportLaunchTypeEnum}). + * + * @return DELAYED, SCHEDULED, IMMEDIATE, AUTOMATIC + */ + ReportLaunchTypeEnum getLaunchType(); + + /** + * Handles a functional error by the user. + * + * @param report the report which failed + * @param error the exception that was encountered (an {@link NoConfChangesException}) + */ + void handleFunctionalError(AbstractExecutionReport report, NoConfChangesException error); + + /** + * Handles a functional error by the user. + * + * @param report the report which failed + * @param error the exception that was encountered (an {@link InvalidUserInputException}) + */ + void handleFunctionalError(AbstractExecutionReport report, InvalidUserInputException error); + + /** + * Handles a technical error. + * + * @param report the report which failed + * @param theThrowable the exception that was encountered + */ + void handleTechnicalError(AbstractExecutionReport report, Throwable theThrowable); +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/strategies/ImmediateExecutionStrategy.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/strategies/ImmediateExecutionStrategy.java new file mode 100644 index 0000000..470d375 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/strategies/ImmediateExecutionStrategy.java @@ -0,0 +1,16 @@ +package com.capgemini.reports.execution.strategies; + +import com.capgemini.reports.ReportLaunchTypeEnum; +import lombok.EqualsAndHashCode; + +/** Execution flow for report that is requested and must be executed immediately. */ +@EqualsAndHashCode(callSuper = true) +public class ImmediateExecutionStrategy extends AbstractExecutionStrategy { + + private static final long serialVersionUID = -4519380941500076374L; + + @Override + public final ReportLaunchTypeEnum getLaunchType() { + return ReportLaunchTypeEnum.IMMEDIATE; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/execution/strategies/ScheduledExecutionStrategy.java b/kurt-utility/src/main/java/com/capgemini/reports/execution/strategies/ScheduledExecutionStrategy.java new file mode 100644 index 0000000..24b1143 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/execution/strategies/ScheduledExecutionStrategy.java @@ -0,0 +1,143 @@ +package com.capgemini.reports.execution.strategies; + +import com.capgemini.framework.common.DateHelper; +import com.capgemini.framework.common.ReportFolderOutputHelper; +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.javabean.DbReportOwner; +import com.capgemini.reports.database.manager.MngReport; +import com.capgemini.reports.database.manager.MngReportOwner; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.actions.*; +import com.capgemini.reports.printing.PrintParameters; +import com.google.common.io.Files; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +import java.io.File; +import java.io.IOException; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.List; + +/** + * Class representing the strategy to execute for scheduled reports. + */ +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class ScheduledExecutionStrategy extends AbstractExecutionStrategy { + private static final long serialVersionUID = -1874201095083131827L; + /** + * Location in HD of the folder where the latest version of scheduled reports are kept. + */ + private static final String SCHEDULING_LOCATION_OUTPUT = SettingsHelper.getSchedulingLocation(); + + /** + * PRepares an execution strategy for scheduled reports. + */ + public ScheduledExecutionStrategy() { + super(new CompositePreAction(new UpdateReportAction(), new QuickCheckAction(), new UpdateReportInDbAction(), new LoggingAction()), + new CompositePostAction(new UpdateReportAction(), new UpdateReportInDbAction(), new ScheduledEmailAction(), new LoggingAction()), makeSchedulingDefaultErrorAction()); + } + + + private static IErrorExecutionStep makeSchedulingDefaultErrorAction() { + UpdateReportAction updateReportAction = new UpdateReportAction(); + UpdateReportInDbAction updateReportInDbAction = new UpdateReportInDbAction(); + ScheduledEmailAction scheduledEmailAction = new ScheduledEmailAction(); + LoggingAction loggingAction = new LoggingAction(); + return new CompositeErrorAction(updateReportAction, updateReportInDbAction, scheduledEmailAction, loggingAction); + } + + @Override + public final ReportLaunchTypeEnum getLaunchType() { + return ReportLaunchTypeEnum.SCHEDULED; + } + + + @Override + public File print(final PrintParameters printParameters, final AbstractExecutionReport report) throws KurtException { + String fileNameShort = fileNameShort(report) + printParameters.getOuputFileExtension(); + if (ReportFolderOutputHelper.checkIfAlreadyLaunched(report.getSchedulingId())) { + // It has already launched so we have to delete the precedent file in the scheduled output folder + // But the history folder doesn't change + try { + ReportFolderOutputHelper.deleteScheduledReportFile(fileNameShort); + } + catch (NotFoundException e) { + log.warn("Unable to delete file generated by previous scheduled execution. Continuing scheduled job.", e); + } + } + + File original = printReport(printParameters, report); + File scheduledFile = new File(SCHEDULING_LOCATION_OUTPUT + fileNameShort); + try { + Files.move(original, scheduledFile); // This RENAMES the file + log.debug("Renamed scheduling file [{}] to [{}]", original.getAbsoluteFile(), scheduledFile.getAbsolutePath()); + } + catch (IOException e) { + File originalFileName = original.getAbsoluteFile(); + String destinationFileName = scheduledFile.getAbsolutePath(); + throw new KurtException("Unable to rename file " + originalFileName + " to " + destinationFileName, e); + } + + // Add the scheduled report in the historic folder + String reportFileNameHistory = getReportFileName(report) + printParameters.getOuputFileExtension(); + try { + ReportFolderOutputHelper.copyToHistoryFolder(scheduledFile, reportFileNameHistory); + log.debug("Saved scheduling file [{}] to history [{}]", scheduledFile.getAbsoluteFile(), reportFileNameHistory); + } + catch (IOException e) { + File originalFileName = scheduledFile.getAbsoluteFile(); + throw new KurtException("Unable to copy file " + originalFileName + " to " + reportFileNameHistory, e); + } + + // Now update DB + MngReport mng = new MngReport(); + mng.updateFileName(report.getReportTechnicalUid(), reportFileNameHistory); + log.debug("Registering report {} file name {} to DB ", report.getReportTechnicalUid(), reportFileNameHistory); + return scheduledFile; + } + + @Override + public String getReportFileName(final AbstractExecutionReport report) { + // Give the name : reportcode+"-"+schedulingname+"-"+postingDate + Timestamp date; + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + MngReport mngReport = new MngReport(); + DbReport dbReport = mngReport.searchByUid(report.getReportTechnicalUid(), session); + List owners = new MngReportOwner().searchReportOwners(session, dbReport.getId()); + if (owners.isEmpty()) { + date = DateHelper.getCurrentSqlTimestamp(); + log.error("No owners of scheduled report, using default scheduling name for file name"); + } + else { + date = owners.get(0).getRequestDate(); + } + } + catch (NotFoundException e) { + date = DateHelper.getCurrentSqlTimestamp(); + log.error("Report not found in DB, using default scheduling name for file name", e); + } + finally { + session.close(); + } + String dateStr = new SimpleDateFormat("yyyyMMdd_HHmmss").format(date); + String fileNameShort = fileNameShort(report); + return fileNameShort + "-" + dateStr; + } + + private String fileNameShort(final AbstractExecutionReport report) { + String reportCode = report.getReportIdentifier().getReportCode(); + String schedulingName = report.getSchedulingName(); + return reportCode + "-" + schedulingName; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/logging/EventsLogger.java b/kurt-utility/src/main/java/com/capgemini/reports/logging/EventsLogger.java new file mode 100644 index 0000000..46efccb --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/logging/EventsLogger.java @@ -0,0 +1,31 @@ +package com.capgemini.reports.logging; + +import lombok.extern.slf4j.Slf4j; + +/** This class merely re-directs logs into this package to have all main events gathered in a single log file. */ +@Slf4j +public final class EventsLogger { + + private EventsLogger() { + // Nothing to do... + } + + /** + * Logs a message. + * + * @param msg a message + */ + public static void log(final String msg) { + log.info(msg); + } + + /** + * Logs an error message, as well as the {@link Throwable} event that caused the error. + * + * @param msg a message. + * @param error an error + */ + public static void log(final String msg, final Throwable error) { + log.error(msg, error); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/logging/ReportLoggerHelper.java b/kurt-utility/src/main/java/com/capgemini/reports/logging/ReportLoggerHelper.java new file mode 100644 index 0000000..8e68740 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/logging/ReportLoggerHelper.java @@ -0,0 +1,181 @@ +package com.capgemini.reports.logging; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.javabean.DbSchedulingReport; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.database.manager.MngCriteriaVal; +import com.capgemini.reports.database.manager.MngReport; +import com.capgemini.reports.database.manager.MngSchedulingCriteriaVal; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.google.common.base.Joiner; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +import java.text.SimpleDateFormat; + +/** + * This class will provide all methods which will allow to log every step of the report's execution. + */ +@Slf4j +public final class ReportLoggerHelper { + private static final String TITLE_REPORT = "Rapport "; + + private static final String ENTRY_ERROR_MESSAGE = " - Message d'erreur: "; + private static final String ENTRY_WITH_CRITERIA = " - Avec les critères suivants:"; + private static final String ENTRY_BY_USER = " - par l'utilisateur '"; + private static final String ENTRY_UID = " - UID="; + private static final String ENTRY_FINISHED = " - terminé le "; + private static final String ENTRY_STARTED = " - Démarré le "; + private static final String ENTRY_DASH = " - "; + private static final String ENTRY_STATUS = " - TcReleaseStatus="; + + private static final String STATUS_AUTOMATIC = " par workflow"; + private static final String STATUS_DELAYED = " en différé"; + private static final String STATUS_SCHEDULING_LAUNCHED = " programmé par planification et actuellement lancé "; + private static final String STATUS_SCHEDULED = " planifié"; + private static final String MSG_NO_REPORT_FOUND_WITH_THIS_ID = " (No report found with this ID)"; + + private ReportLoggerHelper() { + + } + + /** + * To log the beginning of the report's execution. + * + * @param aTheExecutingReport will provide the informations of the report on the database + * @param aAbstractExecutionReport will provide the informations of the report's execution + */ + public static void logStart(final DbReport aTheExecutingReport, final AbstractExecutionReport aAbstractExecutionReport) { + StringBuilder logMsg = new StringBuilder("Début de l'exécution du rapport ") + .append(aAbstractExecutionReport.getReportIdentifier().buildCompleteReportName()); + logMsg.append(ENTRY_UID).append(getSafeUID(aTheExecutingReport)); + logMsg.append(ENTRY_STARTED).append(aAbstractExecutionReport.getStartTime()); + EventsLogger.log(logMsg.toString()); + + } + + private static String getSafeUID(final DbReport aTheExecutingReport) { + if (aTheExecutingReport == null || aTheExecutingReport.getReportUid() == null) { + return MSG_NO_REPORT_FOUND_WITH_THIS_ID; + } + else { + return aTheExecutingReport.getReportUid(); + } + } + + /** + * Logs the fact that a report's exectution reached completion, in a specific file (the file is specified by the log appender in the logging properties of JBoss). + * + * @param theExecutingReport the report being executed, as written in the database. + * @param fileNameWithExtension the file location of the generated report. + * @param aAbstractExecutionReport will provide the informations of the report + */ + public static void logCompletion(final DbReport theExecutingReport, final String fileNameWithExtension, + final AbstractExecutionReport aAbstractExecutionReport) { + StringBuilder logMsg = new StringBuilder(TITLE_REPORT).append(aAbstractExecutionReport.getReportIdentifier().buildCompleteReportName()) + .append(" terminé avec succès"); + logMsg.append(ENTRY_UID).append(getSafeUID(theExecutingReport)); + logMsg.append(ENTRY_STARTED).append(aAbstractExecutionReport.getStartTime()); + logMsg.append(ENTRY_FINISHED).append(aAbstractExecutionReport.getEndTime()); + logMsg.append(ENTRY_STATUS).append(theExecutingReport == null ? MSG_NO_REPORT_FOUND_WITH_THIS_ID : theExecutingReport.getState()); + logMsg.append(" - Fichier généré : ").append(fileNameWithExtension); + EventsLogger.log(logMsg.toString()); + } + + /** + * Log the provided error and message in a specific file (the file is specified by the log appender in the logginig properties of JBoss). + * + * @param msg An error Message + * @param error the actual error that caused this log + * @param aAbstractExecutionReport will provide the informations of the report + */ + public static void logError(final String msg, final Throwable error, final AbstractExecutionReport aAbstractExecutionReport) { + DbReport theExecutingReport = null; + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + theExecutingReport = new MngReport().searchByUid(aAbstractExecutionReport.getReportTechnicalUid(), session); + } + catch (NotFoundException e) { + log.error("Unable to find a report in DB, can't log", e); + } + finally { + session.close(); + } + String status; + if (theExecutingReport != null) { + status = theExecutingReport.getState(); + } + else { + status = MSG_NO_REPORT_FOUND_WITH_THIS_ID; + } + + StringBuilder logMsg = + new StringBuilder(TITLE_REPORT).append(aAbstractExecutionReport.getReportIdentifier().buildCompleteReportName()).append(" en échec"); + logMsg.append(ENTRY_UID).append(aAbstractExecutionReport.getReportTechnicalUid()); + logMsg.append(ENTRY_STARTED).append(aAbstractExecutionReport.getStartTime()); + logMsg.append(ENTRY_FINISHED).append(aAbstractExecutionReport.getFailureTime()); + logMsg.append(ENTRY_STATUS).append(status); + logMsg.append(ENTRY_ERROR_MESSAGE).append(msg); + EventsLogger.log(logMsg.toString(), error); + } + + /** + * Logs the fact that a report was requested by a user, in a specific file (the file is specified by the log appender in the logginig properties of JBoss). + */ + public static void logRequest(final DbUser requestingUser, final DbReport theExecutingReport, final AbstractExecutionReport aAbstractExecutionReport) { + StringBuilder logMsg = + new StringBuilder(TITLE_REPORT).append(aAbstractExecutionReport.getReportIdentifier().buildCompleteReportName()).append(" lancé"); + + // Specially for delayed reports + switch (aAbstractExecutionReport.getLaunchType()) { + case AUTOMATIC: + logMsg.append(STATUS_AUTOMATIC); + break; + case DELAYED: + logMsg.append(STATUS_DELAYED); + break; + default: + break; + } + + logMsg.append(ENTRY_UID).append(getSafeUID(theExecutingReport)); + logMsg.append(ENTRY_BY_USER).append(requestingUser.getLogin()).append('\''); + logMsg.append(ENTRY_WITH_CRITERIA); + logMsg.append(StringHelper.implodeList(ENTRY_DASH, new MngCriteriaVal().searchCriteriasByReportUID(theExecutingReport.getReportUid()))); + logMsg.append(ENTRY_STARTED).append(aAbstractExecutionReport.getPostingTime()); + EventsLogger.log(logMsg.toString()); + } + + /** + * Logs the fact that a scheduling was requested by a user, in a specific file (the file is specified by the log appender in the logginig properties of JBoss).
+ */ + public static void logSchedulingRequestWaiting(Session session, final DbUser requestingUser, final DbSchedulingReport theExecutingReport, + final AbstractExecutionReport aAbstractExecutionReport) { + StringBuilder logMsg = new StringBuilder(TITLE_REPORT).append(aAbstractExecutionReport.getReportIdentifier().buildCompleteReportName()) + .append(STATUS_SCHEDULED); + logMsg.append(ENTRY_BY_USER).append(requestingUser.getLogin()).append('\''); + logMsg.append(ENTRY_WITH_CRITERIA); + logMsg.append(Joiner.on(ENTRY_DASH).join(new MngSchedulingCriteriaVal().searchCriteria(session, theExecutingReport.getId()))); + logMsg.append(" - Planifié le ").append(new SimpleDateFormat(TeamcenterDateFormatter.DD_MM_YYYY).format(theExecutingReport.getLastUpdate())); + EventsLogger.log(logMsg.toString()); + } + + + /** + * Logs the fact that a scheduled report was posted, in a specific file (the file is specified by the log appender in the logginig properties of JBoss). + */ + public static void logSchedulingRequest(final DbReport theExecutingReport, final AbstractExecutionReport aAbstractExecutionReport) { + StringBuilder logMsg = new StringBuilder(TITLE_REPORT).append(aAbstractExecutionReport.getReportIdentifier().buildCompleteReportName()) + .append(STATUS_SCHEDULING_LAUNCHED); + logMsg.append(ENTRY_WITH_CRITERIA); + logMsg.append(StringHelper.implodeList(ENTRY_DASH, new MngCriteriaVal().searchCriteriasByReportUID(theExecutingReport.getReportUid()))); + logMsg.append(ENTRY_STARTED).append(aAbstractExecutionReport.getPostingTime()); + EventsLogger.log(logMsg.toString()); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/optimized/Folder.java b/kurt-utility/src/main/java/com/capgemini/reports/optimized/Folder.java new file mode 100644 index 0000000..fa231b7 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/optimized/Folder.java @@ -0,0 +1,53 @@ +package com.capgemini.reports.optimized; + +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class Folder { + private final Path path; + + public Folder(Path path) { + this.path = path; + } + + public Path mostRecentFile() throws IOException { + List files = new ArrayList<>(); + try (DirectoryStream directoryStream = Files.newDirectoryStream(path)) { + for (Path file : directoryStream) { + if (!file.toFile().isDirectory()) { + files.add(file); + } + } + } + + // Sort newest file is first element + Collections.sort(files, new Comparator() { + public int compare(Path o1, Path o2) { + try { + return Files.getLastModifiedTime(o2).compareTo(Files.getLastModifiedTime(o1)); + } + catch (IOException e) { + return 0; + } + } + }); + + return files.get(0); + } + + public boolean exist() { + return path.toFile().exists(); + } + + public boolean isEmpty() throws IOException { + try (DirectoryStream directoryStream = Files.newDirectoryStream(path)) { + return !directoryStream.iterator().hasNext(); + } + } +} \ No newline at end of file diff --git a/kurt-utility/src/main/java/com/capgemini/reports/optimized/OptimizedFile.java b/kurt-utility/src/main/java/com/capgemini/reports/optimized/OptimizedFile.java new file mode 100644 index 0000000..7e6376f --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/optimized/OptimizedFile.java @@ -0,0 +1,11 @@ +package com.capgemini.reports.optimized; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.reports.parameters.ProductUnit; + +import java.io.IOException; + +public interface OptimizedFile { + + boolean contains(final ProductUnit productUnit) throws KurtException, IOException; +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/optimized/OptimizedFolder.java b/kurt-utility/src/main/java/com/capgemini/reports/optimized/OptimizedFolder.java new file mode 100644 index 0000000..2f75342 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/optimized/OptimizedFolder.java @@ -0,0 +1,10 @@ +package com.capgemini.reports.optimized; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.reports.parameters.ProductUnit; + +public interface OptimizedFolder { + + boolean configurationHasNotChanged(ProductUnit productUnit) throws KurtException; + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/optimized/r23report/OptimizedR23File.java b/kurt-utility/src/main/java/com/capgemini/reports/optimized/r23report/OptimizedR23File.java new file mode 100644 index 0000000..92d4ac3 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/optimized/r23report/OptimizedR23File.java @@ -0,0 +1,37 @@ +package com.capgemini.reports.optimized.r23report; + +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.optimized.OptimizedFile; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.opencsv.CSVReader; + +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; + +public class OptimizedR23File implements OptimizedFile { + + private final Path path; + + public OptimizedR23File(final Path path) { + this.path = path; + } + + @Override + public boolean contains(ProductUnit productUnit) throws IOException, InvalidUserInputException { + try (CSVReader reader = new CSVReader(new FileReader(path.toFile()), ';', '"', 0)) { + List records = reader.readAll(); + for (String[] record : records) { + if (record.length < 1) { + throw new InvalidUserInputException(UserInputErrorEnum.INVALID_FILE); + } + if (record[0].equals(productUnit.getProductID())) { + return true; + } + } + } + return false; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/optimized/r23report/OptimizedR23Folder.java b/kurt-utility/src/main/java/com/capgemini/reports/optimized/r23report/OptimizedR23Folder.java new file mode 100644 index 0000000..16d5f49 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/optimized/r23report/OptimizedR23Folder.java @@ -0,0 +1,26 @@ +package com.capgemini.reports.optimized.r23report; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.optimized.Folder; +import com.capgemini.reports.optimized.OptimizedFolder; +import com.capgemini.reports.reports.parameters.ProductUnit; + +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class OptimizedR23Folder implements OptimizedFolder { + private static final Path PATH = Paths.get(SettingsHelper.getOptimizedFolderR23()); + + @Override + public boolean configurationHasNotChanged(final ProductUnit productUnit) throws KurtException { + Folder folder = new Folder(PATH); + try { + return folder.exist() && !folder.isEmpty() && !new OptimizedR23File(folder.mostRecentFile()).contains(productUnit); + } + catch (IOException e) { + throw new KurtException(e.getMessage(), e); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/optimized/r24report/OptimizedR24File.java b/kurt-utility/src/main/java/com/capgemini/reports/optimized/r24report/OptimizedR24File.java new file mode 100644 index 0000000..a01d3d4 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/optimized/r24report/OptimizedR24File.java @@ -0,0 +1,38 @@ +package com.capgemini.reports.optimized.r24report; + +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.optimized.OptimizedFile; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.opencsv.CSVReader; + +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; + +public class OptimizedR24File implements OptimizedFile { + + private final Path path; + + public OptimizedR24File(final Path path) { + this.path = path; + } + + @Override + public boolean contains(ProductUnit productUnit) throws IOException, InvalidUserInputException { + try (CSVReader reader = new CSVReader(new FileReader(path.toFile()), ';', '"', 0)) { + List records = reader.readAll(); + for (String[] record : records) { + if (record.length < 2) { + throw new InvalidUserInputException(UserInputErrorEnum.INVALID_FILE); + } + if (record[0].equals(productUnit.getProductID()) && record[1].equals(productUnit.getUnitStr())) { + return true; + } + } + } + + return false; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/optimized/r24report/OptimizedR24Folder.java b/kurt-utility/src/main/java/com/capgemini/reports/optimized/r24report/OptimizedR24Folder.java new file mode 100644 index 0000000..1cb3cff --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/optimized/r24report/OptimizedR24Folder.java @@ -0,0 +1,26 @@ +package com.capgemini.reports.optimized.r24report; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.optimized.Folder; +import com.capgemini.reports.optimized.OptimizedFolder; +import com.capgemini.reports.reports.parameters.ProductUnit; + +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class OptimizedR24Folder implements OptimizedFolder { + private static final Path PATH = Paths.get(SettingsHelper.getOptimizedFolderR24()); + + @Override + public boolean configurationHasNotChanged(final ProductUnit productUnit) throws KurtException { + Folder folder = new Folder(PATH); + try { + return folder.exist() && !folder.isEmpty() && !new OptimizedR24File(folder.mostRecentFile()).contains(productUnit); + } + catch (IOException e) { + throw new KurtException(e.getMessage(), e); + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/periodicity/DailyPeriod.java b/kurt-utility/src/main/java/com/capgemini/reports/periodicity/DailyPeriod.java new file mode 100644 index 0000000..de38bf4 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/periodicity/DailyPeriod.java @@ -0,0 +1,44 @@ +package com.capgemini.reports.periodicity; + +import com.capgemini.reports.database.javabean.enumeration.SchedulingEnum; +import com.capgemini.reports.database.manager.MngSchedulingCriteriaVal.SchedulingCriteriaValue; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a daily execution. + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class DailyPeriod implements SchedulingPeriod { + + private static final DailyPeriod instance = new DailyPeriod(); + + /** + * Get an instance. All instances are the same as this one (singleton). + * + * @return an instance + */ + public static DailyPeriod getInstance() { + return instance; + } + + @Override + public SchedulingEnum getPeriodicity() { + return SchedulingEnum.DAILY; + } + + @Override + public T accept(final PeriodVisitor visitor) { + return visitor.visit(this); + } + + @Override + public List asCriteriaValues() { + List list = new ArrayList<>(1); + list.add(new SchedulingCriteriaValue(SchedulingEnum.PERIOD, SchedulingEnum.DAILY.getCriteriaName())); + return list; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/periodicity/DayInMonth.java b/kurt-utility/src/main/java/com/capgemini/reports/periodicity/DayInMonth.java new file mode 100644 index 0000000..9d79089 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/periodicity/DayInMonth.java @@ -0,0 +1,45 @@ +package com.capgemini.reports.periodicity; + +import com.capgemini.reports.database.javabean.enumeration.SchedulingEnum; +import com.capgemini.reports.database.manager.MngSchedulingCriteriaVal.SchedulingCriteriaValue; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents an periodicity that occurs on a specific day, each month. + */ +@Getter +public class DayInMonth implements SchedulingPeriod { + + private final Integer dayInMonth; + + /** + * Builds a instance. + * + * @param dayInMonth the day in the month. [1-31] + */ + public DayInMonth(final int dayInMonth) { + this.dayInMonth = dayInMonth; + } + + @Override + public SchedulingEnum getPeriodicity() { + return SchedulingEnum.DAY_IN_MONTH_VALUE; + } + + @Override + public T accept(final PeriodVisitor visitor) { + return visitor.visit(this); + } + + @Override + public List asCriteriaValues() { + List list = new ArrayList<>(2); + list.add(new SchedulingCriteriaValue(SchedulingEnum.PERIOD, SchedulingEnum.DAY_IN_MONTH_VALUE.getCriteriaName())); + list.add(new SchedulingCriteriaValue(SchedulingEnum.DAY_IN_MONTH_VALUE, String.valueOf(dayInMonth))); + return list; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/periodicity/PeriodFactory.java b/kurt-utility/src/main/java/com/capgemini/reports/periodicity/PeriodFactory.java new file mode 100644 index 0000000..b9ed3aa --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/periodicity/PeriodFactory.java @@ -0,0 +1,176 @@ +package com.capgemini.reports.periodicity; + +import com.capgemini.reports.database.javabean.DbSchedulingCriteriaVal; +import com.capgemini.reports.database.javabean.enumeration.SchedulingEnum; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.InvalidUserInputException; + +import java.text.ParseException; +import java.util.Calendar; +import java.util.List; + +/** Factory class to easily build the various types of scheduling. */ +public final class PeriodFactory { + + private PeriodFactory() { + // Nothing to do + } + + /** + * Builds a {@link SchedulingPeriod} that occurs once every week. + * + * @param dayInWeek the day of the week. + * @return a {@link SchedulingPeriod} + */ + public static WeeklyPeriod weekly(final int dayInWeek) { + return new WeeklyPeriod(dayInWeek); + } + + /** + * Builds a {@link SchedulingPeriod} that occurs every day. + * + * @return a {@link SchedulingPeriod} + */ + public static DailyPeriod daily() { + return DailyPeriod.getInstance(); + } + + /** + * Builds a {@link SchedulingPeriod} that occurs once, on a specific day. + * + * @param day the day of the execution. + * @return a {@link SchedulingPeriod} + * @throws ParseException if unable to parse the String date + */ + public static SpecificDay day(final String day) throws ParseException { + return new SpecificDay(day); + } + + /** + * Builds a {@link SchedulingPeriod} that occurs once every month. + * + * @param dayInMonth the day of the month. + * @return a {@link SchedulingPeriod} + */ + public static DayInMonth dayInMonth(final int dayInMonth) { + return new DayInMonth(dayInMonth); + } + + /** + * Builds a {@link SchedulingPeriod} that occurs once every month, on a weekend. + * + * @param weekend the weekend. + * @return a {@link SchedulingPeriod} + */ + public static WeekendPeriod weekend(final String weekend) { + return WeekendPeriod.getEnum(weekend); + } + + /** + * Builds a {@link SchedulingPeriod} out of a series of Db entries (@link SchedulingPeriod}s). + * + * @param criteria a {@link List} of {@link DbSchedulingCriteriaVal} obtained from the DB + * @return the {@link SchedulingEnum} + * @throws InvalidInputException if unable to construct the period. + */ + public static SchedulingPeriod fromDbSchedulingCriteria(final List criteria) throws InvalidInputException { + // First find periodicity type (date / daily / weekly / monthly / weekend / day_in_month) + SchedulingEnum periodicity = getPeriodicity(criteria); + // Now findAll the value defining the periodicity + String value = getPeriodicityValue(criteria, periodicity); + return fromPeriodicityArguments(periodicity, value); + } + + private static String getPeriodicityValue(final List criteria, final SchedulingEnum periodicity) + throws InvalidInputException { + if (periodicity == SchedulingEnum.DAILY) { + return ""; // No value for daily periodicity + } + for (DbSchedulingCriteriaVal criterion : criteria) { + final String criteriaName = criterion.getDbCriteria().getCriteriaName(); + if (periodicity.getCriteriaName().equals(criteriaName)) { + return criterion.getCriteriaValue(); + } + } + throw new InvalidInputException("Unable to parse criteria for periodicity value : " + criteria.toString()); + } + + private static SchedulingEnum getBasicPeriodicity(final List criteria) throws InvalidInputException { + for (DbSchedulingCriteriaVal criterion : criteria) { + final String criteriaName = criterion.getDbCriteria().getCriteriaName(); + if (SchedulingEnum.PERIOD.toString().equals(criteriaName)) { + final String periodValue = criterion.getCriteriaValue().toLowerCase(); + return SchedulingEnum.getEnum(periodValue); + } + } + throw new InvalidInputException("Unable to parse criteria for periodicity type : " + criteria.toString()); + } + + private static SchedulingEnum getPeriodicity(final List criteria) throws InvalidInputException { + SchedulingEnum periodicity = getBasicPeriodicity(criteria); + if (periodicity == SchedulingEnum.WEEKEND) { + // Special periodicity type, might be constructed in three tiers: + // - period = weekend + // - weekend = day_in_month + // - day_in_month_value = [1..31] + // Instead of usual two-tiers: + // - period = weekend + // - weekend = first_we + String value = getPeriodicityValue(criteria, SchedulingEnum.WEEKEND); + if ("day_in_month_value".equals(value)) { + return SchedulingEnum.DAY_IN_MONTH_VALUE; + } + } + // Normal mode, periodicity was correctly found in 1st iteration + return periodicity; + } + + private static SchedulingPeriod fromPeriodicityArguments(final SchedulingEnum periodicityEnum, final String periodValue) + throws InvalidInputException { + SchedulingPeriod thePeriod; + switch (periodicityEnum) { + case DAILY: + thePeriod = PeriodFactory.daily(); + break; + case DATE: + try { + thePeriod = PeriodFactory.day(periodValue); + } catch (ParseException e) { + throw new InvalidUserInputException("Unable to parse date: " + periodValue, e); + } + break; + case DAY_IN_MONTH_VALUE: + try { + final int dayInMonth = Integer.parseInt(periodValue); + thePeriod = PeriodFactory.dayInMonth(dayInMonth); + } catch (NumberFormatException e) { + throw new InvalidUserInputException("Unable to parse day of month number (int): " + periodValue, e); + } + break; + case WEEKEND: + thePeriod = PeriodFactory.weekend(periodValue); + break; + case WEEKLY: + try { + final int dayInWeek = Integer.parseInt(periodValue); + thePeriod = PeriodFactory.weekly(dayInWeek); + } catch (NumberFormatException e) { + throw new InvalidUserInputException("Unable to parse day of week number (int): " + periodValue, e); + } + break; + default: + final String periodicityStr = periodicityEnum.toString(); + throw new InvalidUserInputException("Unable to understand periodicity value:" + periodicityStr); + } + return thePeriod; + } + + /** + * Returns a {@link SchedulingPeriod} (actually a {@link SpecificDay}) representing today. + * + * @return The schedulingPeriod. + */ + public static SpecificDay today() { + return new SpecificDay(Calendar.getInstance().getTime()); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/periodicity/SchedulingPeriod.java b/kurt-utility/src/main/java/com/capgemini/reports/periodicity/SchedulingPeriod.java new file mode 100644 index 0000000..596ad1c --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/periodicity/SchedulingPeriod.java @@ -0,0 +1,90 @@ +package com.capgemini.reports.periodicity; + +import com.capgemini.reports.database.javabean.enumeration.SchedulingEnum; +import com.capgemini.reports.database.manager.MngSchedulingCriteriaVal.SchedulingCriteriaValue; + +import java.util.List; + +/** + * Object representing various scheduling periodicities and their parameters.
+ * These periodicities are also ablo to presnt themselves as a {@link List} of database entries ({@link SchedulingCriteriaValue}s) using {@link SchedulingPeriod#asCriteriaValues()}. + */ +public interface SchedulingPeriod { + + /** + * Returns the instance of {@link SchedulingEnum} that represents the overall periodicity of this SchedulingPeriod. + * + * @return the instance of {@link SchedulingEnum} + */ + SchedulingEnum getPeriodicity(); + + /** + * Returns a {@link List} of database entries ({@link SchedulingCriteriaValue}s) that represent this period object.
+ * Example: period=weekly, weekly=3 + * + * @return a List of two SchedulingCriteriaValue + */ + List asCriteriaValues(); + + /** + * This object accepts a {@link PeriodVisitor}.
+ * It will invoke one of its visit method and pass itself as a parameter.
+ * This way, the visitor knows exactly which sub-class of {@link SchedulingPeriod} is used. + * + * @param any desired return type + * @param visitor the visitor + * @return any kind of interesting output + */ + T accept(final PeriodVisitor visitor); + + /** + * Visitor of {@link SchedulingPeriod}.
+ * By implementing this interface, you will be able to invoke {@link SchedulingPeriod#accept(PeriodVisitor)} on any SchedulingPeriod instance
+ * The SchedulingPeriod will in turn invoke the visitor's visit methods with itself as a strongly-typed argument. + * + * @param any kind of desired output + */ + interface PeriodVisitor { + + /** + * Behaviour to be had when visiting a {@link DayInMonth}. + * + * @param dayInMonth the day of the month + * @return any kind of desired output + */ + T visit(final DayInMonth dayInMonth); + + /** + * Behaviour to be had when visiting a {@link SpecificDay}. + * + * @param specificDay the day + * @return any kind of desired output + */ + T visit(final SpecificDay specificDay); + + /** + * Behaviour to be had when visiting a {@link WeekendPeriod}. + * + * @param weekend the weekend + * @return any kind of desired output + */ + T visit(final WeekendPeriod weekend); + + /** + * Behaviour to be had when visiting a {@link WeeklyPeriod}. + * + * @param dayInWeek the day of the week + * @return any kind of desired output + */ + T visit(final WeeklyPeriod dayInWeek); + + /** + * Behaviour to be had when visiting a {@link DailyPeriod}. + * + * @param uselessParam this parameter is useless, because a DailPeriod happens every day, by definition. + * @return any kind of desired output + */ + T visit(final DailyPeriod uselessParam); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/periodicity/SpecificDay.java b/kurt-utility/src/main/java/com/capgemini/reports/periodicity/SpecificDay.java new file mode 100644 index 0000000..4417f56 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/periodicity/SpecificDay.java @@ -0,0 +1,82 @@ +package com.capgemini.reports.periodicity; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.reports.database.javabean.enumeration.SchedulingEnum; +import com.capgemini.reports.database.manager.MngSchedulingCriteriaVal.SchedulingCriteriaValue; +import lombok.Getter; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * Represents a specific day for execution. Occurs only once. + */ +@Getter +public class SpecificDay implements SchedulingPeriod { + + private static final String LAUNCH_HOUR_STR = SettingsHelper.getDelayedLaunchHour(); + + private final Date day; + + /** + * Build a specific day. + * + * @param day the day using format: "dd-MM-yyyy" + * @throws ParseException if unable to parse the input date. + */ + public SpecificDay(final String day) throws ParseException { + this.day = getScheduledDate(day); + } + + /** + * Build a specific day. + * + * @param day the {@link Date} + * @throws ParseException + */ + protected SpecificDay(final Date day) { + this.day = day; + } + + @Override + public SchedulingEnum getPeriodicity() { + return SchedulingEnum.DATE; + } + + @Override + public T accept(final PeriodVisitor visitor) { + return visitor.visit(this); + } + + @Override + public List asCriteriaValues() { + List list = new ArrayList<>(2); + list.add(new SchedulingCriteriaValue(SchedulingEnum.PERIOD, SchedulingEnum.DATE.getCriteriaName())); + list.add(new SchedulingCriteriaValue(SchedulingEnum.DATE, String.valueOf(dateToString()))); + return list; + } + + /** + * Get the scheduled date. + * + * @param stringValue String - the date value to the TC format dd-MM-yyyy + * + * @throws ParseException if the parse of the {@link SimpleDateFormat} doesn't work. + * + * @return a {@link Date} pointing to the provided day, at the default hour & minute + */ + private Date getScheduledDate(final String stringValue) throws ParseException { + // Create a date with the appropriate value + SimpleDateFormat curFormater = new SimpleDateFormat(TeamcenterDateFormatter.DD_MM_YYYY_HH_MM); + return curFormater.parse(stringValue + " " + LAUNCH_HOUR_STR); + } + + private String dateToString() { + return new SimpleDateFormat(TeamcenterDateFormatter.DD_MM_YYYY).format(day); + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/periodicity/WeekendPeriod.java b/kurt-utility/src/main/java/com/capgemini/reports/periodicity/WeekendPeriod.java new file mode 100644 index 0000000..283308b --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/periodicity/WeekendPeriod.java @@ -0,0 +1,99 @@ +package com.capgemini.reports.periodicity; + +import com.capgemini.reports.database.javabean.enumeration.SchedulingEnum; +import com.capgemini.reports.database.manager.MngSchedulingCriteriaVal.SchedulingCriteriaValue; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Specific behaviors for the ALL_MONTH period. + */ +public enum WeekendPeriod implements SchedulingPeriod { + + /** + * The report will be executed the first Sunday of the month. + */ + FIRST_WEEK_END("first_we"), + /** + * The report will be executed the second Sunday of the month. + */ + SECOND_WEEK_END("second_we"), + /** + * The report will be executed the third Sunday of the month. + */ + THIRD_WEEK_END("third_we"), + /** + * The report will be executed the fourth Sunday of the month. + */ + FOURTH_WEEK_END("fourth_we"), + /** + * The report will be executed the fifth Sunday of the month. + */ + FIFTH_WEEK_END("fifth_we"), + /** + * The report will be executed the last day of the month. + */ + END_MONTH("end_of_month"); + + /** + * Enumeration cache for conversions. + **/ + private static final Map enumMap; + + static { + enumMap = new HashMap<>(WeekendPeriod.values().length); + for (WeekendPeriod currentEnum : WeekendPeriod.values()) { + enumMap.put(currentEnum.toString(), currentEnum); + } + } + + @Getter + private final String strMonthType; + + WeekendPeriod(final String strMonthType) { + this.strMonthType = strMonthType; + } + + /** + * Give the appropriate {@link WeekendPeriod} associate to the string value.
+ * Else return null. + * + * @param value String - the string value + * @return the appropriate {@link WeekendPeriod}. Return null if the string value doesn't exist. + */ + public static WeekendPeriod getEnum(final String value) { + return enumMap.get(value); + } + + @Override + public SchedulingEnum getPeriodicity() { + return SchedulingEnum.WEEKEND; + } + + @Override + public List asCriteriaValues() { + List list = new ArrayList<>(2); + list.add(new SchedulingCriteriaValue(SchedulingEnum.PERIOD, SchedulingEnum.WEEKEND.getCriteriaName())); + list.add(new SchedulingCriteriaValue(SchedulingEnum.WEEKEND, String.valueOf(this.getStrMonthType()))); + return list; + } + + /** + * Getter for object string value. + * + * @return String value with readable format + **/ + @Override + public String toString() { + return strMonthType; + } + + @Override + public T accept(final PeriodVisitor visitor) { + return visitor.visit(this); + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/periodicity/WeeklyPeriod.java b/kurt-utility/src/main/java/com/capgemini/reports/periodicity/WeeklyPeriod.java new file mode 100644 index 0000000..2ca9f4d --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/periodicity/WeeklyPeriod.java @@ -0,0 +1,35 @@ +package com.capgemini.reports.periodicity; + +import com.capgemini.reports.database.javabean.enumeration.SchedulingEnum; +import com.capgemini.reports.database.manager.MngSchedulingCriteriaVal.SchedulingCriteriaValue; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +/** Represents an event that occurs every week, on a specific week day. */ +@AllArgsConstructor +@Getter +public class WeeklyPeriod implements SchedulingPeriod { + + private final int dayInWeek; + + @Override + public SchedulingEnum getPeriodicity() { + return SchedulingEnum.WEEKLY; + } + + @Override + public T accept(final PeriodVisitor visitor) { + return visitor.visit(this); + } + + @Override + public List asCriteriaValues() { + List list = new ArrayList<>(2); + list.add(new SchedulingCriteriaValue(SchedulingEnum.PERIOD, SchedulingEnum.WEEKLY.getCriteriaName())); + list.add(new SchedulingCriteriaValue(SchedulingEnum.WEEKLY, String.valueOf(dayInWeek))); + return list; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/printing/PrintParameters.java b/kurt-utility/src/main/java/com/capgemini/reports/printing/PrintParameters.java new file mode 100644 index 0000000..0e5fd4b --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/printing/PrintParameters.java @@ -0,0 +1,444 @@ +package com.capgemini.reports.printing; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.exceptions.ReportPrintException; +import com.capgemini.reports.jasper.compilers.JasperCompiler; +import com.capgemini.reports.jasper.fillers.JasperFiller; +import com.capgemini.reports.jasper.fillers.MonoFiller; +import com.capgemini.reports.jasper.fillers.MultiFiller; +import com.capgemini.reports.jasper.printers.JasperCSVPrinter; +import com.capgemini.reports.jasper.printers.JasperPDFPrinter; +import com.capgemini.reports.jasper.printers.JasperPrinter; +import com.capgemini.reports.jasper.printers.JasperXLSXPrinter; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.reports.output.ZipReport; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperPrint; +import net.sf.jasperreports.engine.JasperReport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.InputStream; +import java.util.*; +import java.util.Map.Entry; + +/** + * Constructs a report printing parameters. Use the static factory methods to obtain an instance. + */ +public class PrintParameters { + private static final Logger LOGGER = LoggerFactory.getLogger(PrintParameters.class); + private static final String REPORT_TITLE_MARKER = "report_title"; + private static final String ERROR_MESSAGE = "Could not prepare sub-report template from InputStream"; + // Main report content + private final JasperReport template; + private final Map parameters = new HashMap<>(); + private final List> reportData = new ArrayList<>(); + + // Sub reports content + private final Map subReports = new HashMap<>(); + + // Printing data + private final PrintFormat printTypes; + private final String outputFolder; + private final String outputFileName; + + /** + * Creates some {@link PrintParameters} to print the MAIN Report template.
+ * Specifies the file type (.xlsx, .pdf, ...), the file name, the Folder, and the template. + * + * @param printTypes the file type + * @param fileName the file name + * @param folder the Folder + * @param template the template (an {@link InputStream} to the .jrxml file) + * @throws JRException if the compilation goes wrong + */ + protected PrintParameters(final PrintFormat printTypes, final String fileName, final String folder, final InputStream template) + throws JRException { + this.printTypes = printTypes; + this.outputFileName = fileName; + this.outputFolder = folder; + this.template = JasperCompiler.compile(template); + } + + /** + * Creates some {@link PrintParameters} to print the MAIN Report template.
+ * Specifies the file type (.xlsx, .pdf, ...), the file name, the Folder, and the template. + * + * @param printTypes the file type + * @param fileName the file name + * @param folder the Folder + * @param template the template (a {@link String} whith the whole content) + * @throws JRException if the compilation goes wrong + */ + protected PrintParameters(final PrintFormat printTypes, final String fileName, final String folder, final String template) throws JRException { + this.printTypes = printTypes; + this.outputFileName = fileName; + this.outputFolder = folder; + this.template = JasperCompiler.compile(template); + } + + /** + * Creates some {@link PrintParameters} for a subReport, using its template's {@link InputStream}. + * + * @param template the template + * @throws JRException if the compilation goes wrong + */ + protected PrintParameters(final InputStream template) throws JRException { + this.printTypes = null; + this.outputFileName = ""; + this.outputFolder = ""; + this.template = JasperCompiler.compile(template); + } + + + /** + * Creates some {@link PrintParameters} for a subReport, using its template's full content (as a {@link String}). + * + * @param template the template + * @throws JRException if the compilation goes wrong + */ + protected PrintParameters(final String template) throws JRException { + this.printTypes = null; + this.outputFileName = ""; + this.outputFolder = ""; + this.template = JasperCompiler.compile(template); + } + + public PrintParameters(PrintFormat printFormat, String fileName, String folder) { + this.printTypes = printFormat; + this.outputFileName = fileName; + this.outputFolder = folder; + this.template = null; + } + + /** + * Creates some {@link PrintParameters} to be used as a sub-report. + * + * @param template the template (an {@link InputStream} to the .jrxml file) + * @return the {@link PrintParameters} for the sub-report + * @throws ReportPrintException if a Jasper exception was thrown + */ + public static PrintParameters createSubReport(final InputStream template) throws ReportPrintException { + try { + return new PrintParameters(template); + } catch (JRException e) { + throw new ReportPrintException(ERROR_MESSAGE, e); + } + } + + /** + * Creates some {@link PrintParameters} for the main report.
+ * Specifies the file type (.xlsx, .pdf, ...), the file name, the Folder, and the template. + * + * @param printTypes the file type + * @param fileName the file name + * @param folder the Folder + * @param template the template (an {@link InputStream} to the .jrxml file) + * @return the {@link PrintParameters} for the main report + * @throws ReportPrintException if the template could not be understood by the printer. + */ + public static PrintParameters createMainReport(final PrintFormat printTypes, final String fileName, final String folder, + final InputStream template) throws ReportPrintException { + try { + return new PrintParameters(printTypes, fileName, folder, template); + } catch (JRException e) { + throw new ReportPrintException(ERROR_MESSAGE, e); + } + } + + /** + * Creates some {@link PrintParameters} for the main report.
+ * Specifies the file type (.xlsx, .pdf, ...), the file name, the Folder, and the template. + * + * @param printTypes the file type + * @param fileName the file name + * @param folder the Folder + * @param template the template (a {@link String} containing the actual jrxml content) + * @return the {@link PrintParameters} for the main report + * @throws ReportPrintException if a Jasper exception was thrown + */ + public static PrintParameters createMainReport(final PrintFormat printTypes, final String fileName, final String folder, final String template) + throws ReportPrintException { + try { + return new PrintParameters(printTypes, fileName, folder, template); + } catch (JRException e) { + throw new ReportPrintException(ERROR_MESSAGE, e); + } + } + + /** + * Creates some {@link PrintParameters} to be used as a sub-report.
+ * + * @param template the template (a {@link String} containing the actual jrxml content) + * @return the {@link PrintParameters} for the main report + * @throws ReportPrintException if a Jasper exception was thrown + */ + public static PrintParameters createSubReport(final String template) throws ReportPrintException { + try { + return new PrintParameters(template); + } catch (JRException e) { + throw new ReportPrintException("Could not prepare sub-report template from String", e); + } + } + + /** + * Returns true if the report has sub reports, false otherwise. + * + * @return a boolean + */ + boolean hasSubReports() { + return !subReports.isEmpty(); + } + + /** + * Adds some parameters to this report. + * + * @param key the String key + * @param additionalParameter the parameter content + */ + public void addReportParameter(final String key, final Object additionalParameter) { + parameters.put(key, additionalParameter); + } + + /** + * Adds some parameters to this report. + * + * @param key the enum key + * @param additionalParameter the parameter content + * @param generic object + */ + public > void addReportParameter(final K key, final Object additionalParameter) { + parameters.put(key.toString(), additionalParameter); + } + + /** + * Adds some parameters to this report. + * + * @param Generic object + * @param additionalParameters the parameters, as a {@link Map} whose keys are {@link Enum}s + */ + public > void addReportParameters(final Map additionalParameters) { + for (Entry entry : additionalParameters.entrySet()) { + parameters.put(entry.getKey().toString(), entry.getValue()); + } + } + + /** + * Sets the title of the report. + * + * @param title the title of this report + */ + public void setReportTitle(final String title) { + parameters.put(REPORT_TITLE_MARKER, title); + } + + /** + * Adds data to this report. + * + * @param data a {@link Collection} of several {@link Map}s of data. The Maps use {@link String}s as keys. + */ + public void addReportData(final Collection> data) { + reportData.addAll(data); + } + + /** + * Adds data to this report. + * + * @param Generic object + * @param data a {@link Collection} of several {@link EnumMap}s of data. The Maps use {@link Enum}s as keys + */ + public > void addReportDataFromEnum(final Collection> data) { + for (Map map : data) { + Map newMap = new HashMap<>(); + for (Entry entry : map.entrySet()) { + newMap.put(entry.getKey().toString(), entry.getValue()); + } + reportData.add(newMap); + } + } + + /** + * Adds a simple sub-report to this report. + * + * @param key a {@link String} key identifying the name of this sub-report + * @param aTemplate the sub-report's template, as an {@link InputStream} + * @param data the data forming this sub-report + * @param someParams some parameters for this sub-report + * @param An enum whose values will be used as keys to link to the report data, one map of those keys for each line of the report. + * @param An enum whose values will be used as keys to link to report parameters. Parameters are the same throughout the report. + * @throws ReportPrintException if a Jasper exception was thrown + */ + public , V extends Enum> void addSubReport(final String key, final InputStream aTemplate, + final Collection> data, final Map someParams) throws ReportPrintException { + try { + PrintParameters subReport = new PrintParameters(aTemplate); + subReport.addReportDataFromEnum(data); + subReport.addReportParameters(someParams); + subReports.put(key, subReport); + } catch (JRException e) { + throw new ReportPrintException(ERROR_MESSAGE, e); + } + } + + /** + * Adds a potentially more complex sub-report to this report.
+ * The sub-report may itself have some sub-reports + * + * @param key a {@link String} key identifying the name of this sub-report + * @param subReport a {@link PrintParameters} whith all the sub-report data configured + */ + public void addSubReport(final String key, final PrintParameters subReport) { + subReports.put(key, subReport); + } + + /** + * Returns the expected extension of the printed file: ".xlsx", ".csv" etc. + * + * @return the extension (including the dot) + */ + public String getOuputFileExtension() { + String extension; + switch (this.printTypes) { + case CSV: + extension = ".csv"; + break; + case PDF: + extension = ".pdf"; + break; + case XLSX: + extension = ".xlsx"; + break; + case ZIP: + extension = ".zip"; + break; + default: + extension = ".txt"; + break; + } + return extension; + } + + /** + * Creates a {@link JasperFiller} from this report, configured with the template, the data, and the parameters. + * + * @return the {@link JasperFiller} + * @throws JRException if report creation failed + */ + public JasperFiller createReportFiller() throws JRException { + if (this.hasSubReports()) { + return createReportMultiFiller(); + } else { + return createReportMonoFiller(); + } + } + + /** + * Creates a simple mono-report. Must be called only if this report does not have sub-reports. + * + * @return a {@link MultiFiller} set up + */ + private MonoFiller createReportMonoFiller() { + return new MonoFiller(template, reportData, parameters); + } + + /** + * Recursive for sub-(sub)-reports. + * + * @return a {@link MultiFiller} set up + */ + private MultiFiller createReportMultiFiller() { + MultiFiller mainFiller = new MultiFiller(template, reportData, parameters); + for (Entry entry : subReports.entrySet()) { + PrintParameters subReport = entry.getValue(); + JasperReport compiledTemplate = subReport.getTemplate(); + if (subReport.hasSubReports()) { + MultiFiller subReportFiller = subReport.createReportMultiFiller(); + mainFiller.addSubReport(entry.getKey(), subReportFiller); + } else { + mainFiller.addSubReport(entry.getKey(), compiledTemplate, subReport.getReportData(), subReport.getParameters()); + } + } + return mainFiller; + } + + /** + * Effectue l'impression proprement dite ave le plugin JASPER. + */ + File jasperPrint() throws ReportPrintException { + // Fill in the data + JasperPrint print; + try { + print = createReportFiller().generate(); + } catch (JRException e) { + throw new ReportPrintException("An exception occurred while filling the reports", e); + } + + // Print + try { + return jasperPrinter().print(print); + } catch (JRException e) { + throw new ReportPrintException("An exception occurred while printing the reports", e); + + } + } + + private JasperPrinter jasperPrinter() { + // Create the printer + switch (printTypes) { + case PDF: + return new JasperPDFPrinter(outputFolder, outputFileName); + case XLSX: + return new JasperXLSXPrinter(outputFolder, outputFileName); + case CSV: + default: + return new JasperCSVPrinter(outputFolder, outputFileName); + } + } + + File createZip() throws KurtException { + List filesToZip = new ArrayList<>(); + for (Entry entry : subReports.entrySet()) { + PrintParameters printParameters = entry.getValue(); + if (printParameters.printTypes == PrintFormat.ZIP) { + filesToZip.add(printParameters.createZip()); + } + else { + filesToZip.add(printParameters.jasperPrint()); + } + } + return new ZipReport(outputFolder + outputFileName + ".zip", filesToZip).print().getFile(); + } + + /** + * Prints to console. + */ + File consolePrint() { + // Print + LOGGER.info("Printing to console"); + LOGGER.info("outputFolder ={}", outputFolder); + LOGGER.info("outputFileName ={}", outputFileName); + LOGGER.info("Parameters ={}", parameters); + LOGGER.info("dataMaps size ={}", reportData.size()); + for (Map line : reportData) { + LOGGER.info(" + {}", line.toString()); + } + return null; // No file to be had! this is console + } + + public JasperReport getTemplate() { + return template; + } + + public List> getReportData() { + return reportData; + } + + public Map getParameters() { + return parameters; + } + + public Map getSubReports() { + return subReports; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/printing/PrintReportHelper.java b/kurt-utility/src/main/java/com/capgemini/reports/printing/PrintReportHelper.java new file mode 100644 index 0000000..c139065 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/printing/PrintReportHelper.java @@ -0,0 +1,65 @@ +package com.capgemini.reports.printing; + +import com.capgemini.reports.exceptions.ReportPrintException; +import com.capgemini.reports.execution.AbstractExecutionReport; + +import java.io.InputStream; + +/** + * This class helper will allow to use the method which will set up the parameters for the printing. + * + */ +public final class PrintReportHelper { + + private PrintReportHelper() { + + } + + /** + * Sets up basic printing parameters. + *
    + *
  • Main report Template
  • + *
  • Output folder
  • + *
  • File name
  • + *
  • Report title
  • + *
+ * + * @param template the report template. NOTE: the {@link InputStream} is consumed in this method, but it is the resposibility of the caller to perform the {@link InputStream#close() close()} operation. + * @param outputFolder folder where the file will be saved + * @param outputFileName name of the file as it will be saved on disc + * @param aAbstractExecutionReport will provide all informations for the report which is executing + * @return the PrintParameters configured + * @throws ReportPrintException if the template could not be understood by the printer. + */ + public static PrintParameters setupPrintParameters(final InputStream template, final String outputFolder, final String outputFileName, + final AbstractExecutionReport aAbstractExecutionReport) throws ReportPrintException { + PrintParameters printParameters = + PrintParameters.createMainReport(aAbstractExecutionReport.getPrintingFormat(), outputFileName, outputFolder, template); + printParameters.setReportTitle(aAbstractExecutionReport.getReportIdentifier().getReportTitle()); + return printParameters; + } + + /** + * Sets up basic printing parameters. + *
    + *
  • Main report Template
  • + *
  • Output folder
  • + *
  • File name
  • + *
  • Report title
  • + *
+ * + * @param template the template (a {@link String} containing the actual .jrxml content) + * @param outputFolder the folder where the file will be saved + * @param outputFileName the file name + * @param aAbstractExecutionReport will provide all informations for the report which is executing + * @return the PrintParameters configured + * @throws ReportPrintException if unable to create the report template + */ + public static PrintParameters setupPrintParameters(final String template, final String outputFolder, final String outputFileName, + final AbstractExecutionReport aAbstractExecutionReport) throws ReportPrintException { + PrintParameters printParameters = + PrintParameters.createMainReport(aAbstractExecutionReport.getPrintingFormat(), outputFileName, outputFolder, template); + printParameters.setReportTitle(aAbstractExecutionReport.getReportIdentifier().getReportTitle()); + return printParameters; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/printing/Printer.java b/kurt-utility/src/main/java/com/capgemini/reports/printing/Printer.java new file mode 100644 index 0000000..681560d --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/printing/Printer.java @@ -0,0 +1,60 @@ +package com.capgemini.reports.printing; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.exceptions.ReportPrintException; + +import java.io.File; + +/** + * This class can print a report using a certain API (JASPER, BURT...) on a {@link PrintParameters}. + */ +public class Printer { + + private final AvailablePrinter availablePrinter; + + /** + * Construit un Printer en specifiant le plugin a utiliser (JASPER, BURT...). + * + * @param printer le plugin a utiliser pour imprimer + */ + public Printer(final AvailablePrinter printer) { + this.availablePrinter = printer; + } + + /** + * Effectue l'impression proprement dite. + * + * @param params les parametres d'impression + * @return a {@link File} referencing the produced document + * @throws ReportPrintException if a Jasper exception was thrown + */ + public File print(final PrintParameters params) throws KurtException { + switch (availablePrinter) { + case JASPER: + return params.jasperPrint(); + case ZIP: + return params.createZip(); + default: + return params.consolePrint(); + } + } + + /** + * All sorts of available output formats. + */ + public enum PrintFormat { + PDF, + XLSX, + CSV, + ZIP + } + + /** + * All sorts of available output formats. + */ + public enum AvailablePrinter { + JASPER, + ZIP, + TEST + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/queuing/ReportPriority.java b/kurt-utility/src/main/java/com/capgemini/reports/queuing/ReportPriority.java new file mode 100644 index 0000000..52d4fd5 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/queuing/ReportPriority.java @@ -0,0 +1,76 @@ +package com.capgemini.reports.queuing; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +/** Reflects the priority level of each report. */ +@Getter +@Slf4j +public enum ReportPriority { + HIGH_PRIORITY(1), + MED_PRIORITY(2), + LOW_PRIORITY(3); + + private static final int HIGH_PRIORITY_VALUE = 1; + private static final int MED_PRIORITY_VALUE = 2; + private static final int LOW_PRIORITY_VALUE = 3; + + private final int priorityValue; + + ReportPriority(final int priorityValue) { + this.priorityValue = priorityValue; + } + + @Override + public String toString() { + String val; + switch (this) { + case HIGH_PRIORITY: + val = "High Priority Queue"; + break; + case MED_PRIORITY: + val = "Medium Priority Queue"; + break; + case LOW_PRIORITY: + val = "Low Priority Queue"; + break; + default: + val = "No Queue"; + break; + } + return val; + } + + /** + * Give the appropriate {@link ReportPriority} associate to a code:
+ *
    + *
  • Code 1 : HIGH_PRIORITY
  • + *
  • Code 2 : MED_PRIORITY
  • + *
  • Code 3 : LOW_PRIORITY
  • + *
+ * Else return null. + * + * @param value int - the code value + * @return the appropriate {@link ReportPriority} + */ + public static ReportPriority getReportPriority(final int value) { + ReportPriority priority; + switch (value) { + case HIGH_PRIORITY_VALUE: + priority = ReportPriority.HIGH_PRIORITY; + break; + case MED_PRIORITY_VALUE: + priority = ReportPriority.MED_PRIORITY; + break; + case LOW_PRIORITY_VALUE: + priority = ReportPriority.LOW_PRIORITY; + break; + default: + log.error("No priority found for reports. The int {} is not valid (only 1, 2, 3 allowed). Defaulting to LOW priority", + String.valueOf(value)); + priority = ReportPriority.LOW_PRIORITY; + break; + } + return priority; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/reports/IReportVisitor.java b/kurt-utility/src/main/java/com/capgemini/reports/reports/IReportVisitor.java new file mode 100644 index 0000000..6b8c500 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/reports/IReportVisitor.java @@ -0,0 +1,24 @@ +package com.capgemini.reports.reports; + +import java.util.List; +import java.util.Map; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; + +/** + * Interface Generic Report Generator using the Visitor pattern. + * + * @param key + * @param value + */ +public interface IReportVisitor { + + /** + * visits a report and presents a result that the printer can understand. + * + * @param holder the top {@link BOMLineHolder} + * @return the report contents + */ + List> visitReport(final BOMLineHolder holder); + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/reports/output/ReportOutput.java b/kurt-utility/src/main/java/com/capgemini/reports/reports/output/ReportOutput.java new file mode 100644 index 0000000..31fadb1 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/reports/output/ReportOutput.java @@ -0,0 +1,8 @@ +package com.capgemini.reports.reports.output; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import net.lingala.zip4j.core.ZipFile; + +public interface ReportOutput { + ZipFile print() throws KurtException; +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/reports/output/ZipReport.java b/kurt-utility/src/main/java/com/capgemini/reports/reports/output/ZipReport.java new file mode 100644 index 0000000..705a009 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/reports/output/ZipReport.java @@ -0,0 +1,53 @@ +package com.capgemini.reports.reports.output; + + +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import net.lingala.zip4j.core.ZipFile; +import net.lingala.zip4j.exception.ZipException; +import net.lingala.zip4j.model.ZipParameters; +import net.lingala.zip4j.util.Zip4jConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.List; + +public class ZipReport implements ReportOutput { + private static final Logger LOGGER = LoggerFactory.getLogger(ZipReport.class); + + private final String zipFilePath; + private final List filesToCompress; + + public ZipReport(final String zipFilePath, final List filesToCompress) { + this.zipFilePath = zipFilePath; + this.filesToCompress = filesToCompress; + } + + @Override + public ZipFile print() throws KurtException { + try { + ZipFile zipFile = new ZipFile(zipFilePath); + ZipParameters parameters = zipParameters(); + addFilesToZip(zipFile, parameters); + return zipFile; + } catch (ZipException e) { + throw new KurtException(e.getMessage(), e); + } + } + + private ZipParameters zipParameters() { + ZipParameters parameters = new ZipParameters(); + parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); + parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); + return parameters; + } + + private void addFilesToZip(ZipFile zipFile, ZipParameters parameters) throws ZipException { + for (File file : filesToCompress) { + zipFile.addFile(file, parameters); + if (file.delete()) { + LOGGER.debug("Archive file {} deleted.", file.getName()); + } + } + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/templates/Alignment.java b/kurt-utility/src/main/java/com/capgemini/reports/templates/Alignment.java new file mode 100644 index 0000000..79859b6 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/templates/Alignment.java @@ -0,0 +1,22 @@ +package com.capgemini.reports.templates; + +/** + * Horizontal Text alignment for jrxml template. + */ +public enum Alignment { + LEFT("Left"), + CENTER("Center"), + RIGHT("Right"), + JUSTIFIED("Justified"); + + private final String value; + + Alignment(final String str) { + value = str; + } + + @Override + public String toString() { + return value; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/templates/Cell.java b/kurt-utility/src/main/java/com/capgemini/reports/templates/Cell.java new file mode 100644 index 0000000..eeefefe --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/templates/Cell.java @@ -0,0 +1,237 @@ +package com.capgemini.reports.templates; + +import com.capgemini.framework.common.StringHelper; +import lombok.Getter; + +import java.util.Map; + +/** + * Represents a Cell in a jrxml Grid Template.
+ * A Cell may be a static textfield, a dynamic Parameter textfield, or a dynamic Field textfield. + */ +@Getter +public final class Cell { + // Parameters and field declarations + private static final String REPORT_FIELD_BEGIN = "\n "; + + // Text elements to create a Cell + private static final String BEGIN_TEXTFIELD = "\n "; + private static final String BEGIN_TEXTFIELD_STRETCH_WITH_OVERFLOW = "\n "; + private static final String BEGIN_STATICTEXT = "\n "; + private static final String BEGIN_STATICTEXT_STRETCH_WITH_OVERFLOW = "\n "; + private static final String BEGIN_ELEMENT = "\n "; + private static final String HTML_MARKUP_BEGIN = "\n \n"; + private static final String END_TEXTELEMENT = "\n "; + private static final String BEGIN_FIELD = "\n "; + private static final String BEGIN_TEXT = "\n "; + private static final String END_TEXTFIELD = "\n "; + private static final String END_STATICTEXT = "\n "; + + // Make a nice box af any textField + private static final String BOX_L1 = "\n "; + private static final String BOX_L2 = "\n "; + private static final String BOX_L3 = "\n "; + private static final String BOX_L4 = "\n "; + private static final String BOX_L5 = "\n "; + private static final String BOX_L6 = "\n "; + + + // Final Cell properties + private final boolean dynamic; + private final boolean isHeader; + private final boolean isStretchWithOverflow; + private final String content; + private final String xPosition; + private final String yPosition; + private final String width; + + private final CellFormat format; + private String nameStyle; + + // The Cell height may vary, do not make this final + private int height; + + private static final String END_STYLE = "\""; + + /** + * Creates a static textfield, with fixed text content (Cannot stretch with overflow). + * + *
+     * < textField>}
+     *     < reportElement x="0" y="0" width="100" height="20"/>
+     *     < textFieldExpression>< ![CDATA[Some text content]]>< /textFieldExpression>}
+     * < /textField>
+     * 
+ * + * @param content the text content as a {@link String} + * @param height the Cell height + * @param width the Cell width + * @param xPosition the Cell horizontal position + * @param yPosition the Cell vertical position + * @param format this cell's format + * @return a properly built {@link Cell} + */ + public static Cell makeStaticCell(final String content, final int height, final int width, final int xPosition, final int yPosition, + final CellFormat format) { + return new Cell(content, false, true, false, height, width, xPosition, yPosition, format); + } + + /** + * Creates a dynamic Field textfield, whose content will be replaced using the value with a matching key in the field {@link Map}.
+ * Exemple: + * + *
+     * < textField>
+     *     < reportElement x="0" y="0" width="100" height="20"/>
+     *     < textFieldExpression>< ![CDATA[$F{FIELD_KEY_HERE}]]>< /textFieldExpression>
+     * < /textField>
+     * 
+ * + * @param fieldKey the field key as a {@link String} + * @param height the Cell height + * @param width the Cell width + * @param stretchWithOverflow if true, the cell will expand downwards to shall all the text inside it + * @param xPosition the Cell horizontal position + * @param yPosition the Cell vertical position + * @param format this cell's format + * @return a properly built {@link Cell} + */ + public static Cell makeFieldCell(final String fieldKey, final int height, final int width, final boolean stretchWithOverflow, + final int xPosition, final int yPosition, final CellFormat format) { + return new Cell(fieldKey, true, false, stretchWithOverflow, height, width, xPosition, yPosition, format); + } + + + /** + * Creates a dynamic Parameter textfield, whose content will be replaced using the value with a matching key in the parameters {@link Map}.
+ * Exemple: + * + *
+     * < textField>
+     *     < reportElement x="0" y="0" width="100" height="20"/>
+     *     < textFieldExpression>< ![CDATA[$P{PARAMETER_KEY_HERE}]]>< /textFieldExpression>
+     * < /textField>
+     * 
+ * + * @param parameterKey the parameter key as a {@link String} + * @param height the Cell height + * @param width the Cell width + * @param stretchWithOverflow if true, the cell will expand downwards to shall all the text inside it + * @param xPosition the Cell horizontal position + * @param yPosition the Cell vertical position + * @param format this cell's format + * @return a properly built {@link Cell} + */ + public static Cell makeParameterCell(final String parameterKey, final int height, final int width, final boolean stretchWithOverflow, + final int xPosition, final int yPosition, final CellFormat format) { + return new Cell(parameterKey, true, true, stretchWithOverflow, height, width, xPosition, yPosition, format); + } + + private Cell(final String content, final boolean dynamic, final boolean isHeader, final boolean stretchWithOverflow, final int height, + final int width, final int xPosition, final int yPosition, final CellFormat format) { + this.content = content; + this.dynamic = dynamic; + this.isHeader = isHeader; + this.isStretchWithOverflow = dynamic && stretchWithOverflow; // can only use stretch With Overflow in dynamic cell + this.height = height; + this.width = String.valueOf(width); + this.xPosition = String.valueOf(xPosition); + this.yPosition = String.valueOf(yPosition); + this.format = format == null ? new CellFormat() : format; + } + + /** + * Adds some extra height to this Cell, increasing its height towards the bottom. + * + * @param extraHeight the extra height, in pixels + */ + public void addHeight(final int extraHeight) { + this.height += extraHeight; + } + + /** + * Generates a cell declaration for a jrxml template. + * + * @return a String containing the full cell template + */ + public String makeCell() { + String heightStr = String.valueOf(height); + String alignmentStr = format.getAlignment(); + String color = format.getColor(); + String bold = format.getIsBold(); + String aLignementVertical = format.getVerticalAligement(); + if (dynamic) { + if (nameStyle != null) { + return StringHelper.concatToString(isStretchWithOverflow ? BEGIN_TEXTFIELD_STRETCH_WITH_OVERFLOW : BEGIN_TEXTFIELD, BEGIN_ELEMENT, + isStretchWithOverflow ? STRETCH_TYPE : "", BEGIN_STYLE, nameStyle, END_STYLE, BEGIN_XPOS, xPosition, X_TO_Y, yPosition, + Y_TO_WIDTH, width, HEIGHT, heightStr, END_ELEMENT, BOX_L1, BOX_L2, BOX_L3, BOX_L4, BOX_L5, BOX_L6, HTML_MARKUP_BEGIN, + alignmentStr, HTML_MARKUP_END, END_TEXTELEMENT, BEGIN_FIELD, content, END_EXPRESSION, END_TEXTFIELD); + + } + else { + return StringHelper.concatToString(isStretchWithOverflow ? BEGIN_TEXTFIELD_STRETCH_WITH_OVERFLOW : BEGIN_TEXTFIELD, BEGIN_ELEMENT, + isStretchWithOverflow ? STRETCH_TYPE : "", BEGIN_XPOS, xPosition, X_TO_Y, yPosition, Y_TO_WIDTH, width, HEIGHT, heightStr, + END_ELEMENT, BOX_L1, BOX_L2, BOX_L3, BOX_L4, BOX_L5, BOX_L6, HTML_MARKUP_BEGIN, alignmentStr, HTML_MARKUP_END, + END_TEXTELEMENT, isHeader ? BEGIN_PARAMETER : BEGIN_FIELD, content, END_EXPRESSION, END_TEXTFIELD); + } + } + else { + return StringHelper.concatToString(isStretchWithOverflow ? BEGIN_STATICTEXT_STRETCH_WITH_OVERFLOW : BEGIN_STATICTEXT, BEGIN_ELEMENT, + isStretchWithOverflow ? STRETCH_TYPE : "", BEGIN_XPOS, xPosition, X_TO_Y, yPosition, Y_TO_WIDTH, width, HEIGHT, heightStr, color, + END_ELEMENT, BOX_L1, BOX_L2, BOX_L3, BOX_L4, BOX_L5, BOX_L6, HTML_MARKUP_BEGIN, alignmentStr, aLignementVertical, + HTML_MARKUP_END, bold, END_TEXTELEMENT, BEGIN_TEXT, content, END_TEXT, END_STATICTEXT); + } + + } + + /** + * Returns a declaration of this cell's Field key, if it is a dynamic field. + * + * @return the {@link String} key + */ + public String getFieldsDeclaration() { + if (!this.isDynamic() || this.isHeader) { + return ""; + } + else { + return REPORT_FIELD_BEGIN + content + REPORT_FIELD_OR_PARAM_END; + } + } + + /** + * Returns a declaration of this cell's Parameter key, if it is a dynamic parameter. + * + * @return the {@link String} key + */ + public String getParametersDeclaration() { + if (!this.isDynamic() || !this.isHeader) { + return ""; + } + else { + return REPORT_PARAMETER_BEGIN + content + REPORT_FIELD_OR_PARAM_END; + } + } + + /** + * Gives the Cell a style by the provided name. + * + * @param aNameStyle the name of the style. Use null to remove style. + */ + public void setNameStyle(final String aNameStyle) { + nameStyle = aNameStyle; + } +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/templates/CellFormat.java b/kurt-utility/src/main/java/com/capgemini/reports/templates/CellFormat.java new file mode 100644 index 0000000..e455577 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/templates/CellFormat.java @@ -0,0 +1,93 @@ +package com.capgemini.reports.templates; + +import lombok.Getter; + +/** Represents a Cell's format: stretch with overflow, color, alignment. */ +@Getter +public class CellFormat { + + private static final String EMPTY_STRING = ""; + private static final String BEGIN_COLOR = "\" mode=\"Opaque\" backcolor=\""; + private static final String FORECOLOR = " forecolor =\""; + private static final String END_COLOR = ""; + private static final String ALIGNMENT_BEGIN = " textAlignment=\""; + private static final String ALIGNMENT_END = "\""; + private static final String BEGIN_BOLD = "\n "; + private static final String VERTICAL_ALIGNEMENT = " verticalAlignment=\""; + private static final String END_ALIGNEMENT = ">"; + + protected String alignment; + protected String color; + protected String verticalAligement; + + private String isBold; + protected String colorForecolor; + + /** Basic constructor. Color is black, Alignment is default (left). */ + public CellFormat() { + this.alignment = EMPTY_STRING; + this.color = EMPTY_STRING; + this.isBold = EMPTY_STRING; + this.verticalAligement = EMPTY_STRING; + } + + /** + * Specify an {@link Alignment}. + * + * @param anAlignment + * @return same object, for chaining + */ + public CellFormat setAlignment(final Alignment anAlignment) { + this.alignment = makeAlignmentDeclaration(anAlignment); + return this; + } + + /** + * If null, the cell is transparent. Otherwise, this is a color code like '#E3E3E3' -> grey. + * + * @param colorID + * @return this same object, for chaining + */ + public CellFormat setColor(final String colorID) { + this.color = makeColorDeclaration(colorID); + return this; + } + + /** + * Method which allow to put the value of a cell in bold. + * + * @param isBold + * @return the object CellFormat + */ + public CellFormat setBold(final boolean isBold) { + this.isBold = makeBoldDeclaration(isBold); + return this; + } + + /** + * Make an alignment for the cell's value. + * + * @param nameVerticalAlignement + */ + public void setAlignment(final String nameVerticalAlignement) { + this.verticalAligement = makeVerticalAlignmentDeclaration(nameVerticalAlignement); + } + + private String makeBoldDeclaration(boolean isBold2) { + return isBold == null ? EMPTY_STRING : BEGIN_BOLD + isBold2 + END; + } + + private String makeColorDeclaration(final String aColor) { + return aColor == null ? EMPTY_STRING : BEGIN_COLOR + aColor + END_COLOR; + } + + private String makeAlignmentDeclaration(final Alignment anAlignment) { + return anAlignment == null ? EMPTY_STRING : ALIGNMENT_BEGIN + anAlignment.toString() + ALIGNMENT_END; + } + + private String makeVerticalAlignmentDeclaration(final String anAlignment) { + return anAlignment == null ? EMPTY_STRING : VERTICAL_ALIGNEMENT + anAlignment; + } + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/templates/Column.java b/kurt-utility/src/main/java/com/capgemini/reports/templates/Column.java new file mode 100644 index 0000000..847f102 --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/templates/Column.java @@ -0,0 +1,122 @@ +package com.capgemini.reports.templates; + +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a column for a .jrxml dynamic table template.
+ * A {@link Column} specifies a series of content Dynamic field {@link Cell Cells}, and may (optionally) specify some Header {@link Cell Cells}. These header cells may contain static text, or a reference to a report parameter key. + */ +@Getter +public class Column { + + private final List headers; + private final Cell field; + private final int width; + private final int xPosition; + /** The total height of all the headers. grows whenever a new header {@link Cell} is added. */ + private int totalHeaderHeight; + + + + /** + * Creates a {@link Column} object. Field cells are always transparent. + * + * @param fieldKey The field key to put into the table body + * @param width The Column width, in pixels. All {@link Cell Cells} inside this column will have the same width + * @param stretchWithOverflow if true, the cell will expand downwards to shall all the text inside it + * @param xPosition the Column's horizontal position, in pixels + * @param contentHeight the height of any field cell in the table's body + * @param fieldFormat the format of this field + */ + public Column(final String fieldKey, final int width, final int xPosition, final boolean stretchWithOverflow, final int contentHeight, + final CellFormat fieldFormat) { + this.headers = new ArrayList<>(); + this.field = Cell.makeFieldCell(fieldKey, contentHeight, width, stretchWithOverflow, xPosition, 0, fieldFormat); + this.width = width; + this.xPosition = xPosition; + this.totalHeaderHeight = 0; + } + + /** + * Adds a Header {@link Cell} to this column. This Cell is added as the last header cell, right before the table body. + * + * @param dynamic if true, then this header clel will contain a reference to a report parameter using the content argument as a key + * @param content the Header content. If this header is dynamic, it is the name of the paremeter key. If it is not dynamic, this content will be the raw static text to display in the cell. + * @param height this header cell's height + * @param stretchWithOverflow if true, the cell will expand downwards to shall all the text inside it. Ignored if the cell is Static + * @param format This header line's format + */ + public void addHeader(final String content, final boolean dynamic, final int height, final boolean stretchWithOverflow, final CellFormat format) { + if (dynamic) { + headers.add(Cell.makeParameterCell(content, height, width, stretchWithOverflow, xPosition, totalHeaderHeight, format)); + } + else { + headers.add(Cell.makeStaticCell(content, height, width, xPosition, totalHeaderHeight, format)); + } + totalHeaderHeight += height; + } + + /** + * Lengthens the previous header Cell (if any). To be used to fuse cells istead of creating a new one. + * + * @param heightPx the height to add to the previous header cell, in pixels + */ + public void addToPreviousHeaderCellHeight(final int heightPx) { + if (!headers.isEmpty()) { + headers.get(headers.size() - 1).addHeight(heightPx); + totalHeaderHeight += heightPx; + } + } + + /** + * Generates the .jrxml code for this column's headers. + * + * @return a String containing the text to put in the template + */ + public String makeHeaders() { + StringBuilder output = new StringBuilder(); + for (Cell header : headers) { + output.append(header.makeCell()); + } + return output.toString(); + } + + /** + * Generates the .jrxml code for this column's body field. + * + * @return a String containing the text to put in the template + */ + public String makeContent() { + return field.makeCell(); + } + + /** + * Returns a declaration of this Column's Field key, if it is a dynamic field. + * + * @return the {@link String} key + */ + public String getFieldsDeclaration() { + return field.getFieldsDeclaration(); + } + + /** + * Returns all the declarations of this Column's Parameter keys, if any. + * + * @return the {@link String} declarations, or an empty string if none are required + */ + public String getParametersDeclaration() { + StringBuilder stringBuilder = new StringBuilder(); + for (Cell header : headers) { + if (header.isDynamic()) { + stringBuilder.append(header.getParametersDeclaration()); + } + } + return stringBuilder.toString(); + } + + + +} diff --git a/kurt-utility/src/main/java/com/capgemini/reports/templates/DynamicGridTemplateBuilder.java b/kurt-utility/src/main/java/com/capgemini/reports/templates/DynamicGridTemplateBuilder.java new file mode 100644 index 0000000..44834ed --- /dev/null +++ b/kurt-utility/src/main/java/com/capgemini/reports/templates/DynamicGridTemplateBuilder.java @@ -0,0 +1,220 @@ +package com.capgemini.reports.templates; + +import com.capgemini.framework.common.FileTemplate; +import com.capgemini.framework.common.ResourceHelper; +import com.capgemini.reports.exceptions.FileLoadingException; +import com.capgemini.reports.exceptions.InvalidInputException; + +import java.util.ArrayList; +import java.util.List; + +/** + * Dynamically creates a jrxml template for a table with an arbitrary number of columns. + */ +public class DynamicGridTemplateBuilder extends FileTemplate { + + // Keys to replace in the template.jrxml + private static final String HEADER_HEIGHT = "HEADER_HEIGHT"; + private static final String CONTENT_HEIGHT = "CONTENT_HEIGHT"; + protected static final String TITLE_HEIGHT = "TITLE_HEIGHT"; + private static final String TOTAL_HEIGHT = "TOTAL_HEIGHT"; + private static final String TOTAL_WIDTH = "TOTAL_WIDTH"; + private static final String PARAMETERS = "PARAMETERS"; + private static final String FIELDS = "FIELDS"; + private static final String HEADERS = "HEADERS"; + private static final String CONTENT = "CONTENT"; + protected static final String PROPERTY = "PROPERTY"; + private static final String IS_IGNORE_PAGINATION = "IS_IGNORE_PAGINATION"; + protected static final String STYLE = "STYLE"; + protected static final String TITLE = "TITLE"; + protected static final String NAME_SHEET = "NAME_SHEET"; + protected StringBuilder parametersDeclaration = new StringBuilder(); + protected StringBuilder fieldsDeclaration = new StringBuilder(); + protected StringBuilder contentStyle = new StringBuilder(); + private final StringBuilder headersDeclaration = new StringBuilder(); + private final StringBuilder contentFields = new StringBuilder(); + protected StringBuilder titleDeclaration = new StringBuilder(); + protected StringBuilder propertyDeclaration = new StringBuilder(); + protected String nameSheetDeclaration = ""; + protected final List columns; + private final int contentLineHeight; + private final int numberOfColumns; + private final int totalGridWidth; + protected int heigthTitle; + private int totalHeaderHeight; + protected static final String BEGIN_STYLE = "\n "; + protected static final String END_STYLE_FIRST = "\n "; + protected static final String MULTIPLE_CONDITIONAL_INCLUSIF = " && "; + protected static final String MULTIPLE_CONDITIONAL_EXCLUSIF = " || "; + protected static final String BEGIN_VARIABLE_DATA = ""; + protected static final String TOP_PEN = " listElementTitle = new ArrayList<>(); + + /** + * Builds a table template. + * + * @param widths The widths of every columns in this table + * @param contentKeys the String keys of each column's content fields + * @param contentLineHeight The height of each content rows, in pixels + * @param formats (optional) a List of field {@link CellFormat}. If the list is null or empty, no format is specified + * @param stretchWithOverFlow (optional) a List of field alignments. If the list is null or empty, no stretch will be performed + * @throws FileLoadingException if the template could not be loaded + * @throws InvalidInputException if input list length do not match + */ + public DynamicGridTemplateBuilder(final List widths, final List contentKeys, final List formats, + final List stretchWithOverFlow, final int contentLineHeight) throws FileLoadingException, InvalidInputException { + super(); + heigthTitle = 0; + if (widths == null || contentKeys == null || widths.size() != contentKeys.size()) { + throw new InvalidInputException("Column size mismatch: widths List must be the same length as contentKeys list"); + } + if (formats != null && !formats.isEmpty() && formats.size() != widths.size()) { + throw new InvalidInputException("Alignments specified but do not match the table size"); + } + this.numberOfColumns = widths.size(); + // Setup each column + int incrementalWidth = 0; + this.columns = new ArrayList<>(numberOfColumns); + this.contentLineHeight = contentLineHeight; + for (int numCol = 0; numCol < numberOfColumns; numCol++) { + Integer width = widths.get(numCol); + CellFormat fieldFormat = (formats == null || formats.isEmpty()) ? null : formats.get(numCol); + boolean isStretch = (stretchWithOverFlow == null || stretchWithOverFlow.isEmpty()) ? false : stretchWithOverFlow.get(numCol); + columns.add(new Column(contentKeys.get(numCol), width, incrementalWidth, isStretch, contentLineHeight, fieldFormat)); + incrementalWidth += width; + } + totalGridWidth = incrementalWidth; + this.setTemplateContent(ResourceHelper.getResourceContent("/Jasper/template/dynamic_table/template.jrxml")); + this.setTagValue(IS_IGNORE_PAGINATION, "false"); + + } + + /** + * Makes this template nover change page (use this to have a single long excel sheet). + */ + public void ignorePagination() { + this.setTagValue(IS_IGNORE_PAGINATION, "true"); + } + + /** + * Adds a header line to this table. The line is added as the last of the header lines, just before the main body. + * + * @param heightPx th eline's height, in pixels + * @param lineContent the line's content: Either the static text, the dynamic parameter key, or null if the cell above should be fused with this one + * @param dynamic a list of booleans, telling this line if each of the columns above are dynamic (tru) or static (false) or null if the cell above should be fused with this one + * @param formats a List of field Formats. + * @param stretchWithOverFlow (optional) a List of field alignments. If the list is null or empty, no stretch will be performed + * @throws InvalidInputException when the line's 'content' or 'dynamic' params are not of the same legntth as the number of columns in the report + */ + public void addHeaderLine(final int heightPx, final List lineContent, final List dynamic, final List formats, + final List stretchWithOverFlow) throws InvalidInputException { + if (lineContent.size() != numberOfColumns || dynamic.size() != numberOfColumns) { + throw new InvalidInputException("Line content length does not match the number of columns (" + numberOfColumns + ")"); + } + CellFormat defaultFormatWithOnlyColor = new CellFormat(); + boolean defaultFormat = formats == null || formats.isEmpty() || formats.size() != numberOfColumns; + for (int numCol = 0; numCol < numberOfColumns; numCol++) { + String cellContent = lineContent.get(numCol); + Column column = columns.get(numCol); + Boolean isDynamic = dynamic.get(numCol); + if (cellContent == null || isDynamic == null) { + column.addToPreviousHeaderCellHeight(heightPx); + } + else { + CellFormat format; + if (defaultFormat) { + format = defaultFormatWithOnlyColor; + } + else { + format = formats.get(numCol); + } + boolean isStretch = (stretchWithOverFlow == null || stretchWithOverFlow.isEmpty()) ? false : stretchWithOverFlow.get(numCol); + column.addHeader(cellContent, isDynamic, heightPx, isStretch, format); + } + } + totalHeaderHeight += heightPx; + } + + /** + * Adds a header line to this table. The line is added as the last of the header lines, just before the main body. + * + * @param heightPx th eline's height, in pixels + * @param lineContent the line's content: Either the static text, the dynamic parameter key, or null if the cell above should be fused with this one + * @param dynamic a list of booleans, telling this line if each of the columns above are dynamic (tru) or static (false) or null if the cell above should be fused with this one + * @param theFormat the Format for all fields. If null, no format is specified. + * @param stretchWithOverFlow (optional) a List of field alignments. If the list is null or empty, no stretch will be performed + * @throws InvalidInputException when the line's 'content' or 'dynamic' params are not of the same legntth as the number of columns in the report + */ + public void addHeaderLine(final int heightPx, final List lineContent, final List dynamic, final CellFormat theFormat, + final List stretchWithOverFlow) throws InvalidInputException { + if (lineContent.size() != numberOfColumns || dynamic.size() != numberOfColumns) { + throw new InvalidInputException("Line content length does not match the number of columns (" + numberOfColumns + ")"); + } + for (int numCol = 0; numCol < numberOfColumns; numCol++) { + String cellContent = lineContent.get(numCol); + Column column = columns.get(numCol); + Boolean isDynamic = dynamic.get(numCol); + if (cellContent == null || isDynamic == null) { + column.addToPreviousHeaderCellHeight(heightPx); + } + else { + boolean isStretch = (stretchWithOverFlow == null || stretchWithOverFlow.isEmpty()) ? false : stretchWithOverFlow.get(numCol); + column.addHeader(cellContent, isDynamic, heightPx, isStretch, theFormat); + } + } + totalHeaderHeight += heightPx; + } + + @Override + public String generateCode() { + + for (Column col : columns) { + parametersDeclaration.append(col.getParametersDeclaration()); + fieldsDeclaration.append(col.getFieldsDeclaration()); + headersDeclaration.append(col.makeHeaders()); + contentFields.append(col.makeContent()); + } + // Setup the proper tags + + super.setTagValue(PARAMETERS, parametersDeclaration.toString()); + super.setTagValue(FIELDS, fieldsDeclaration.toString()); + super.setTagValue(HEADERS, headersDeclaration.toString()); + super.setTagValue(CONTENT, contentFields.toString()); + super.setTagValue(HEADER_HEIGHT, String.valueOf(totalHeaderHeight)); + super.setTagValue(CONTENT_HEIGHT, String.valueOf(contentLineHeight)); + super.setTagValue(TOTAL_HEIGHT, String.valueOf(totalHeaderHeight + contentLineHeight + heigthTitle)); + super.setTagValue(TOTAL_WIDTH, String.valueOf(totalGridWidth)); + // Generate the content + return super.generateCode(); + } + +} diff --git a/kurt-utility/src/main/resources/Jasper/images/Snecma_logo.png b/kurt-utility/src/main/resources/Jasper/images/Snecma_logo.png new file mode 100644 index 0000000..e40717b Binary files /dev/null and b/kurt-utility/src/main/resources/Jasper/images/Snecma_logo.png differ diff --git a/kurt-utility/src/main/resources/Jasper/images/confidentiel_industrie.jpg b/kurt-utility/src/main/resources/Jasper/images/confidentiel_industrie.jpg new file mode 100644 index 0000000..3008bff Binary files /dev/null and b/kurt-utility/src/main/resources/Jasper/images/confidentiel_industrie.jpg differ diff --git a/kurt-utility/src/main/resources/Jasper/template/dynamic_table/template.jrxml b/kurt-utility/src/main/resources/Jasper/template/dynamic_table/template.jrxml new file mode 100644 index 0000000..86687d3 --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/dynamic_table/template.jrxml @@ -0,0 +1,17 @@ + +[[PARAMETERS]] + + + [[FIELDS]] + + + + + [[HEADERS]] + + + + [[CONTENT]] + + + \ No newline at end of file diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r01.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r01.jrxml new file mode 100644 index 0000000..f96b030 --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r01.jrxml @@ -0,0 +1,1076 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r03.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r03.jrxml new file mode 100644 index 0000000..39b0ecc --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r03.jrxml @@ -0,0 +1,726 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r10.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r10.jrxml new file mode 100644 index 0000000..efa9bad --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r10.jrxml @@ -0,0 +1,918 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r11.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r11.jrxml new file mode 100644 index 0000000..c7f76ab --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r11.jrxml @@ -0,0 +1,638 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band height="160" splitType="Stretch"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <staticText> + <reportElement x="-20" y="100" width="320" height="20" uuid="33d7e186-0b67-416e-8a86-26655b01cf0c"/> + <textElement> + <font size="8"/> + </textElement> + <text><![CDATA[Nombre de repères fonctionnels avec mise en maquette cohérente]]></text> + </staticText> + <staticText> + <reportElement x="-20" y="20" width="320" height="20" uuid="b554ec37-e2af-4344-a385-263bd5dffdab"/> + <textElement> + <font size="8"/> + </textElement> + <text><![CDATA[Nombre de repères fonctionnels mis en maquette :]]></text> + </staticText> + <staticText> + <reportElement x="-20" y="40" width="320" height="20" uuid="4628b4ee-acce-490a-a3cc-5ff1289d5db0"/> + <textElement> + <font size="8"/> + </textElement> + <text><![CDATA[Pourcentage de mise en maquette :]]></text> + </staticText> + <staticText> + <reportElement x="-20" y="60" width="320" height="20" uuid="d2763629-2316-46e2-8d08-bc2f012aa4be"/> + <textElement> + <font size="8"/> + </textElement> + <text><![CDATA[Nombre de repères fonctionnels avec une incohérence de mise en maquette :]]></text> + </staticText> + <staticText> + <reportElement x="-20" y="80" width="320" height="20" uuid="594ca80b-2686-45e1-a831-1d32b7d0e891"/> + <textElement> + <font size="8"/> + </textElement> + <text><![CDATA[Pourcentage de repères fonctionnels mis en maquette incohérente]]></text> + </staticText> + <textField> + <reportElement x="300" y="0" width="80" height="20" uuid="1ad40902-0de9-428b-aa8a-7a6f21d3c998"/> + <textFieldExpression><![CDATA[$P{NOMBRE_REPERE_FONCTIONNEL_METTRE_EN_MAQUETTE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="300" y="20" width="80" height="20" uuid="dd6c4654-9f34-4bdd-84df-55ef28c91c67"/> + <textFieldExpression><![CDATA[$P{NOMBRE_REPERE_FONCTIONNEL_MAQUETTE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="300" y="40" width="80" height="20" uuid="6fb1523c-9e69-45aa-b61d-5a8ae9b6ef19"/> + <textFieldExpression><![CDATA[$P{MISE_EN_MAQUETTE_POURCENTAGE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="300" y="60" width="80" height="20" uuid="a90d110c-893d-4f00-83d6-0ad6a7454926"/> + <textFieldExpression><![CDATA[$P{NOMBRE_REPERE_FONCTIONNEL_INCOHERENT}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="300" y="80" width="80" height="20" uuid="f8c79aed-4af3-44d3-bc43-a4ac7fb08f4d"/> + <textFieldExpression><![CDATA[$P{REPERE_FONCTIONNEL_MAQUETTE_INCOHERENTE_POURCENTAGE}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="-20" y="0" width="320" height="20" uuid="686e3570-9ad2-4202-8d37-a7e6f8cdb515"/> + <textElement> + <font size="8"/> + </textElement> + <text><![CDATA[Nombre de repères fonctionnels à mettre en maquette]]></text> + </staticText> + <staticText> + <reportElement x="-20" y="120" width="320" height="20" uuid="87021f19-7594-4bdd-a6ff-8ea485226e51"/> + <textElement> + <font size="8"/> + </textElement> + <text><![CDATA[Pourcentage de repères fonctionnels mis en maquette cohérente]]></text> + </staticText> + <textField> + <reportElement x="300" y="120" width="80" height="20" uuid="08415e62-0b9f-439f-af0f-0ab21019984b"/> + <textFieldExpression><![CDATA[$P{POURCENTAGE_MAQUETTE_COHERENTE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="300" y="100" width="80" height="20" uuid="7a9d71de-3528-41f3-a26d-481290de89c6"/> + <textFieldExpression><![CDATA[$P{NOMBRE_REPERE_FONCTIONNEL_MISE_EN_MAQUETTE_COHERENTE}]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r13/report_r13_cr.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r13/report_r13_cr.jrxml new file mode 100644 index 0000000..0ced7e3 --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r13/report_r13_cr.jrxml @@ -0,0 +1,975 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r13/report_r13_fpp.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r13/report_r13_fpp.jrxml new file mode 100644 index 0000000..0543af8 --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r13/report_r13_fpp.jrxml @@ -0,0 +1,579 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r15r16.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r15r16.jrxml new file mode 100644 index 0000000..732d64b --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r15r16.jrxml @@ -0,0 +1,695 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1]]> + + + + + + + + + + + + + <band height="761"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <image> + <reportElement x="0" y="0" width="180" height="40" uuid="bd1c5457-daa9-4754-9f61-54f1400686ee"> + <property name="local_mesure_unitwidth" value="pixel"/> + <property name="com.jaspersoft.studio.unit.width" value="px"/> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <imageExpression><![CDATA[$P{SNECMA_LOGO}]]></imageExpression> + </image> + <staticText> + <reportElement positionType="Float" x="0" y="521" width="150" height="30" uuid="c8e9f5f7-1896-4aaf-b18a-0c09312016cd"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <printWhenExpression><![CDATA[$P{IS_PREVIOUS_DEF}]]></printWhenExpression> + </reportElement> + <textElement verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[MT +MT Number]]></text> + </staticText> + <staticText> + <reportElement positionType="Float" x="0" y="551" width="150" height="30" uuid="62981c54-a5b2-48bf-9840-cc4e60859226"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <printWhenExpression><![CDATA[$P{IS_PREVIOUS_DEF}]]></printWhenExpression> + </reportElement> + <textElement verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Date de lancement +Release date]]></text> + </staticText> + <textField> + <reportElement positionType="Float" x="150" y="551" width="405" height="30" uuid="2c240f3e-0a02-4bcd-a98c-8c894e9e1d19"> + <printWhenExpression><![CDATA[$P{IS_PREVIOUS_DEF}]]></printWhenExpression> + </reportElement> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PREVIOUS_RELEASE_DATE}]]></textFieldExpression> + </textField> + <textField> + <reportElement positionType="Float" stretchType="RelativeToTallestObject" x="150" y="521" width="405" height="30" uuid="2830e066-9f5f-4682-bc32-64bc41b898fa"> + <printWhenExpression><![CDATA[$P{IS_PREVIOUS_DEF}]]></printWhenExpression> + </reportElement> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{MT_NUMBER}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="280" width="150" height="30" uuid="d58f0c3a-9c3f-42a0-9a74-c4b13a4bfc9e"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Dénomination Française +French Designation]]></text> + </staticText> + <textField> + <reportElement x="150" y="280" width="405" height="30" uuid="e5081414-e2bf-40bd-bccc-567131df6a5e"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{FRENCH_DESIGNATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="490" width="150" height="30" uuid="c71a994c-a413-4f90-a94a-fcadd4a82a17"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Obturation +Obturation]]></text> + </staticText> + <textField> + <reportElement x="150" y="400" width="405" height="30" uuid="48b02918-dd5b-45ea-bce6-6423778e1596"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{LOG_DOCUMENT}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="160" width="405" height="30" uuid="b8f4eb10-ca2d-498c-94ce-7589f0d24c80"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PRODUCT_TYPE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="190" width="405" height="30" uuid="06a0f02d-35ff-49f5-a0da-43fd541563bb"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PART_NUMBER}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="400" width="150" height="30" uuid="a329c593-2261-491c-8216-3449466dd821"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Document de contrôle +Log Document]]></text> + </staticText> + <staticText> + <reportElement x="0" y="250" width="150" height="30" uuid="c887a61f-5bdf-4759-b01f-ca535f263f7c"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Version de l’article +Part version]]></text> + </staticText> + <staticText> + <reportElement x="0" y="160" width="150" height="30" uuid="0b2fbdcf-2b30-4936-b89a-b237bc00858a"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Type produit +Product Type]]></text> + </staticText> + <textField> + <reportElement x="150" y="490" width="405" height="30" uuid="f9019024-1120-45c1-a3fa-a4f6b6c00eab"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{OBTURATION}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="220" width="405" height="30" uuid="04f2420a-7fd1-42b0-8da2-422f0b2a99c5"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{MANUFACTURER_CODE}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="370" width="150" height="30" uuid="a3f18762-a923-47c2-9dab-0bb02dea7ec5"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Suivi Utilisation +Field OPN serialisation]]></text> + </staticText> + <textField> + <reportElement x="150" y="370" width="405" height="30" uuid="0f42ed3c-21a3-48ab-bab2-7e61699bdc78"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{FIELD_OPN_SERIALISATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="340" width="150" height="30" uuid="e74a400e-5b28-4206-9538-0e5322e395be"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Classement +Classification]]></text> + </staticText> + <textField> + <reportElement x="150" y="340" width="405" height="30" uuid="5531e836-80a9-4bb9-8216-98637993b852"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{CLASSIFICATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="190" width="150" height="30" uuid="a760d63d-8652-4c30-a0fc-80032474925f"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Référence de l’article +Part Number]]></text> + </staticText> + <textField> + <reportElement x="150" y="250" width="405" height="30" uuid="7acd17db-c975-482b-b33a-5a50cd7e495e"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PART_VERSION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="220" width="150" height="30" uuid="56254219-d62f-4d1f-b7e2-e7ba6b55db05"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Code Fabricant +Manufacturer code]]></text> + </staticText> + <textField> + <reportElement x="60" y="80" width="120" height="20" uuid="16a34db8-b544-4ed7-aa30-723bbd0f2c97"> + <property name="local_mesure_unity" value="pixel"/> + <property name="com.jaspersoft.studio.unit.y" value="px"/> + </reportElement> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{ITEM_ID}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="200" y="120" width="290" height="20" uuid="5cd5ea2e-370d-4843-86ec-284dd5cc4669"/> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{RELEASE_DATE}]]></textFieldExpression> + </textField> + <textField isStretchWithOverflow="true"> + <reportElement x="200" y="80" width="290" height="20" uuid="90631035-798d-4f4d-800a-1ae0da7199ce"/> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{ITEM_REVISION_ID}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="60" y="120" width="120" height="20" uuid="ae3b956d-b485-4801-81d9-dc75765b5f27"/> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PRODUCT_UNIT}]]></textFieldExpression> + </textField> + <textField isStretchWithOverflow="true"> + <reportElement stretchType="RelativeToTallestObject" x="20" y="681" width="510" height="80" uuid="0953ec0c-dd4c-4d2b-bfdf-bc17f90863e7"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Center" markup="styled"> + <font size="7" isBold="false" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{CLAUSE_PROPRIETE}]]></textFieldExpression> + </textField> + <line> + <reportElement x="0" y="680" width="555" height="1" uuid="c8a04261-d21b-476f-a9c8-3513667543fe"> + <property name="local_mesure_unity" value="pixel"/> + <property name="com.jaspersoft.studio.unit.y" value="px"/> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + </line> + <textField> + <reportElement x="520" y="741" width="34" height="20" uuid="f3f0d26b-5d68-4356-88f2-fc0b8d32b880"/> + <textElement textAlignment="Right"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <textFieldExpression><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="310" width="405" height="30" uuid="1e3b2e3b-8658-4332-8baa-1492978ab190"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{ENGLISH_DESIGNATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="310" width="150" height="30" uuid="1026facf-47bb-4163-939d-a87d49e93d9e"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Dénomination Anglaise +English designation]]></text> + </staticText> + <staticText> + <reportElement x="0" y="430" width="150" height="30" uuid="58157510-6554-420b-b0eb-97ade29844ae"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Frontière Avion +Installation Interface]]></text> + </staticText> + <textField> + <reportElement x="150" y="460" width="405" height="30" uuid="a12899e5-d6f2-42f0-9de5-5acdc64ed2a2"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PARTNER_INTERFACE}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="460" width="150" height="30" uuid="5a2f3dcd-1fbd-4e8f-b46f-577c64544d37"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Frontière Coopérant +Partner Interface]]></text> + </staticText> + <textField> + <reportElement x="150" y="430" width="405" height="30" uuid="ab848d3a-8005-4763-8583-384bb8c70cfc"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{INSTALLATION_INTERFACE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="80" y="40" width="380" height="30" uuid="3f7c9d3f-0877-4237-a0c2-5b2c3e0e561c"/> + <textElement textAlignment="Center" verticalAlignment="Middle" markup="styled"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <textFieldExpression><![CDATA[$P{REPORT_TITLE}]]></textFieldExpression> + </textField> + <textField isStretchWithOverflow="true"> + <reportElement x="0" y="520" width="554" height="1" uuid="0ce0810e-0f14-4a0c-a06f-7f6665643d74"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <printWhenExpression><![CDATA[$P{IS_PREVIOUS_DEF}]]></printWhenExpression> + </reportElement> + <textElement textAlignment="Center" verticalAlignment="Middle"> + <font isBold="true"/> + </textElement> + <textFieldExpression><![CDATA["\nDéfinition précédente / Previous Definition\n"]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r17.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r17.jrxml new file mode 100644 index 0000000..996a677 --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r17.jrxml @@ -0,0 +1,620 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1]]> + + + + + + + + + + + + + <band height="760"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <image> + <reportElement x="0" y="0" width="180" height="40" uuid="bd1c5457-daa9-4754-9f61-54f1400686ee"> + <property name="local_mesure_unitwidth" value="pixel"/> + <property name="com.jaspersoft.studio.unit.width" value="px"/> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <imageExpression><![CDATA[$P{SNECMA_LOGO}]]></imageExpression> + </image> + <staticText> + <reportElement x="0" y="560" width="150" height="30" uuid="c8e9f5f7-1896-4aaf-b18a-0c09312016cd"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[MT +MT Number]]></text> + </staticText> + <staticText> + <reportElement x="0" y="590" width="150" height="30" uuid="62981c54-a5b2-48bf-9840-cc4e60859226"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Date de lancement +Release date]]></text> + </staticText> + <staticText> + <reportElement x="180" y="530" width="300" height="20" uuid="7cd156c7-8245-4fad-bac6-3244c82501c8"/> + <textElement> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Définition précédente / Previous Definition]]></text> + </staticText> + <textField> + <reportElement x="150" y="590" width="405" height="30" uuid="2c240f3e-0a02-4bcd-a98c-8c894e9e1d19"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PREVIOUS_RELEASE_DATE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="560" width="405" height="30" uuid="2830e066-9f5f-4682-bc32-64bc41b898fa"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{MT_NUMBER}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="280" width="150" height="30" uuid="d58f0c3a-9c3f-42a0-9a74-c4b13a4bfc9e"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Dénomination Française +French Designation]]></text> + </staticText> + <textField> + <reportElement x="150" y="280" width="405" height="30" uuid="e5081414-e2bf-40bd-bccc-567131df6a5e"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{FRENCH_DESIGNATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="430" width="150" height="30" uuid="c71a994c-a413-4f90-a94a-fcadd4a82a17"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Obturation +Obturation]]></text> + </staticText> + <textField> + <reportElement x="150" y="400" width="405" height="30" uuid="48b02918-dd5b-45ea-bce6-6423778e1596"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{LOG_DOCUMENT}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="160" width="405" height="30" uuid="b8f4eb10-ca2d-498c-94ce-7589f0d24c80"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PRODUCT_TYPE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="190" width="405" height="30" uuid="06a0f02d-35ff-49f5-a0da-43fd541563bb"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PART_NUMBER}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="400" width="150" height="30" uuid="a329c593-2261-491c-8216-3449466dd821"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Document de contrôle +Log Document]]></text> + </staticText> + <staticText> + <reportElement x="0" y="250" width="150" height="30" uuid="c887a61f-5bdf-4759-b01f-ca535f263f7c"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Version de l’article +Part version]]></text> + </staticText> + <staticText> + <reportElement x="0" y="160" width="150" height="30" uuid="0b2fbdcf-2b30-4936-b89a-b237bc00858a"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Type produit +Product Type]]></text> + </staticText> + <textField> + <reportElement x="150" y="430" width="405" height="30" uuid="f9019024-1120-45c1-a3fa-a4f6b6c00eab"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{OBTURATION}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="220" width="405" height="30" uuid="04f2420a-7fd1-42b0-8da2-422f0b2a99c5"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{MANUFACTURER_CODE}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="370" width="150" height="30" uuid="a3f18762-a923-47c2-9dab-0bb02dea7ec5"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Suivi Utilisation +Field OPN serialisation]]></text> + </staticText> + <textField> + <reportElement x="150" y="370" width="405" height="30" uuid="0f42ed3c-21a3-48ab-bab2-7e61699bdc78"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{FIELD_OPN_SERIALISATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="340" width="150" height="30" uuid="e74a400e-5b28-4206-9538-0e5322e395be"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Classement +Classification]]></text> + </staticText> + <textField> + <reportElement x="150" y="340" width="405" height="30" uuid="5531e836-80a9-4bb9-8216-98637993b852"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{CLASSIFICATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="190" width="150" height="30" uuid="a760d63d-8652-4c30-a0fc-80032474925f"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Référence de l’article +Part Number]]></text> + </staticText> + <textField> + <reportElement x="150" y="250" width="405" height="30" uuid="7acd17db-c975-482b-b33a-5a50cd7e495e"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{PART_VERSION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="220" width="150" height="30" uuid="56254219-d62f-4d1f-b7e2-e7ba6b55db05"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Code Fabricant +Manufacturer code]]></text> + </staticText> + <textField> + <reportElement x="60" y="80" width="120" height="20" uuid="16a34db8-b544-4ed7-aa30-723bbd0f2c97"> + <property name="local_mesure_unity" value="pixel"/> + <property name="com.jaspersoft.studio.unit.y" value="px"/> + </reportElement> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{ITEM_ID}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="200" y="120" width="290" height="20" uuid="5cd5ea2e-370d-4843-86ec-284dd5cc4669"/> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{RELEASE_DATE}]]></textFieldExpression> + </textField> + <textField isStretchWithOverflow="true"> + <reportElement x="200" y="80" width="290" height="20" uuid="90631035-798d-4f4d-800a-1ae0da7199ce"/> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"> + <font pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{ITEM_REVISION_ID}]]></textFieldExpression> + </textField> + <textField isStretchWithOverflow="true"> + <reportElement stretchType="RelativeToTallestObject" x="20" y="680" width="520" height="80" uuid="0953ec0c-dd4c-4d2b-bfdf-bc17f90863e7"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Center" markup="styled"> + <font size="7" isBold="false" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{CLAUSE_PROPRIETE}]]></textFieldExpression> + </textField> + <line> + <reportElement x="0" y="680" width="555" height="1" uuid="c8a04261-d21b-476f-a9c8-3513667543fe"> + <property name="local_mesure_unity" value="pixel"/> + <property name="com.jaspersoft.studio.unit.y" value="px"/> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + </line> + <textField> + <reportElement x="530" y="740" width="24" height="20" uuid="f3f0d26b-5d68-4356-88f2-fc0b8d32b880"/> + <textElement textAlignment="Right"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <textFieldExpression><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="310" width="150" height="30" uuid="7807ccdf-9479-42d0-8a5c-a41805923c37"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Dénomination Anglaise +English designation]]></text> + </staticText> + <textField> + <reportElement x="150" y="310" width="405" height="30" uuid="fdd0ad29-2a8c-4c0a-88f8-da8648ca3f5d"/> + <textElement verticalAlignment="Middle"> + <font size="8" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{ENGLISH_DESIGNATION}]]></textFieldExpression> + </textField> + <rectangle> + <reportElement x="60" y="120" width="120" height="20" uuid="fe8029bb-5c43-450a-bb89-70908609e531"/> + </rectangle> + <textField> + <reportElement x="80" y="40" width="380" height="30" uuid="13308d92-200e-48eb-8dcf-77e6f9f271b9"/> + <textElement textAlignment="Center" verticalAlignment="Middle" markup="styled"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <textFieldExpression><![CDATA[$P{REPORT_TITLE}]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r19.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r19.jrxml new file mode 100644 index 0000000..37c5dea --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r19.jrxml @@ -0,0 +1,649 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r20/Snecma_logo.png b/kurt-utility/src/main/resources/Jasper/template/report_r20/Snecma_logo.png new file mode 100644 index 0000000..e40717b Binary files /dev/null and b/kurt-utility/src/main/resources/Jasper/template/report_r20/Snecma_logo.png differ diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r20/page2/r20_p2_generics.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r20/page2/r20_p2_generics.jrxml new file mode 100644 index 0000000..e060ed0 --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r20/page2/r20_p2_generics.jrxml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r20/page2/r20_p2_impacts.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r20/page2/r20_p2_impacts.jrxml new file mode 100644 index 0000000..a21b676 --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r20/page2/r20_p2_impacts.jrxml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r20/page2/r20_p2_noimpacts.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r20/page2/r20_p2_noimpacts.jrxml new file mode 100644 index 0000000..962ba07 --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r20/page2/r20_p2_noimpacts.jrxml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r20/page3/report_r20_p3.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r20/page3/report_r20_p3.jrxml new file mode 100644 index 0000000..6ba0f72 --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r20/page3/report_r20_p3.jrxml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [[SUBTABLES]] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r20/report_r20_master.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r20/report_r20_master.jrxml new file mode 100644 index 0000000..9bb472e --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r20/report_r20_master.jrxml @@ -0,0 +1,286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + >)$P{SUBREPORT_P2}.get("DATA"))]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + >)$P{SUBREPORT_P1}.get("DATA"))]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + >)$P{SUBREPORT_P3}.get("DATA"))]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + >)$P{SUBREPORT_P4}.get("DATA"))]]> + + + + + + + + + + + + Ce document est la propriété de Safran Aircraft Engines. Il ne peut être utilisé, reproduit ou communiqué sans son autorisation.
F0301"]]>
+
+
+
+ + + + + + + + + + + +
diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r20/report_r20_p1.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r20/report_r20_p1.jrxml new file mode 100644 index 0000000..a9d34e5 --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r20/report_r20_p1.jrxml @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r20/report_r20_p2.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r20/report_r20_p2.jrxml new file mode 100644 index 0000000..d6cd26b --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r20/report_r20_p2.jrxml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + >)$P{SUBREPORT_GENERIC}.get("DATA"))]]> + + + + + + + + + + + + + + + + + + + + >)$P{SUBREPORT_IMPACTS}.get("DATA"))]]> + + + + + + + + + + + + + >)$P{SUBREPORT_NOIMPACTS}.get("DATA"))]]> + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r20/report_r20_p4.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r20/report_r20_p4.jrxml new file mode 100644 index 0000000..46b2b08 --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r20/report_r20_p4.jrxml @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + <band height="103" splitType="Stretch"> + <staticText> + <reportElement x="0" y="0" width="800" height="30" uuid="92028f51-246a-47f2-8c73-95be69612b49"/> + <textElement textAlignment="Center"> + <font isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[DOCUMENT DE GEL DE UNIT FINAL (ANNEXE) +CALCUL DES REFERENCES TECHNIQUES]]></text> + </staticText> + <staticText> + <reportElement x="0" y="30" width="800" height="20" uuid="75b69c65-ad19-482b-905e-786a7605cd9a"/> + <text><![CDATA[L'impact de chaque modification sur les références des assemblages est décrit dans le tableau suivant : ]]></text> + </staticText> + <textField> + <reportElement x="0" y="50" width="800" height="20" uuid="510054a1-5695-4b3c-954e-fc5b312835aa"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textFieldExpression><![CDATA["Avant : UNIT " + $P{UNIT_AVANT} + " " + $P{EXCEPTIONNEL_AVANT} + " du produit " + $P{DOMAINE_PRODUIT_AVANT} + " " + $P{LIGNE_PRODUIT_AVANT}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="0" y="70" width="800" height="20" uuid="b9a32778-73b0-4b97-9616-c06f6f4f2c92"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textFieldExpression><![CDATA["Après : UNIT " + $P{UNIT_APRES} + " " + $P{EXCEPTIONNEL_APRES} + " du produit " + $P{DOMAINE_PRODUIT_APRES} + " " + $P{LIGNE_PRODUIT_APRES}]]></textFieldExpression> + </textField> + <textField> + <reportElement mode="Opaque" x="0" y="90" width="290" height="13" backcolor="#E3E3E3" uuid="c4e431d0-0c8a-4266-9c73-97958c24f127"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <box leftPadding="5"> + <topPen lineWidth="0.5"/> + <leftPen lineWidth="0.5"/> + <bottomPen lineWidth="0.5"/> + <rightPen lineWidth="0.5"/> + </box> + <textFieldExpression><![CDATA[$P{LIGNE_PRODUIT_APRES}]]></textFieldExpression> + </textField> + <rectangle> + <reportElement x="290" y="90" width="130" height="13" backcolor="#E3E3E3" uuid="c0013ff2-080b-4606-869c-e4105272fdbc"/> + <graphicElement> + <pen lineWidth="0.5"/> + </graphicElement> + </rectangle> + <staticText> + <reportElement mode="Opaque" x="420" y="90" width="190" height="13" backcolor="#E3E3E3" uuid="e43f8acf-e867-4e00-8108-c15fd3ebc4d2"/> + <box> + <topPen lineWidth="0.5"/> + <leftPen lineWidth="0.5"/> + <bottomPen lineWidth="0.5"/> + <rightPen lineWidth="0.5"/> + </box> + <textElement textAlignment="Center"/> + <text><![CDATA[Ancienne référence]]></text> + </staticText> + <staticText> + <reportElement mode="Opaque" x="610" y="90" width="190" height="13" backcolor="#E3E3E3" uuid="dcdf2e41-3751-4d1c-9950-7bb9b71f7042"/> + <box> + <topPen lineWidth="0.5"/> + <leftPen lineWidth="0.5"/> + <bottomPen lineWidth="0.5"/> + <rightPen lineWidth="0.5"/> + </box> + <textElement textAlignment="Center"/> + <text><![CDATA[Nouvelle référence]]></text> + </staticText> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r21.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r21.jrxml new file mode 100644 index 0000000..cb34e75 --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r21.jrxml @@ -0,0 +1,1027 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r22.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r22.jrxml new file mode 100644 index 0000000..3ae0027 --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r22.jrxml @@ -0,0 +1,912 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band height="181"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <image> + <reportElement x="0" y="0" width="802" height="30" uuid="02f283fc-725c-4091-a6df-64b3fe139563"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <imageExpression><![CDATA[$P{LOGO_SNECMA}]]></imageExpression> + </image> + <staticText> + <reportElement stretchType="RelativeToTallestObject" x="0" y="20" width="802" height="40" uuid="6f86d0ba-b648-4c52-b7dd-f6882be41c2e"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Center"> + <font fontName="SansSerif" size="24" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Extraction de nomenclatures sur effectivité par DATE]]></text> + </staticText> + <staticText> + <reportElement x="0" y="60" width="802" height="20" uuid="3ee15cb1-b6f7-4e0a-8ce4-55531cc1cd0c"/> + <textElement textAlignment="Center"> + <font fontName="SansSerif" size="14" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Bills of material using date effectivity]]></text> + </staticText> + <staticText> + <reportElement x="0" y="80" width="30" height="20" uuid="8213394e-7143-4f85-8259-f11a9e9f6da1"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Date :]]></text> + </staticText> + <staticText> + <reportElement x="0" y="100" width="90" height="20" uuid="16268bcd-1f46-436a-8985-139d61ae36ca"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Date d'effectivité :]]></text> + </staticText> + <staticText> + <reportElement x="0" y="120" width="90" height="20" uuid="ed387d70-8182-4a54-ad00-903b07d1cf5e"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Référence article :]]></text> + </staticText> + <staticText> + <reportElement x="0" y="140" width="40" height="20" uuid="adc6bff6-2abe-41b5-8ed9-296c4ec7649b"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Niveau :]]></text> + </staticText> + <staticText> + <reportElement x="0" y="160" width="50" height="20" uuid="223b27bf-23e1-4c1d-bf84-b487debd8fb2"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" isBold="true" pdfFontName="Helvetica-Bold"/> + </textElement> + <text><![CDATA[Résultat :]]></text> + </staticText> + <textField evaluationTime="Report"> + <reportElement x="30" y="80" width="772" height="20" uuid="2b6b80bd-3694-4680-9b89-8d80a4369f7c"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{DATE_TRAITEMENT}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report"> + <reportElement x="90" y="100" width="712" height="20" uuid="d5cc6967-759a-4822-908b-a0dee6741a2c"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{DATE_EFFECTIVITE}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report"> + <reportElement x="90" y="120" width="712" height="20" uuid="d2f8d509-7634-472c-a313-aecb48ed601a"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[$P{REFERENCE_ARTICLE}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report"> + <reportElement x="40" y="140" width="762" height="20" uuid="2f49bcdb-558b-45f0-810c-8f20fd157827"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" pdfFontName="Helvetica"/> + </textElement> + <textFieldExpression><![CDATA[" " + $P{NIVEAU}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="50" y="160" width="752" height="20" uuid="abcf5995-dfdf-44f2-820a-ecc79f1bf320"/> + <textElement verticalAlignment="Bottom"> + <font fontName="SansSerif" pdfFontName="Helvetica"/> + </textElement> + <text><![CDATA[pdf]]></text> + </staticText> + <break> + <reportElement x="0" y="180" width="96" height="1" uuid="76003345-b03a-4011-b34c-9c3d6a49d511"/> + </break> + </band> + + + + + + 1]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r23.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r23.jrxml new file mode 100644 index 0000000..eade002 --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r23.jrxml @@ -0,0 +1,1404 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r24.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r24.jrxml new file mode 100644 index 0000000..a83b0ad --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r24.jrxml @@ -0,0 +1,499 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band height="510"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <staticText> + <reportElement positionType="Float" x="0" y="441" width="150" height="30" uuid="c8e9f5f7-1896-4aaf-b18a-0c09312016cd"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <printWhenExpression><![CDATA[$P{IS_PREVIOUS_DEF}]]></printWhenExpression> + </reportElement> + <textElement verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[MT +MT Number]]></text> + </staticText> + <staticText> + <reportElement positionType="Float" x="0" y="471" width="150" height="30" uuid="62981c54-a5b2-48bf-9840-cc4e60859226"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <printWhenExpression><![CDATA[$P{IS_PREVIOUS_DEF}]]></printWhenExpression> + </reportElement> + <textElement verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Date de lancement +Release date]]></text> + </staticText> + <textField> + <reportElement positionType="Float" x="150" y="471" width="405" height="30" uuid="2c240f3e-0a02-4bcd-a98c-8c894e9e1d19"> + <printWhenExpression><![CDATA[$P{IS_PREVIOUS_DEF}]]></printWhenExpression> + </reportElement> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{PREVIOUS_RELEASE_DATE}]]></textFieldExpression> + </textField> + <textField> + <reportElement positionType="Float" stretchType="RelativeToTallestObject" x="150" y="441" width="405" height="30" uuid="2830e066-9f5f-4682-bc32-64bc41b898fa"> + <printWhenExpression><![CDATA[$P{IS_PREVIOUS_DEF}]]></printWhenExpression> + </reportElement> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{MT_NUMBER}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="200" width="150" height="30" uuid="d58f0c3a-9c3f-42a0-9a74-c4b13a4bfc9e"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Dénomination Française +French Designation]]></text> + </staticText> + <textField> + <reportElement x="150" y="200" width="405" height="30" uuid="e5081414-e2bf-40bd-bccc-567131df6a5e"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{FRENCH_DESIGNATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="410" width="150" height="30" uuid="c71a994c-a413-4f90-a94a-fcadd4a82a17"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Obturation +Obturation]]></text> + </staticText> + <textField> + <reportElement x="150" y="320" width="405" height="30" uuid="48b02918-dd5b-45ea-bce6-6423778e1596"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{LOG_DOCUMENT}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="80" width="405" height="30" uuid="b8f4eb10-ca2d-498c-94ce-7589f0d24c80"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{PRODUCT_TYPE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="110" width="405" height="30" uuid="06a0f02d-35ff-49f5-a0da-43fd541563bb"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{PART_NUMBER}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="320" width="150" height="30" uuid="a329c593-2261-491c-8216-3449466dd821"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Document de contrôle +Log Document]]></text> + </staticText> + <staticText> + <reportElement x="0" y="170" width="150" height="30" uuid="c887a61f-5bdf-4759-b01f-ca535f263f7c"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Version de l’article +Part version]]></text> + </staticText> + <staticText> + <reportElement x="0" y="80" width="150" height="30" uuid="0b2fbdcf-2b30-4936-b89a-b237bc00858a"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Type produit +Product Type]]></text> + </staticText> + <textField> + <reportElement x="150" y="410" width="405" height="30" uuid="f9019024-1120-45c1-a3fa-a4f6b6c00eab"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{OBTURATION}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="140" width="405" height="30" uuid="04f2420a-7fd1-42b0-8da2-422f0b2a99c5"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{MANUFACTURER_CODE}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="290" width="150" height="30" uuid="a3f18762-a923-47c2-9dab-0bb02dea7ec5"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Suivi Utilisation +Field OPN serialisation]]></text> + </staticText> + <textField> + <reportElement x="150" y="290" width="405" height="30" uuid="0f42ed3c-21a3-48ab-bab2-7e61699bdc78"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{FIELD_OPN_SERIALISATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="260" width="150" height="30" uuid="e74a400e-5b28-4206-9538-0e5322e395be"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Classement +Classification]]></text> + </staticText> + <textField> + <reportElement x="150" y="260" width="405" height="30" uuid="5531e836-80a9-4bb9-8216-98637993b852"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{CLASSIFICATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="110" width="150" height="30" uuid="a760d63d-8652-4c30-a0fc-80032474925f"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Référence de l’article +Part Number]]></text> + </staticText> + <textField> + <reportElement x="150" y="170" width="405" height="30" uuid="7acd17db-c975-482b-b33a-5a50cd7e495e"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{PART_VERSION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="140" width="150" height="30" uuid="56254219-d62f-4d1f-b7e2-e7ba6b55db05"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Code Fabricant +Manufacturer code]]></text> + </staticText> + <textField> + <reportElement x="60" y="0" width="120" height="20" uuid="16a34db8-b544-4ed7-aa30-723bbd0f2c97"> + <property name="local_mesure_unity" value="pixel"/> + <property name="com.jaspersoft.studio.unit.y" value="px"/> + <propertyExpression name="net.sf.jasperreports.export.xls.sheet.name"><![CDATA[$P{ITEM_ID}+ "_" + $V{PAGE_NUMBER}]]></propertyExpression> + </reportElement> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"/> + <textFieldExpression><![CDATA[$P{ITEM_ID}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="200" y="40" width="290" height="20" uuid="5cd5ea2e-370d-4843-86ec-284dd5cc4669"/> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"/> + <textFieldExpression><![CDATA[$P{RELEASE_DATE}]]></textFieldExpression> + </textField> + <textField isStretchWithOverflow="true"> + <reportElement x="200" y="0" width="290" height="20" uuid="90631035-798d-4f4d-800a-1ae0da7199ce"/> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"/> + <textFieldExpression><![CDATA[$P{ITEM_REVISION_ID}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="60" y="40" width="120" height="20" uuid="ae3b956d-b485-4801-81d9-dc75765b5f27"/> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"/> + <textFieldExpression><![CDATA[$P{PRODUCT_UNIT}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="230" width="405" height="30" uuid="1e3b2e3b-8658-4332-8baa-1492978ab190"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{ENGLISH_DESIGNATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="230" width="150" height="30" uuid="1026facf-47bb-4163-939d-a87d49e93d9e"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Dénomination Anglaise +English designation]]></text> + </staticText> + <staticText> + <reportElement x="0" y="350" width="150" height="30" uuid="58157510-6554-420b-b0eb-97ade29844ae"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Frontière Avion +Installation Interface]]></text> + </staticText> + <textField> + <reportElement x="150" y="380" width="405" height="30" uuid="a12899e5-d6f2-42f0-9de5-5acdc64ed2a2"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{PARTNER_INTERFACE}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="380" width="150" height="30" uuid="5a2f3dcd-1fbd-4e8f-b46f-577c64544d37"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Frontière Coopérant +Partner Interface]]></text> + </staticText> + <textField> + <reportElement x="150" y="350" width="405" height="30" uuid="ab848d3a-8005-4763-8583-384bb8c70cfc"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{INSTALLATION_INTERFACE}]]></textFieldExpression> + </textField> + <textField isStretchWithOverflow="true"> + <reportElement x="0" y="440" width="554" height="1" uuid="0ce0810e-0f14-4a0c-a06f-7f6665643d74"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <printWhenExpression><![CDATA[$P{IS_PREVIOUS_DEF}]]></printWhenExpression> + </reportElement> + <textElement textAlignment="Center" verticalAlignment="Middle"> + <font isBold="true"/> + </textElement> + <textFieldExpression><![CDATA["\nDéfinition précédente / Previous Definition\n"]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r25.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r25.jrxml new file mode 100644 index 0000000..ea1af4f --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r25.jrxml @@ -0,0 +1,790 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band height="510"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <staticText> + <reportElement positionType="Float" x="0" y="441" width="150" height="30" + uuid="c8e9f5f7-1896-4aaf-b18a-0c09312016cd"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <printWhenExpression><![CDATA[$P{IS_PREVIOUS_DEF}]]></printWhenExpression> + </reportElement> + <textElement verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[MT +MT Number]]></text> + </staticText> + <staticText> + <reportElement positionType="Float" x="0" y="471" width="150" height="30" + uuid="62981c54-a5b2-48bf-9840-cc4e60859226"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <printWhenExpression><![CDATA[$P{IS_PREVIOUS_DEF}]]></printWhenExpression> + </reportElement> + <textElement verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Date de lancement +Release date]]></text> + </staticText> + <textField> + <reportElement positionType="Float" x="150" y="471" width="405" height="30" + uuid="2c240f3e-0a02-4bcd-a98c-8c894e9e1d19"> + <printWhenExpression><![CDATA[$P{IS_PREVIOUS_DEF}]]></printWhenExpression> + </reportElement> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{PREVIOUS_RELEASE_DATE}]]></textFieldExpression> + </textField> + <textField> + <reportElement positionType="Float" stretchType="RelativeToTallestObject" x="150" y="441" width="405" + height="30" uuid="2830e066-9f5f-4682-bc32-64bc41b898fa"> + <printWhenExpression><![CDATA[$P{IS_PREVIOUS_DEF}]]></printWhenExpression> + </reportElement> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{MT_NUMBER}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="200" width="150" height="30" uuid="d58f0c3a-9c3f-42a0-9a74-c4b13a4bfc9e"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Dénomination Française +French Designation]]></text> + </staticText> + <textField> + <reportElement x="150" y="200" width="405" height="30" uuid="e5081414-e2bf-40bd-bccc-567131df6a5e"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{FRENCH_DESIGNATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="410" width="150" height="30" uuid="c71a994c-a413-4f90-a94a-fcadd4a82a17"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Obturation +Obturation]]></text> + </staticText> + <textField> + <reportElement x="150" y="320" width="405" height="30" uuid="48b02918-dd5b-45ea-bce6-6423778e1596"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{LOG_DOCUMENT}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="80" width="405" height="30" uuid="b8f4eb10-ca2d-498c-94ce-7589f0d24c80"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{PRODUCT_TYPE}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="110" width="405" height="30" uuid="06a0f02d-35ff-49f5-a0da-43fd541563bb"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{PART_NUMBER}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="320" width="150" height="30" uuid="a329c593-2261-491c-8216-3449466dd821"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Document de contrôle +Log Document]]></text> + </staticText> + <staticText> + <reportElement x="0" y="170" width="150" height="30" uuid="c887a61f-5bdf-4759-b01f-ca535f263f7c"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Version de l’article +Part version]]></text> + </staticText> + <staticText> + <reportElement x="0" y="80" width="150" height="30" uuid="0b2fbdcf-2b30-4936-b89a-b237bc00858a"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Type produit +Product Type]]></text> + </staticText> + <textField> + <reportElement x="150" y="410" width="405" height="30" uuid="f9019024-1120-45c1-a3fa-a4f6b6c00eab"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{OBTURATION}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="140" width="405" height="30" uuid="04f2420a-7fd1-42b0-8da2-422f0b2a99c5"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{MANUFACTURER_CODE}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="290" width="150" height="30" uuid="a3f18762-a923-47c2-9dab-0bb02dea7ec5"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Suivi Utilisation +Field OPN serialisation]]></text> + </staticText> + <textField> + <reportElement x="150" y="290" width="405" height="30" uuid="0f42ed3c-21a3-48ab-bab2-7e61699bdc78"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{FIELD_OPN_SERIALISATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="260" width="150" height="30" uuid="e74a400e-5b28-4206-9538-0e5322e395be"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Classement +Classification]]></text> + </staticText> + <textField> + <reportElement x="150" y="260" width="405" height="30" uuid="5531e836-80a9-4bb9-8216-98637993b852"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{CLASSIFICATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="110" width="150" height="30" uuid="a760d63d-8652-4c30-a0fc-80032474925f"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Référence de l’article +Part Number]]></text> + </staticText> + <textField> + <reportElement x="150" y="170" width="405" height="30" uuid="7acd17db-c975-482b-b33a-5a50cd7e495e"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{PART_VERSION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="140" width="150" height="30" uuid="56254219-d62f-4d1f-b7e2-e7ba6b55db05"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Code Fabricant +Manufacturer code]]></text> + </staticText> + <textField> + <reportElement x="60" y="0" width="120" height="20" uuid="16a34db8-b544-4ed7-aa30-723bbd0f2c97"> + <property name="local_mesure_unity" value="pixel"/> + <property name="com.jaspersoft.studio.unit.y" value="px"/> + <propertyExpression name="net.sf.jasperreports.export.xls.sheet.name"> + <![CDATA[$P{ITEM_ID}+ "_" + $V{PAGE_NUMBER}]]></propertyExpression> + </reportElement> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"/> + <textFieldExpression><![CDATA[$P{ITEM_ID}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="200" y="40" width="290" height="20" uuid="5cd5ea2e-370d-4843-86ec-284dd5cc4669"/> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"/> + <textFieldExpression><![CDATA[$P{RELEASE_DATE}]]></textFieldExpression> + </textField> + <textField isStretchWithOverflow="true"> + <reportElement x="200" y="0" width="290" height="20" uuid="90631035-798d-4f4d-800a-1ae0da7199ce"/> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"/> + <textFieldExpression><![CDATA[$P{ITEM_REVISION_ID}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="60" y="40" width="120" height="20" uuid="ae3b956d-b485-4801-81d9-dc75765b5f27"/> + <box leftPadding="5"> + <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement verticalAlignment="Middle"/> + <textFieldExpression><![CDATA[$P{PRODUCT_UNIT}]]></textFieldExpression> + </textField> + <textField> + <reportElement x="150" y="230" width="405" height="30" uuid="1e3b2e3b-8658-4332-8baa-1492978ab190"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{ENGLISH_DESIGNATION}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="230" width="150" height="30" uuid="1026facf-47bb-4163-939d-a87d49e93d9e"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Dénomination Anglaise +English designation]]></text> + </staticText> + <staticText> + <reportElement x="0" y="350" width="150" height="30" uuid="58157510-6554-420b-b0eb-97ade29844ae"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Frontière Avion +Installation Interface]]></text> + </staticText> + <textField> + <reportElement x="150" y="380" width="405" height="30" uuid="a12899e5-d6f2-42f0-9de5-5acdc64ed2a2"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{PARTNER_INTERFACE}]]></textFieldExpression> + </textField> + <staticText> + <reportElement x="0" y="380" width="150" height="30" uuid="5a2f3dcd-1fbd-4e8f-b46f-577c64544d37"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Left" verticalAlignment="Middle"> + <font size="8" isBold="true"/> + </textElement> + <text><![CDATA[Frontière Coopérant +Partner Interface]]></text> + </staticText> + <textField> + <reportElement x="150" y="350" width="405" height="30" uuid="ab848d3a-8005-4763-8583-384bb8c70cfc"/> + <textElement verticalAlignment="Middle"> + <font size="8"/> + </textElement> + <textFieldExpression><![CDATA[$P{INSTALLATION_INTERFACE}]]></textFieldExpression> + </textField> + <textField isStretchWithOverflow="true"> + <reportElement x="0" y="440" width="554" height="1" uuid="0ce0810e-0f14-4a0c-a06f-7f6665643d74"> + <property name="local_mesure_unitheight" value="pixel"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + <printWhenExpression><![CDATA[$P{IS_PREVIOUS_DEF}]]></printWhenExpression> + </reportElement> + <textElement textAlignment="Center" verticalAlignment="Middle"> + <font isBold="true"/> + </textElement> + <textFieldExpression><![CDATA["\nDéfinition précédente / Previous Definition\n"]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r26/report_r26_master.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r26/report_r26_master.jrxml new file mode 100644 index 0000000..4740970 --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r26/report_r26_master.jrxml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + >)$P{SUBREPORT_P1}.get("DATA"))]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + >)$P{SUBREPORT_P2}.get("DATA"))]]> + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r26/report_r26_subreport.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r26/report_r26_subreport.jrxml new file mode 100644 index 0000000..73ea70d --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r26/report_r26_subreport.jrxml @@ -0,0 +1,536 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r27.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r27.jrxml new file mode 100644 index 0000000..8be1c10 --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r27.jrxml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/report_r28.jrxml b/kurt-utility/src/main/resources/Jasper/template/report_r28.jrxml new file mode 100644 index 0000000..6d9fc05 --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/report_r28.jrxml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/Jasper/template/template_R07.jrxml b/kurt-utility/src/main/resources/Jasper/template/template_R07.jrxml new file mode 100644 index 0000000..5ed3b37 --- /dev/null +++ b/kurt-utility/src/main/resources/Jasper/template/template_R07.jrxml @@ -0,0 +1,18 @@ + +[[PROPERTY]][[STYLE]][[PARAMETERS]][[FIELDS]] + + + + + <band height = "[[TITLE_HEIGHT]]" splitType="Stretch">[[TITLE]] + </band> + + + [[HEADERS]] + + + + [[CONTENT]] + + + \ No newline at end of file diff --git a/kurt-utility/src/main/resources/hibernate.cfg.xml b/kurt-utility/src/main/resources/hibernate.cfg.xml new file mode 100644 index 0000000..77d9a61 --- /dev/null +++ b/kurt-utility/src/main/resources/hibernate.cfg.xml @@ -0,0 +1,42 @@ + + + + + + + + + org.hibernate.dialect.Oracle10gDialect + java:jboss/datasources/ReportDS + + + org.hibernate.cache.NoCacheProvider + + org.hibernate.transaction.JDBCTransactionFactory + + + thread + + + false + + + update + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/hibernate/DbCriteriaVal_mapping.xml b/kurt-utility/src/main/resources/hibernate/DbCriteriaVal_mapping.xml new file mode 100644 index 0000000..9f49460 --- /dev/null +++ b/kurt-utility/src/main/resources/hibernate/DbCriteriaVal_mapping.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/hibernate/DbCriteria_mapping.xml b/kurt-utility/src/main/resources/hibernate/DbCriteria_mapping.xml new file mode 100644 index 0000000..98c9485 --- /dev/null +++ b/kurt-utility/src/main/resources/hibernate/DbCriteria_mapping.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/hibernate/DbMemMonitor_mapping.xml b/kurt-utility/src/main/resources/hibernate/DbMemMonitor_mapping.xml new file mode 100644 index 0000000..2f64619 --- /dev/null +++ b/kurt-utility/src/main/resources/hibernate/DbMemMonitor_mapping.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/hibernate/DbReportOwner_mapping.xml b/kurt-utility/src/main/resources/hibernate/DbReportOwner_mapping.xml new file mode 100644 index 0000000..05173ae --- /dev/null +++ b/kurt-utility/src/main/resources/hibernate/DbReportOwner_mapping.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/hibernate/DbReportType_mapping.xml b/kurt-utility/src/main/resources/hibernate/DbReportType_mapping.xml new file mode 100644 index 0000000..d2b8cd9 --- /dev/null +++ b/kurt-utility/src/main/resources/hibernate/DbReportType_mapping.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/hibernate/DbReport_mapping.xml b/kurt-utility/src/main/resources/hibernate/DbReport_mapping.xml new file mode 100644 index 0000000..40c01a5 --- /dev/null +++ b/kurt-utility/src/main/resources/hibernate/DbReport_mapping.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/hibernate/DbSchedulingCriteriaVal_mapping.xml b/kurt-utility/src/main/resources/hibernate/DbSchedulingCriteriaVal_mapping.xml new file mode 100644 index 0000000..55c4236 --- /dev/null +++ b/kurt-utility/src/main/resources/hibernate/DbSchedulingCriteriaVal_mapping.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/hibernate/DbSchedulingReport_mapping.xml b/kurt-utility/src/main/resources/hibernate/DbSchedulingReport_mapping.xml new file mode 100644 index 0000000..b524945 --- /dev/null +++ b/kurt-utility/src/main/resources/hibernate/DbSchedulingReport_mapping.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/hibernate/DbUser_mapping.xml b/kurt-utility/src/main/resources/hibernate/DbUser_mapping.xml new file mode 100644 index 0000000..527feff --- /dev/null +++ b/kurt-utility/src/main/resources/hibernate/DbUser_mapping.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/html/email/template_email_bad_parameters.html b/kurt-utility/src/main/resources/html/email/template_email_bad_parameters.html new file mode 100644 index 0000000..37762dc --- /dev/null +++ b/kurt-utility/src/main/resources/html/email/template_email_bad_parameters.html @@ -0,0 +1,7 @@ +

Notification de fin d'exécution du rapport

+
+Date/heure de lancement: [[POSTING_TIME]]
+Nom du rapport: [[REPORT_NAME]]

+Date/heure de début de génération: [[START_TIME]]

+Date/heure de fin de génération: [[END_TIME]]
+[[ERROR_MESSAGE]]
\ No newline at end of file diff --git a/kurt-utility/src/main/resources/html/email/template_email_failed.html b/kurt-utility/src/main/resources/html/email/template_email_failed.html new file mode 100644 index 0000000..347e21f --- /dev/null +++ b/kurt-utility/src/main/resources/html/email/template_email_failed.html @@ -0,0 +1,7 @@ +

Notification de fin d'exécution du rapport

+
+Date/heure de lancement: [[POSTING_TIME]]
+Nom du rapport: [[REPORT_NAME]]

+Date/heure de début de génération: [[START_TIME]]

+Date/heure de fin de génération: [[END_TIME]]

+[[ERROR_MESSAGE]]
\ No newline at end of file diff --git a/kurt-utility/src/main/resources/html/email/template_email_failed_admin.html b/kurt-utility/src/main/resources/html/email/template_email_failed_admin.html new file mode 100644 index 0000000..347e21f --- /dev/null +++ b/kurt-utility/src/main/resources/html/email/template_email_failed_admin.html @@ -0,0 +1,7 @@ +

Notification de fin d'exécution du rapport

+
+Date/heure de lancement: [[POSTING_TIME]]
+Nom du rapport: [[REPORT_NAME]]

+Date/heure de début de génération: [[START_TIME]]

+Date/heure de fin de génération: [[END_TIME]]

+[[ERROR_MESSAGE]]
\ No newline at end of file diff --git a/kurt-utility/src/main/resources/html/email/template_email_finished.html b/kurt-utility/src/main/resources/html/email/template_email_finished.html new file mode 100644 index 0000000..2f037bf --- /dev/null +++ b/kurt-utility/src/main/resources/html/email/template_email_finished.html @@ -0,0 +1,7 @@ +

Notification de fin d'exécution du rapport

+
+Date/heure de lancement: [[POSTING_TIME]]
+Nom du rapport: [[REPORT_NAME]]

+Date/heure de début de génération: [[START_TIME]]

+Date/heure de fin de génération: [[END_TIME]]
+Lien de récupération du rapport: [[REPORT_LOCATION]]
diff --git a/kurt-utility/src/main/resources/html/email/template_email_posted.html b/kurt-utility/src/main/resources/html/email/template_email_posted.html new file mode 100644 index 0000000..2f3173a --- /dev/null +++ b/kurt-utility/src/main/resources/html/email/template_email_posted.html @@ -0,0 +1,4 @@ +

Détails du lancement effectué

+
+Nom du rapport: [[REPORT_NAME]]
+Nom de la file d'attente: [[QUEUE_NAME]]
\ No newline at end of file diff --git a/kurt-utility/src/main/resources/html/email/template_email_started.html b/kurt-utility/src/main/resources/html/email/template_email_started.html new file mode 100644 index 0000000..f3ac27d --- /dev/null +++ b/kurt-utility/src/main/resources/html/email/template_email_started.html @@ -0,0 +1,5 @@ +

Notification de début d'exécution du rapport

+
+Date/heure de lancement: [[POSTING_TIME]]
+Nom du rapport: [[REPORT_NAME]]
+Date/heure de début de génération: [[START_TIME]]

diff --git a/kurt-utility/src/main/resources/html/error_jsp_page.html b/kurt-utility/src/main/resources/html/error_jsp_page.html new file mode 100644 index 0000000..5fadccb --- /dev/null +++ b/kurt-utility/src/main/resources/html/error_jsp_page.html @@ -0,0 +1,30 @@ + + + [[ERROR_TITLE]] + + + +

+ + The following error occurred on the server side: + +

+ + + + + +
![[ERROR_MESSAGE]]
+ +
+ +
  • Go back to the previous page + +
  • + + \ No newline at end of file diff --git a/kurt-utility/src/main/resources/log4j.properties b/kurt-utility/src/main/resources/log4j.properties new file mode 100644 index 0000000..ed54611 --- /dev/null +++ b/kurt-utility/src/main/resources/log4j.properties @@ -0,0 +1,16 @@ +log4j.logger.com.teamcenter.soa=WARN, stdout +log4j.additivity.com.teamcenter.soa=false +log4j.logger.com.teamcenter.soa.client.Connection=INFO, stdout +log4j.additivity.com.teamcenter.soa.client.Connection=false +log4j.logger.org.apache=WARN, stdout +log4j.logger.httpclient=WARN, stdout + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.threshold=DEBUG +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %c{1}:%L - %m%n + +# Root logger option +log4j.rootLogger=DEBUG, stdout diff --git a/kurt-utility/src/main/resources/quartz.properties b/kurt-utility/src/main/resources/quartz.properties new file mode 100644 index 0000000..6a3eb28 --- /dev/null +++ b/kurt-utility/src/main/resources/quartz.properties @@ -0,0 +1,56 @@ +#========================================================================== +# Configure Main Scheduler Properties +#========================================================================== +org.quartz.scheduler.instanceName: DefaultQuartzScheduler +org.quartz.scheduler.rmi.export: false +org.quartz.scheduler.rmi.proxy: false +org.quartz.scheduler.wrapJobExecutionInUserTransaction: false +org.quartz.scheduler.batchTriggerAcquisitionMaxCount = 100 +org.quartz.scheduler.batchTriggerAcquisitionFireAheadTimeWindow =1 + +# Amount of time in milliseconds that the scheduler will wait before re-queries for available triggers when the scheduler is otherwise idle +org.quartz.scheduler.idleWaitTime: 1000 + +# Amount of time in milliseconds that the scheduler will wait between re-tries when it has detected a loss of connectivity to the database (obviously not meaningful with RamJobStore) +org.quartz.scheduler.dbFailureRetryInterval: 3600 + +#========================================================================== +# Configure ThreadPool +#========================================================================== +org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool + +# Number of threads that are available for concurrent execution of jobs +org.quartz.threadPool.threadCount: 100 + +# Thread priority (Can be any int between Thread.MIN_PRIORITY (which is 1) and Thread.MAX_PRIORITY (which is 10). The default is Thread.NORM_PRIORITY (5)) +org.quartz.threadPool.threadPriority: 5 + +org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true + +#========================================================================== +# Configure JobStore +#========================================================================== +org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX +org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate +org.quartz.jobStore.dataSource=quartzDS +org.quartz.jobStore.tablePrefix=QRTZ_ +org.quartz.jobStore.useProperties = false +org.quartz.jobStore.misfireThreshold = 60000 +org.quartz.jobStore.isClustered = false +org.quartz.jobStore.maxMisfiresToHandleAtATime = 20 +org.quartz.jobStore.dontSetAutoCommitFalse = false + +# "{0}" is replaced during run-time with the TABLE_PREFIX that you configured above and "{1}" with the scheduler's name +org.quartz.jobStore.selectWithLockSQL = "SELECT * FROM {0}LOCKS WHERE SCHED_NAME = {1} AND LOCK_NAME = ? FOR UPDATE" + +org.quartz.jobStore.txIsolationLevelSerializable = false +org.quartz.jobStore.acquireTriggersWithinLock = true + +#========================================================================== +# Configure Datasources +#========================================================================== +org.quartz.dataSource.quartzDS.jndiURL=java:jboss/datasources/QuartzDS +org.quartz.dataSource.quartzDSNoTx.jndiURL=java:jboss/datasources/QuartzDS + +# Be configured to be at least the number of worker threads in the thread pool plus three +org.quartz.dataSource.quartzDS.maxConnections=103 diff --git a/kurt-utility/src/main/resources/reporting.properties b/kurt-utility/src/main/resources/reporting.properties new file mode 100644 index 0000000..ad7243c --- /dev/null +++ b/kurt-utility/src/main/resources/reporting.properties @@ -0,0 +1,99 @@ +# Configuration resolution parameters +com.capgemini.report.common.bom.revisionRule.default=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R01=\ DMA Configuration Interface R01 +com.capgemini.report.common.bom.revisionRule.REPORT_R03=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R05=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R06=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R07=\ DMA Configuration Rapport PU +com.capgemini.report.common.bom.revisionRule.REPORT_R10=\ DMA Configuration Validated +com.capgemini.report.common.bom.revisionRule.REPORT_R11=\ DMA Configuration Mockup Best So Far +com.capgemini.report.common.bom.revisionRule.REPORT_R13=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R15=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_W15=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R16=\ DMA Configuration Validated +com.capgemini.report.common.bom.revisionRule.REPORT_R17=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R19=\ Generic / Generic Assemb R19 +com.capgemini.report.common.bom.revisionRule.REPORT_R20=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R21=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R22=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_W22=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R23=\ DMA Configuration Interface PU R23 +com.capgemini.report.common.bom.revisionRule.REPORT_R24=\ DMA Configuration Validated +com.capgemini.report.common.bom.revisionRule.REPORT_R25=\ DMA Configuration Descriptif R25 +com.capgemini.report.common.bom.revisionRule.REPORT_R26=\ DMA Configuration Interface + +# Report titles +com.capgemini.report.title.REPORT_R01=BOM assemblage PU +com.capgemini.report.title.REPORT_R03=BOM fabrication date +com.capgemini.report.title.REPORT_R05=BOM Multi récepteursPU +com.capgemini.report.title.REPORT_R06=Statut Def et Indus PU +com.capgemini.report.title.REPORT_R07=Comparaison BOM PU +com.capgemini.report.title.REPORT_R10=Documents associés générique +com.capgemini.report.title.REPORT_R11=Mise en maquette et cohérence +com.capgemini.report.title.REPORT_R13=Etat avancement processus +com.capgemini.report.title.REPORT_R15=Fiche article +com.capgemini.report.title.REPORT_W15=Fiche article +com.capgemini.report.title.REPORT_R16=Fiche générique +com.capgemini.report.title.REPORT_R17=Liste documents associés article +com.capgemini.report.title.REPORT_R19=Cas utilisation document +com.capgemini.report.title.REPORT_R20=Gel de UNIT +com.capgemini.report.title.REPORT_R21=Compare Net +com.capgemini.report.title.REPORT_R22=BOM fabrication date PDF eDOC +com.capgemini.report.title.REPORT_W22=BOM fabrication date PDF eDOC +com.capgemini.report.title.REPORT_R23=Bom assemblage PU(s) +com.capgemini.report.title.REPORT_R24=Fiche(s) générique(s) +com.capgemini.report.title.REPORT_R25=Liste des documents des génériques +com.capgemini.report.title.REPORT_R26=Cas d'emploi d'un article +com.capgemini.report.title.REPORT_R27=Extraction des articles de type pièces +com.capgemini.report.title.REPORT_R28=Extraction des repères fonctionnels + +# Report priorities (1=High, 2=Medium, 3=Low) +com.capgemini.report.priority.REPORT_R01=2 +com.capgemini.report.priority.REPORT_R03=1 +com.capgemini.report.priority.REPORT_R05=3 +com.capgemini.report.priority.REPORT_R06=3 +com.capgemini.report.priority.REPORT_R07=3 +com.capgemini.report.priority.REPORT_R10=3 +com.capgemini.report.priority.REPORT_R11=2 +com.capgemini.report.priority.REPORT_R13=2 +com.capgemini.report.priority.REPORT_R15=1 +com.capgemini.report.priority.REPORT_W15=1 +com.capgemini.report.priority.REPORT_R16=1 +com.capgemini.report.priority.REPORT_R17=1 +com.capgemini.report.priority.REPORT_R19=1 +com.capgemini.report.priority.REPORT_R20=2 +com.capgemini.report.priority.REPORT_R21=3 +com.capgemini.report.priority.REPORT_R22=1 +com.capgemini.report.priority.REPORT_W22=1 +com.capgemini.report.priority.REPORT_R23=2 +com.capgemini.report.priority.REPORT_R24=1 +com.capgemini.report.priority.REPORT_R25=1 +com.capgemini.report.priority.REPORT_R26=1 +com.capgemini.report.priority.REPORT_R27=1 +com.capgemini.report.priority.REPORT_R28=1 + +# Report launch type parameters (immediate or delayed) +com.capgemini.report.common.launch.launchType.default=immediate +com.capgemini.report.common.launch.launchType.REPORT_R01=immediate +com.capgemini.report.common.launch.launchType.REPORT_R03=immediate +com.capgemini.report.common.launch.launchType.REPORT_R05=immediate +com.capgemini.report.common.launch.launchType.REPORT_R06=immediate +com.capgemini.report.common.launch.launchType.REPORT_R07=immediate +com.capgemini.report.common.launch.launchType.REPORT_R10=immediate +com.capgemini.report.common.launch.launchType.REPORT_R11=immediate +com.capgemini.report.common.launch.launchType.REPORT_R13=immediate +com.capgemini.report.common.launch.launchType.REPORT_R15=immediate +com.capgemini.report.common.launch.launchType.REPORT_W15=immediate +com.capgemini.report.common.launch.launchType.REPORT_R16=immediate +com.capgemini.report.common.launch.launchType.REPORT_R17=immediate +com.capgemini.report.common.launch.launchType.REPORT_R19=immediate +com.capgemini.report.common.launch.launchType.REPORT_R20=immediate +com.capgemini.report.common.launch.launchType.REPORT_R21=immediate +com.capgemini.report.common.launch.launchType.REPORT_R22=immediate +com.capgemini.report.common.launch.launchType.REPORT_W22=immediate +com.capgemini.report.common.launch.launchType.REPORT_R23=immediate +com.capgemini.report.common.launch.launchType.REPORT_R24=immediate +com.capgemini.report.common.launch.launchType.REPORT_R25=immediate +com.capgemini.report.common.launch.launchType.REPORT_R26=immediate +com.capgemini.report.common.launch.launchType.REPORT_R27=immediate +com.capgemini.report.common.launch.launchType.REPORT_R28=immediate diff --git a/kurt-utility/src/main/resources/xml/policies/r01report/R01_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r01report/R01_policy_full.xml new file mode 100644 index 0000000..b1ca931 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r01report/R01_policy_full.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r01report/R01_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r01report/R01_policy_light.xml new file mode 100644 index 0000000..1354d8a --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r01report/R01_policy_light.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r03report/R03_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r03report/R03_policy_full.xml new file mode 100644 index 0000000..f125d80 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r03report/R03_policy_full.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r03report/R03_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r03report/R03_policy_light.xml new file mode 100644 index 0000000..d46c6f7 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r03report/R03_policy_light.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r07report/R07_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r07report/R07_policy_full.xml new file mode 100644 index 0000000..8a22480 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r07report/R07_policy_full.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r07report/R07_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r07report/R07_policy_light.xml new file mode 100644 index 0000000..1354d8a --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r07report/R07_policy_light.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r10report/R10_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r10report/R10_policy_full.xml new file mode 100644 index 0000000..f5c3508 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r10report/R10_policy_full.xml @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kurt-utility/src/main/resources/xml/policies/r10report/R10_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r10report/R10_policy_light.xml new file mode 100644 index 0000000..1354d8a --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r10report/R10_policy_light.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r11report/R11_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r11report/R11_policy_full.xml new file mode 100644 index 0000000..e0d4588 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r11report/R11_policy_full.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r11report/R11_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r11report/R11_policy_light.xml new file mode 100644 index 0000000..1354d8a --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r11report/R11_policy_light.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r13report/R13_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r13report/R13_policy_full.xml new file mode 100644 index 0000000..b226910 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r13report/R13_policy_full.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r13report/R13_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r13report/R13_policy_light.xml new file mode 100644 index 0000000..c8bcf6e --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r13report/R13_policy_light.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kurt-utility/src/main/resources/xml/policies/r15report/R15_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r15report/R15_policy_full.xml new file mode 100644 index 0000000..123cdad --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r15report/R15_policy_full.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r15report/R15_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r15report/R15_policy_light.xml new file mode 100644 index 0000000..0b516e6 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r15report/R15_policy_light.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r15report/R15_policy_wkf.xml b/kurt-utility/src/main/resources/xml/policies/r15report/R15_policy_wkf.xml new file mode 100644 index 0000000..887ddcb --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r15report/R15_policy_wkf.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r16report/R16_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r16report/R16_policy_full.xml new file mode 100644 index 0000000..05d7552 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r16report/R16_policy_full.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r16report/R16_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r16report/R16_policy_light.xml new file mode 100644 index 0000000..da9a0b7 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r16report/R16_policy_light.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r17report/R17_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r17report/R17_policy_full.xml new file mode 100644 index 0000000..3e4e8af --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r17report/R17_policy_full.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r17report/R17_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r17report/R17_policy_light.xml new file mode 100644 index 0000000..68358af --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r17report/R17_policy_light.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r19report/R19_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r19report/R19_policy_full.xml new file mode 100644 index 0000000..93d848c --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r19report/R19_policy_full.xml @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r19report/R19_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r19report/R19_policy_light.xml new file mode 100644 index 0000000..784a89f --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r19report/R19_policy_light.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r20report/R20_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r20report/R20_policy_full.xml new file mode 100644 index 0000000..f60f99c --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r20report/R20_policy_full.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r20report/R20_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r20report/R20_policy_light.xml new file mode 100644 index 0000000..9bad06b --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r20report/R20_policy_light.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kurt-utility/src/main/resources/xml/policies/r21report/R21_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r21report/R21_policy_full.xml new file mode 100644 index 0000000..4d2a202 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r21report/R21_policy_full.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r21report/R21_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r21report/R21_policy_light.xml new file mode 100644 index 0000000..df6f145 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r21report/R21_policy_light.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r22report/R22_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r22report/R22_policy_full.xml new file mode 100644 index 0000000..d3d09b1 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r22report/R22_policy_full.xml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r22report/R22_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r22report/R22_policy_light.xml new file mode 100644 index 0000000..68358af --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r22report/R22_policy_light.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r22report/R22_policy_wkf.xml b/kurt-utility/src/main/resources/xml/policies/r22report/R22_policy_wkf.xml new file mode 100644 index 0000000..79531e1 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r22report/R22_policy_wkf.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r23report/R23_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r23report/R23_policy_full.xml new file mode 100644 index 0000000..f8338bb --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r23report/R23_policy_full.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r23report/R23_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r23report/R23_policy_light.xml new file mode 100644 index 0000000..1354d8a --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r23report/R23_policy_light.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r24report/R24_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r24report/R24_policy_full.xml new file mode 100644 index 0000000..3336432 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r24report/R24_policy_full.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r24report/R24_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r24report/R24_policy_light.xml new file mode 100644 index 0000000..da9a0b7 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r24report/R24_policy_light.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r25report/R25_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r25report/R25_policy_full.xml new file mode 100644 index 0000000..3336432 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r25report/R25_policy_full.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r25report/R25_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r25report/R25_policy_light.xml new file mode 100644 index 0000000..da9a0b7 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r25report/R25_policy_light.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r26report/R26_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r26report/R26_policy_full.xml new file mode 100644 index 0000000..8d58050 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r26report/R26_policy_full.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kurt-utility/src/main/resources/xml/policies/r26report/R26_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r26report/R26_policy_light.xml new file mode 100644 index 0000000..1354d8a --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r26report/R26_policy_light.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r27report/R27_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r27report/R27_policy_full.xml new file mode 100644 index 0000000..5065e17 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r27report/R27_policy_full.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r27report/R27_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r27report/R27_policy_light.xml new file mode 100644 index 0000000..5065e17 --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r27report/R27_policy_light.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r28report/R28_policy_full.xml b/kurt-utility/src/main/resources/xml/policies/r28report/R28_policy_full.xml new file mode 100644 index 0000000..1bc28bc --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r28report/R28_policy_full.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xml/policies/r28report/R28_policy_light.xml b/kurt-utility/src/main/resources/xml/policies/r28report/R28_policy_light.xml new file mode 100644 index 0000000..1bc28bc --- /dev/null +++ b/kurt-utility/src/main/resources/xml/policies/r28report/R28_policy_light.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/main/resources/xsd/policies.xsd b/kurt-utility/src/main/resources/xsd/policies.xsd new file mode 100644 index 0000000..ab69397 --- /dev/null +++ b/kurt-utility/src/main/resources/xsd/policies.xsd @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kurt-utility/src/main/sh/JenkinsDeploy.bat b/kurt-utility/src/main/sh/JenkinsDeploy.bat new file mode 100644 index 0000000..3b783aa --- /dev/null +++ b/kurt-utility/src/main/sh/JenkinsDeploy.bat @@ -0,0 +1,41 @@ +@echo off +rem The NOPAUSE env variable should be set to avoid prompt confirmations + +rem Define environment variables +set LOG_FILE=%TEMP%/JenkinsDeploy.log +set DEPLOYMENT_DIR=C:\JBoss-7.1\standalone\packages\deploy +set TOKEN_FILE=%DEPLOYMENT_DIR%\deploy.token +cd %DEPLOYMENT_DIR% + +rem Check if an EAR file should be deployed +if exist "%TOKEN_FILE%" ( + del "%TOKEN_FILE%" +) else ( + echo No token detected at %TOKEN_FILE% + pause + exit +) + +rem Reset log file +date /t > %LOG_FILE% + +echo ========================= +echo Jenkins deployment in VAL +echo ========================= + +echo - Undeploy previous EAR +call C:\JBoss-7.1\bin\jboss-cli.bat --connect --command="undeploy snecma-reports.ear" + +echo - Deploy new EAR +call C:\JBoss-7.1\bin\jboss-cli.bat --connect --command="deploy snecma-reports.ear" + +echo - Restart FSC +net stop "Teamcenter FSC Service FSC_pvtc10_tcadmin" >> %LOG_FILE% +net start "Teamcenter FSC Service FSC_pvtc10_tcadmin" >> %LOG_FILE% + +echo - Restart Teamcenter +net stop "TeamcenterServerManager_TC10" >> %LOG_FILE% +net start "TeamcenterServerManager_TC10" >> %LOG_FILE% + +del "%DEPLOYMENT_DIR%\snecma-reports.ear" + diff --git a/kurt-utility/src/main/sh/JenkinsDeploy.bat:Zone.Identifier b/kurt-utility/src/main/sh/JenkinsDeploy.bat:Zone.Identifier new file mode 100644 index 0000000..a45e1ac --- /dev/null +++ b/kurt-utility/src/main/sh/JenkinsDeploy.bat:Zone.Identifier @@ -0,0 +1,2 @@ +[ZoneTransfer] +ZoneId=3 diff --git a/kurt-utility/src/main/sh/JenkinsDeploy.vbs b/kurt-utility/src/main/sh/JenkinsDeploy.vbs new file mode 100644 index 0000000..312dac7 --- /dev/null +++ b/kurt-utility/src/main/sh/JenkinsDeploy.vbs @@ -0,0 +1,8 @@ +' *** Script start *** +Set oShell = CreateObject("WScript.Shell") + +' Lance le script batch en arrière plan pour les tâches planifiées +oShell.Run "C:\JBoss-7.1\standalone\packages\JenkinsDeploy.bat", 0, False + +' Quitte avec le code retour 0 +WScript.Quit 0 diff --git a/kurt-utility/src/main/sh/JenkinsDeploy.vbs:Zone.Identifier b/kurt-utility/src/main/sh/JenkinsDeploy.vbs:Zone.Identifier new file mode 100644 index 0000000..a45e1ac --- /dev/null +++ b/kurt-utility/src/main/sh/JenkinsDeploy.vbs:Zone.Identifier @@ -0,0 +1,2 @@ +[ZoneTransfer] +ZoneId=3 diff --git a/kurt-utility/src/main/sh/jenkins_packaging.sh b/kurt-utility/src/main/sh/jenkins_packaging.sh new file mode 100644 index 0000000..fad1e1f --- /dev/null +++ b/kurt-utility/src/main/sh/jenkins_packaging.sh @@ -0,0 +1,165 @@ +# Reset Kurt packaging temporary folders +# ====================================================== +export TMP_KURT=/tmp/kurt +rm -rf $TMP_KURT + + +export TMP_PACKAGING_KURT=$TMP_KURT/package +export TMP_SOURCE_KURT=$TMP_KURT/source +export TMP_UPLOAD_KURT=$TMP_KURT/upload +export TMP_DEPLOY_KURT=$TMP_KURT/deploy + +mkdir -p $TMP_PACKAGING_KURT +mkdir -p $TMP_SOURCE_KURT +mkdir -p $TMP_UPLOAD_KURT +mkdir -p $TMP_DEPLOY_KURT + +export HOST="10.24.192.36" + +export BUILD_FILENAME="build_infos.txt" +export BUILD_FILE="${TMP_PACKAGING_KURT}/${BUILD_FILENAME}" + +cd /tmp +echo "Build information:" > ${BUILD_FILE} +echo " - Job name: ${JOB_NAME}" >> ${BUILD_FILE} +echo " - Reference: ${BUILD_ID}" >> ${BUILD_FILE} +echo " - Number: ${BUILD_NUMBER}" >> ${BUILD_FILE} +echo " - SVN revision: ${SVN_REVISION}" >> ${BUILD_FILE} +echo " - Jenkins URL: ${BUILD_URL}" >> ${BUILD_FILE} +echo " - Workspace: ${WORKSPACE}" >> ${BUILD_FILE} + +# Group sources +# ====================================================== +cp ${WORKSPACE}/kurt-ejb/target/kurt-ejb-*-sources.jar $TMP_SOURCE_KURT +cp ${WORKSPACE}/jasper/target/jasper-*-sources.jar $TMP_SOURCE_KURT +cp ${WORKSPACE}/kurt-utility/target/kurt-utility-*-sources.jar $TMP_SOURCE_KURT +cp ${WORKSPACE}/kurt-web/target/kurt-web-*-sources.jar $TMP_SOURCE_KURT +cp ${WORKSPACE}/teamcenter/target/teamcenter-*-sources.jar $TMP_SOURCE_KURT + +# Create source package for report WebApp +cd $TMP_SOURCE_KURT +zip -r ${TMP_PACKAGING_KURT}/snecma-reports-${TAG_VERSION}-sources.zip . + +# Deploy policies on Teamcenter +# ====================================================== +cd ${WORKSPACE}/policies +ftp -n ${HOST} < ${TMP_DEPLOY_KURT}/deploy.token +date >> ${TMP_DEPLOY_KURT}/deploy.token +cd $TMP_DEPLOY_KURT +ftp -n ${HOST} < + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kurt-utility/src/test/java/com/capgemini/framework/common/DateHelperTest.java b/kurt-utility/src/test/java/com/capgemini/framework/common/DateHelperTest.java new file mode 100644 index 0000000..6e1cc77 --- /dev/null +++ b/kurt-utility/src/test/java/com/capgemini/framework/common/DateHelperTest.java @@ -0,0 +1,43 @@ +package com.capgemini.framework.common; + +import org.testng.annotations.Test; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Locale; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DateHelperTest { + private static final String PATTERN_YEAR_DASH_MONTH = "^[\\d]{4}-[\\d]{2}$"; // 4 digits, followed by a dash ('-'), followed by two difits, end of String. + private static final String DATE_USER_INPUT = "08-12-2014"; + private static final String EXPECTED_DATE_OUTPUT_US = "08-Dec-2014"; + private static final String DATE_USER_INPUT_EMPTY = ""; + private static final String EXPECTED_DATE_TODAY = "[\\d]{2}-[\\d]{2}-[\\d]{4}"; //25-01-2016 + + @Test + public void testMakeTeamcenterCalendar() { + assertThat(TeamcenterDateFormatter.makeTeamcenterCalendar(DATE_USER_INPUT)).isNotNull(); + assertThat(TeamcenterDateFormatter.makeTeamcenterCalendar(DATE_USER_INPUT_EMPTY)).isNotNull(); + } + + @Test + public void testMakeDateFormatForRequest() { + assertThat(TeamcenterDateFormatter.translateDateFormatForRequest(DATE_USER_INPUT)).isEqualTo(EXPECTED_DATE_OUTPUT_US); + assertThat(TeamcenterDateFormatter.translateDateFormatForRequest(DATE_USER_INPUT_EMPTY)).isEqualTo(getCurrentDate()); + } + + @Test + public void testGetMonthPeriod() { + assertThat(DateHelper.getMonthPeriod()).matches(PATTERN_YEAR_DASH_MONTH); + } + + @Test + public void testGetDate() { + assertThat(DateHelper.getDate()).matches(EXPECTED_DATE_TODAY); + } + + private String getCurrentDate() { + return new SimpleDateFormat("dd-MMM-yyyy", Locale.US).format(Calendar.getInstance().getTime()); + } +} diff --git a/kurt-utility/src/test/java/com/capgemini/framework/common/DoubleFormatterTest.java b/kurt-utility/src/test/java/com/capgemini/framework/common/DoubleFormatterTest.java new file mode 100644 index 0000000..c44a21d --- /dev/null +++ b/kurt-utility/src/test/java/com/capgemini/framework/common/DoubleFormatterTest.java @@ -0,0 +1,52 @@ +package com.capgemini.framework.common; + +import org.testng.annotations.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DoubleFormatterTest { + + @Test + public void toSignificantDigitsTest() { + // Some Integers + tryToFormat(0, 1, "0"); // Simple integer + tryToFormat(20001054, 9, "20001054"); // Simple integer + tryToFormat(20001054, 8, "20001054"); // Simple integer, exact size + tryToFormat(20001054, 3, "20000000"); // Integer, with truncation of non-significant digits + tryToFormat(20001054, 6, "20001100"); // Integer, with rounding of non-significant digits + tryToFormat(-20001054, 9, "-20001054"); // [Negative] Simple integer + tryToFormat(-20001054, 8, "-20001054"); // [Negative] Simple integer, exact size + tryToFormat(-20001054, 3, "-20000000"); // [Negative] Integer, with truncation of non-significant digits + tryToFormat(-20001054, 6, "-20001100"); // [Negative] Integer, with rounding of non-significant digits + + // Some positive powers + tryToFormat(200010.54, 9, "200010.54"); // Simple real number + tryToFormat(200010.54, 8, "200010.54"); // Simple real number, exact size + tryToFormat(200010.54, 3, "200000"); // Real number, with truncation of non-significant digits before the coma + tryToFormat(200010.54, 7, "200010.5"); // Real number, with truncation of non-significant digits after the coma + tryToFormat(200010.56, 7, "200010.6"); // Real number, with rounding of non-significant digits after the coma + tryToFormat(-200010.54, 9, "-200010.54"); // [Negative] Simple real number + tryToFormat(-200010.54, 8, "-200010.54"); // [Negative] Simple real number, exact size + tryToFormat(-200010.54, 3, "-200000"); // [Negative] Real number, with truncation of non-significant digits before the coma [NOTE the zeroes and the coma must go away] + tryToFormat(-200010.54, 7, "-200010.5"); // [Negative] Real number, with truncation of non-significant digits after the coma + tryToFormat(-200010.56, 7, "-200010.6"); // [Negative] Real number, with rounding of non-significant digits after the coma + + // Very high number of significant digits, must still be correct (16 is the max) + tryToFormat(-100.0002005105412345, 16, "-100.0002005105412"); // [Negative] + + // Extremely high number of significant digits, must fail due to Long being too short :D + tryToFormat(-100.0002005105412345, 25, "-100.0002005105412"); // [Negative] + + // Some negative powers + tryToFormat(0.0002, 15, "0.0002"); // Test simple printing + tryToFormat(0.00020051024, 6, "0.00020051"); // Test truncating [NOTE the zeroes after the last digit must go away] + tryToFormat(0.00020051054, 3, "0.000201"); // Test rounding up the last significant digit + tryToFormat(-0.0002, 6, "-0.0002"); // [Negative] Test simple printing + tryToFormat(-0.00020051024, 6, "-0.00020051"); // [Negative] Test truncating [NOTE the zeroes after the last digit must go away] + tryToFormat(-0.00020051054, 3, "-0.000201"); // [Negative] Test rounding up the last significant digit + } + + private void tryToFormat(final double value, final int significantDigits, final String expectedResult) { + assertThat(DoubleFormatter.toSignificantDigits(value, significantDigits)).isEqualTo(expectedResult); + } +} diff --git a/kurt-utility/src/test/java/com/capgemini/framework/common/DynamicErrorTemplateHelperTest.java b/kurt-utility/src/test/java/com/capgemini/framework/common/DynamicErrorTemplateHelperTest.java new file mode 100644 index 0000000..51237d1 --- /dev/null +++ b/kurt-utility/src/test/java/com/capgemini/framework/common/DynamicErrorTemplateHelperTest.java @@ -0,0 +1,14 @@ +package com.capgemini.framework.common; + + +import org.testng.annotations.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DynamicErrorTemplateHelperTest { + + @Test + public void testResolve() { + assertThat("ChangeRequest MOD079600 inconnu.").isEqualTo(new DynamicErrorTemplateHelper("ChangeRequest {} inconnu.", "MOD079600").resolve()); + } +} diff --git a/kurt-utility/src/test/java/com/capgemini/reports/definition/r26report/RangesTest.java b/kurt-utility/src/test/java/com/capgemini/reports/definition/r26report/RangesTest.java new file mode 100644 index 0000000..6ce549d --- /dev/null +++ b/kurt-utility/src/test/java/com/capgemini/reports/definition/r26report/RangesTest.java @@ -0,0 +1,306 @@ +package com.capgemini.reports.definition.r26report; + +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class RangesTest { + + + @Test + public void oneRangeShouldReturnTheRange() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("A", 1, 10)); + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("A")).isEqualTo("1-10"); + } + + @Test + public void oneRangeWithSameBornInfBorneSupShouldReturnTheRange() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("A", 10, 10)); + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("A")).isEqualTo("10"); + } + + @Test + public void twoExcludedRangeShouldReturnTwoRange() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("A", 1, 10)); + rangesList.add(new Range("A", 20, 30)); + + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("A")).isEqualTo("1-10;20-30"); + } + + @Test + public void twoExcludedRangeShouldReturnTwoRange2() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("A", 1, 10)); + rangesList.add(new Range("A", 20, 30)); + rangesList.add(new Range("B", 40, 60)); + + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("A")).isEqualTo("1-10;20-30"); + assertThat(ranges.toString("B")).isEqualTo("40-60"); + } + + @Test + public void twoExcludedRangeShouldReturnTwoRange3() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("A", 1, 10)); + rangesList.add(new Range("A", 20, 30)); + rangesList.add(new Range("B", 40, 50)); + rangesList.add(new Range("B", 60, 80)); + + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("A")).isEqualTo("1-10;20-30"); + assertThat(ranges.toString("B")).isEqualTo("40-50;60-80"); + } + + @Test + public void twoPartiallyIncludedRangeShouldReturnTwoRange() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("A", 1, 20)); + rangesList.add(new Range("A", 10, 30)); + + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("A")).isEqualTo("1-30"); + } + + @Test + public void secondeRangeRangeShouldBeFirstRange() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("A", 1, 100)); + rangesList.add(new Range("A", 200, 400)); + + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("A")).isEqualTo("1-100;200-400"); + } + + @Test + public void twoTotallyIncludedRangeWithSameBorneIfBorneSupShouldReturnThreeRange() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("A", 1, 20)); + rangesList.add(new Range("B", 10, 10)); + + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("A")).isEqualTo("1-9;11-20"); + assertThat(ranges.toString("B")).isEqualTo("10"); + } + + @Test + public void twoTotallyIncludedRangeShouldReturnThreeRange() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("A", 1, 20)); + rangesList.add(new Range("B", 10, 15)); + + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("A")).isEqualTo("1-9;16-20"); + assertThat(ranges.toString("B")).isEqualTo("10-15"); + } + + @Test + public void twoTotallyIncludedWithUpRangeShouldReturnTwoRange() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("A", 1, 2147483646)); + rangesList.add(new Range("B", 10, 2147483646)); + + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("A")).isEqualTo("1-9"); + assertThat(ranges.toString("B")).isEqualTo("10-UP"); + } + + @Test + public void multipleRangeShouldReturnEightRange() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("A", 1, 2147483646)); // 1-UP + rangesList.add(new Range("B", 1, 2147483646)); // 1-UP + rangesList.add(new Range("C", 100, 150)); // 1-99;100-150;151-UP + rangesList.add(new Range("B", 150, 2147483646)); // 1-149;150-UP + rangesList.add(new Range("C", 250, 250)); // 1-99;100-150;151-249;250;251-299;300-UP + rangesList.add(new Range("C", 300, 2147483646)); // 1-99;100-150;151-299;300-UP + rangesList.add(new Range("D", 500, 500)); // 1-99;100-150;151-249;250;251-299;300-499;500;501-UP + + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("A")).isEmpty(); + assertThat(ranges.toString("B")).isEqualTo("1-99;150-249;251-299"); + assertThat(ranges.toString("C")).isEqualTo("100-149;250;300-499;501-UP"); + assertThat(ranges.toString("D")).isEqualTo("500"); + } + + @Test + public void multipleRangeShouldReturnSevenRange() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("A", 1, 2147483646)); // 1-UP + rangesList.add(new Range("B", 1, 2147483646)); // 1-UP + rangesList.add(new Range("C", 100, 160)); // 1-99;100-149;150-160;161-UP + rangesList.add(new Range("B", 150, 2147483646)); // 1-149;150-UP + rangesList.add(new Range("C", 150, 2147483646)); // 1-99;100-149;150-UP + rangesList.add(new Range("C", 250, 250)); // 1-99;100-149;150-249;250;251-UP + rangesList.add(new Range("D", 500, 500)); // 1-99;100-149;150-249;250;251-499;500;501-UP + + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("A")).isEmpty(); + assertThat(ranges.toString("B")).isEqualTo("1-99;150"); + assertThat(ranges.toString("C")).isEqualTo("100-149;151-499;501-UP"); + assertThat(ranges.toString("D")).isEqualTo("500"); + } + + @Test + public void twoTotallyIncludedWithUpRangeShouldReturnThreeRange() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("B", 20, 300)); // 20-49;50-199;301-399;400-UP + rangesList.add(new Range("A", 50, 2147483646)); // 50-UP + rangesList.add(new Range("B", 200, 2147483646)); // 50-199;200-UP + rangesList.add(new Range("B", 400, 2147483646)); // 50-199;200-399;400-UP + + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("A")).isEqualTo("50-199"); + assertThat(ranges.toString("B")).isEqualTo("20-49;200-UP"); + } + + @Test + public void twoTotallyIncludedWithUpRangeShouldReturnThreeRange2() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("C", 600, 600)); // 600 + rangesList.add(new Range("G", 650, 800)); // 600;650-800 + rangesList.add(new Range("G", 700, 700)); // 600;700 + rangesList.add(new Range("I", 900, 900)); // 600;650-800;900;1000-UP + rangesList.add(new Range("G", 1000, 2147483646)); // 600;650-800;1000-UP + + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("C")).isEqualTo("600"); + assertThat(ranges.toString("G")).isEqualTo("650-800;1000-UP"); + assertThat(ranges.toString("I")).isEqualTo("900"); + } + + @Test + public void twoTotallyIncludedWithUpRangeShouldReturnThreeRange3() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("C", 600, 600)); // 600 + rangesList.add(new Range("G", 700, 700)); // 600;700 + rangesList.add(new Range("I", 900, 900)); // 600;700;900;1000-UP + rangesList.add(new Range("G", 1000, 2147483646)); // 600;700;1000-UP + + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("C")).isEqualTo("600"); + assertThat(ranges.toString("G")).isEqualTo("700;1000-UP"); + assertThat(ranges.toString("I")).isEqualTo("900"); + } + + @Test + public void twoTotallyIncludedWithUpRangeShouldReturnThreeRange4() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("C", 600, 600)); // 600 + rangesList.add(new Range("G", 650, 850)); // 600;650-850 + rangesList.add(new Range("G", 700, 700)); // 600;700 + rangesList.add(new Range("G", 800, 800)); // 600;700;800 + rangesList.add(new Range("I", 900, 900)); // 600;650-850;900;1000-UP + rangesList.add(new Range("G", 1000, 2147483646)); // 600;650-850;1000-UP + + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("C")).isEqualTo("600"); + assertThat(ranges.toString("G")).isEqualTo("650-850;1000-UP"); + assertThat(ranges.toString("I")).isEqualTo("900"); + } + + @Test + public void twoTotallyIncludedWithUpRangeShouldReturnThreeRange5() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("G", 1, 2147483646)); // 1-UP + rangesList.add(new Range("G", 300, 300)); // 300;700 + rangesList.add(new Range("G", 700, 700)); // 700 + + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("G")).isEqualTo("1-UP"); + } + + @Test + public void twoTotallyIncludedWithUpRangeShouldReturnThreeRange6() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("A", 600, 600)); // 600 + rangesList.add(new Range("B", 700, 700)); // 600;700 + rangesList.add(new Range("E", 800, 2147483646)); // 600;700;800-899;900;901-999;1000-1099;1100;1101-UP + rangesList.add(new Range("C", 900, 900)); // 600;700;900;1000-UP + rangesList.add(new Range("B", 1000, 2147483646)); // 600;700;1000-UP + rangesList.add(new Range("D", 1100, 1100)); // 600;700;900;1000-1099;1100;1101-UP + + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("A")).isEqualTo("600"); + assertThat(ranges.toString("B")).isEqualTo("700;1000-1099;1101-UP"); + assertThat(ranges.toString("C")).isEqualTo("900"); + assertThat(ranges.toString("D")).isEqualTo("1100"); + assertThat(ranges.toString("E")).isEqualTo("800-899;901-999"); + } + + @Test + public void twoTotallyIncludedWithUpRangeShouldReturnThreeRange7() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("F", 1, 2147483646)); // 600;700;800-UP + rangesList.add(new Range("A", 600, 600)); // 600 + rangesList.add(new Range("G", 600, 600)); // 600;700;800-UP + rangesList.add(new Range("B", 700, 700)); // 600;700 + rangesList.add(new Range("E", 800, 2147483646)); // 600;700;800-UP + rangesList.add(new Range("C", 900, 900)); // 600;700;900;1000-UP + rangesList.add(new Range("B", 1000, 2147483646)); // 600;700;1000-UP + rangesList.add(new Range("D", 1100, 1100)); // 600;700;900;1000-1099;1100;1101-UP + + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("A")).isEmpty(); + assertThat(ranges.toString("B")).isEqualTo("700;1000-1099;1101-UP"); + assertThat(ranges.toString("C")).isEqualTo("900"); + assertThat(ranges.toString("D")).isEqualTo("1100"); + assertThat(ranges.toString("E")).isEqualTo("800-899;901-999"); + assertThat(ranges.toString("F")).isEqualTo("1-599;601-699;701-799"); + assertThat(ranges.toString("G")).isEqualTo("600"); + } + + @Test + public void twoTotallyIncludedWithUpRangeShouldReturnThreeRange8() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("B", 5, 2147483646)); // 5-9;10-UP + rangesList.add(new Range("A", 10, 2147483646)); // 10-UP + rangesList.add(new Range("C", 20, 2147483646)); // 5-9;10-19;20-UP + rangesList.add(new Range("D", 30, 2147483646)); // 5-9;10-19;20-29;30-UP + + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("A")).isEqualTo("10-19"); + assertThat(ranges.toString("B")).isEqualTo("5-9"); + assertThat(ranges.toString("C")).isEqualTo("20-29"); + assertThat(ranges.toString("D")).isEqualTo("30-UP"); + } + + @Test + public void twoTotallyIncludedWithUpRangeShouldReturnThreeRange9() { + List rangesList = new ArrayList<>(); + rangesList.add(new Range("A", 600, 600)); // 1-599;600;601-UP + rangesList.add(new Range("B", 700, 700)); // 1-599;600;601-699;700;701-UP + rangesList.add(new Range("B", 1000, 2147483646));// 1-599;600;601-699;700;701-799;800-849;850-899;900;901-999;1000-UP + rangesList.add(new Range("C", 900, 900)); // 1-599;600;601-699;700;701-799;800-849;850-899;900;901-UP + rangesList.add(new Range("D", 1100, 1100));// 1-599;600;601-699;700;701-799;800-849;850-899;900;901-999;1000-1099;1100;1101-UP + rangesList.add(new Range("E", 800, 2147483646)); // 1-599;600;601-699;700;701-799;800-UP + rangesList.add(new Range("F", 1, 2147483646)); // 1-UP + rangesList.add(new Range("G", 600, 600)); // 1-599;600;601-UP + rangesList.add(new Range("H", 850, 900)); // 1-599;600;601-699;700;701-799;800-849;850-900;901-UP + Collections.sort(rangesList, new Comparator() { + public int compare(Range r1, Range r2) { + return Integer.compare(r1.borneInf(), r2.borneInf()); + } + }); + Ranges ranges = new Ranges(rangesList); + assertThat(ranges.toString("A")).isEmpty(); + assertThat(ranges.toString("B")).isEqualTo("700;1000-1099;1101-UP"); + assertThat(ranges.toString("C")).isEqualTo("900"); + assertThat(ranges.toString("D")).isEqualTo("1100"); + assertThat(ranges.toString("E")).isEqualTo("800-849;901-999"); + assertThat(ranges.toString("F")).isEqualTo("1-599;601-699;701-799"); + assertThat(ranges.toString("G")).isEqualTo("600"); + assertThat(ranges.toString("H")).isEqualTo("850-899"); + } +} \ No newline at end of file diff --git a/kurt-utility/src/test/java/com/capgemini/reports/printing/PrintParametersTest.java b/kurt-utility/src/test/java/com/capgemini/reports/printing/PrintParametersTest.java new file mode 100644 index 0000000..b7a1256 --- /dev/null +++ b/kurt-utility/src/test/java/com/capgemini/reports/printing/PrintParametersTest.java @@ -0,0 +1,36 @@ +package com.capgemini.reports.printing; + +import com.capgemini.framework.common.ResourceHelper; +import com.capgemini.reports.exceptions.FileLoadingException; +import com.capgemini.reports.printing.Printer.PrintFormat; +import net.sf.jasperreports.engine.JRException; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.io.InputStream; + +import static org.assertj.core.api.Assertions.assertThat; + + +public class PrintParametersTest { + + private static final String PARAM_KEY = "Parameter Key"; + private static final String PARAM_VALUE = "Parameter Value"; + private static final String TEMPLATE = "/Jasper/template/dynamic_table/reference.jrxml"; + private static final String FOLDER = "Folder"; + private static final String FILENAME = "Filename"; + + + @Test + public void printParametersTest() throws FileLoadingException, JRException, IOException { + try (InputStream templateIS = ResourceHelper.getResourceAsStream(TEMPLATE)) { + PrintParameters mainReport = new PrintParameters(PrintFormat.PDF, FILENAME, FOLDER, templateIS); + assertThat(mainReport.getTemplate()).isNotNull(); + assertThat(mainReport.getParameters()).isEmpty(); + assertThat(mainReport.hasSubReports()).isFalse(); + + mainReport.addReportParameter(PARAM_KEY, PARAM_VALUE); + assertThat(mainReport.getParameters().get(PARAM_KEY)).isEqualTo(PARAM_VALUE); + } + } +} diff --git a/kurt-utility/src/test/java/com/capgemini/reports/templates/CellTest.java b/kurt-utility/src/test/java/com/capgemini/reports/templates/CellTest.java new file mode 100644 index 0000000..354a49c --- /dev/null +++ b/kurt-utility/src/test/java/com/capgemini/reports/templates/CellTest.java @@ -0,0 +1,148 @@ +package com.capgemini.reports.templates; + +import lombok.extern.slf4j.Slf4j; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + + +@Slf4j +public class CellTest { + + private static final int INITIAL_HEIGHT = 20; + private static final int EXTRA_HEIGHT = 8; + private static final String CONTENT = "Some Content"; + + private final String expectedCell = "" + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n\n " + + "\n " + + "\n "; + + private final String expectedStretchCell = "" + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n\n " + + "\n " + + "\n "; + + private final String expectedGreyCell = "" + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n\n " + + "\n " + + "\n "; + + private final String expectedJustifiedCell = "" + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n " + + "\n\n " + + "\n " + + "\n "; + + @Test + public void testMakeStaticCell() { + Cell cell = Cell.makeStaticCell(CONTENT, INITIAL_HEIGHT, 50, 12, 30, null); + assertThat(cell.isDynamic()).isFalse(); + assertThat(CONTENT).isEqualTo(cell.getContent()); + assertThat(INITIAL_HEIGHT).isEqualTo(cell.getHeight()); + assertThat("50").isEqualTo(cell.getWidth()); + assertThat("12").isEqualTo(cell.getXPosition()); + assertThat("30").isEqualTo(cell.getYPosition()); + assertThat(cell.isStretchWithOverflow()).isFalse(); + } + + @Test + public void testMakeParameterCell() { + Cell cell = Cell.makeParameterCell(CONTENT, INITIAL_HEIGHT, 50, false, 12, 30, null); + assertThat(cell.isDynamic()).isTrue(); + assertThat(cell.isHeader()).isTrue(); + assertThat(CONTENT).isEqualTo(cell.getContent()); + assertThat(INITIAL_HEIGHT).isEqualTo(cell.getHeight()); + assertThat("50").isEqualTo(cell.getWidth()); + assertThat("12").isEqualTo(cell.getXPosition()); + assertThat("30").isEqualTo(cell.getYPosition()); + assertThat(cell.isStretchWithOverflow()).isFalse(); + } + + @Test + public void testCellWithOverflow() { + Cell cell = Cell.makeParameterCell(CONTENT, INITIAL_HEIGHT, 50, true, 12, 30, null); + assertThat(cell.isDynamic()).isTrue(); + assertThat(CONTENT).isEqualTo(cell.getContent()); + assertThat(INITIAL_HEIGHT).isEqualTo(cell.getHeight()); + assertThat("50").isEqualTo(cell.getWidth()); + assertThat("12").isEqualTo(cell.getXPosition()); + assertThat("30").isEqualTo(cell.getYPosition()); + assertThat(cell.isStretchWithOverflow()).isTrue(); + } + + @Test + public void testMakeFieldCell() { + Cell cell = Cell.makeFieldCell(CONTENT, INITIAL_HEIGHT, 50, false, 0, 30, null); + assertThat(cell.isDynamic()).isTrue(); + assertThat(cell.isHeader()).isFalse(); + assertThat(CONTENT).isEqualTo(cell.getContent()); + } + + @Test + public void testMakeCell() { + Cell cell = Cell.makeStaticCell(CONTENT, INITIAL_HEIGHT, 50, 0, 30, null); + assertThat(expectedCell).isEqualTo(cell.makeCell()); + } + + @Test + public void testStretchCell() { + Cell cell = Cell.makeParameterCell(CONTENT, INITIAL_HEIGHT, 50, true, 0, 30, null); + assertThat(expectedStretchCell).isEqualTo(cell.makeCell()); + } + + @Test + public void testAddHeight() { + Cell cell = Cell.makeStaticCell(CONTENT, INITIAL_HEIGHT, 50, 0, 30, null); + assertThat(INITIAL_HEIGHT).isEqualTo(cell.getHeight()); + cell.addHeight(EXTRA_HEIGHT); + assertThat(INITIAL_HEIGHT + EXTRA_HEIGHT).isEqualTo(cell.getHeight()); + } + + @Test + public void testGreyCell() { + Cell cell = Cell.makeStaticCell(CONTENT, INITIAL_HEIGHT, 50, 0, 30, new CellFormat().setColor("#E3E3E3")); + assertThat(expectedGreyCell).isEqualTo(cell.makeCell()); + } + + @Test + public void testJustifiedCell() { + Cell cell = Cell.makeStaticCell(CONTENT, INITIAL_HEIGHT, 50, 0, 30, new CellFormat().setAlignment(Alignment.JUSTIFIED)); + assertThat(expectedJustifiedCell).isEqualTo(cell.makeCell()); + } +} diff --git a/kurt-utility/src/test/java/com/capgemini/reports/templates/ColumnTest.java b/kurt-utility/src/test/java/com/capgemini/reports/templates/ColumnTest.java new file mode 100644 index 0000000..e64ecfa --- /dev/null +++ b/kurt-utility/src/test/java/com/capgemini/reports/templates/ColumnTest.java @@ -0,0 +1,125 @@ +package com.capgemini.reports.templates; + + +import org.testng.annotations.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ColumnTest { + + private static final int CONTENT_HEIGHT = 13; + private static final int HEADER_HEIGHT = 20; + private static final int EXTRA_HEIGHT = 10; + private static final String HEADER_KEY = "HEADER_KEY"; + private static final String CONTENT_KEY = "CONTENT_KEY"; + private static final int WIDTH = 100; + private static final int XPOS = 0; + private static final String COLOR = "#E3E3E3"; + + private static final String EXPECTED_CONTENT = "" /*------------------------------------------------------------------------------------------*/ + + "\n " /*------------------------------------------------------------------------------------------------------*/ + + "\n " /*--------*/ + + "\n "/*---------------------------------------------------------------------------------------*/ + + "\n " /*------------------------------------------------------------------------------*/ + + "\n " /*-----------------------------------------------------------------------------*/ + + "\n "/*----------------------------------------------------------------------------*/ + + "\n " /*----------------------------------------------------------------------------*/ + + "\n " /*-------------------------------------------------------------------------------------------------------*/ + + "\n " /*-------------------------------------------------------------------------------*/ + + "\n\n "/*-------------------------------------------------------------------------------------------------*/ + + "\n "/*--------------------------------*/ + + "\n "; + + private static final String EXPECTED_HEADER = ""/*--------------------------------------------------------------------------------------------*/ + + "\n "/*------------------------------------------------------------------------------------------------------*/ + + "\n " /*---------*/ + + "\n " /*--------------------------------------------------------------------------------------*/ + + "\n "/*-------------------------------------------------------------------------------*/ + + "\n " /*-----------------------------------------------------------------------------*/ + + "\n "/*----------------------------------------------------------------------------*/ + + "\n " /*----------------------------------------------------------------------------*/ + + "\n " /*-------------------------------------------------------------------------------------------------------*/ + + "\n " /*-------------------------------------------------------------------------------*/ + + "\n\n "/*-------------------------------------------------------------------------------------------------*/ + + "\n "/*-------------------------------------------------------------------*/ + + "\n "; + + private static final String EXPECTED_GREY_HEADER = ""/*---------------------------------------------------------------------------------------*/ + + "\n " /*-----------------------------------------------------------------------------------------------------*/ + + "\n "/*-------------------------------------------------------------------------------------------*/ + + "\n "/*---------------------------------------------------------------------------------------*/ + + "\n "/*-------------------------------------------------------------------------------*/ + + "\n " /*-----------------------------------------------------------------------------*/ + + "\n "/*----------------------------------------------------------------------------*/ + + "\n " /*----------------------------------------------------------------------------*/ + + "\n " /*-------------------------------------------------------------------------------------------------------*/ + + "\n " /*-------------------------------------------------------------------------------*/ + + "\n\n "/*-------------------------------------------------------------------------------------------------*/ + + "\n " /*------------------------------------------------------------------*/ + + "\n "; + + private static final String EXPECTED_EXTRA_HIGH_HEADER = "" /*--------------------------------------------------------------------------------*/ + + "\n " /*-----------------------------------------------------------------------------------------------------*/ + + "\n " /*---------------------------------------------------------------------------------------------------------------------------*/ + + "\n " /*--------------------------------------------------------------------------------------*/ + + "\n " /*------------------------------------------------------------------------------*/ + + "\n " /*-----------------------------------------------------------------------------*/ + + "\n " /*---------------------------------------------------------------------------*/ + + "\n "/*-----------------------------------------------------------------------------*/ + + "\n " /*-------------------------------------------------------------------------------------------------------*/ + + "\n " /*-------------------------------------------------------------------------------*/ + + "\n\n "/*-------------------------------------------------------------------------------------------------*/ + + "\n " /*------------------------------------------------------------------*/ + + "\n "; /*---------------------------------------------------------------------------------------------------*/ + + @Test + public void testColumnField() { + Column col = new Column(CONTENT_KEY, WIDTH, XPOS, false, CONTENT_HEIGHT, null); + assertThat(col.makeContent()).isEqualTo(EXPECTED_CONTENT); + assertThat(col.makeHeaders()).isEmpty(); + } + + @Test + public void testAddHeader() { + Column col = new Column(CONTENT_KEY, WIDTH, XPOS, false, HEADER_HEIGHT, null); + String headerStr = col.makeHeaders(); + assertThat(headerStr).isEmpty(); + col.addHeader(HEADER_KEY, false, HEADER_HEIGHT, false, null); + headerStr = col.makeHeaders(); + assertThat(headerStr).isEqualTo(EXPECTED_HEADER); + } + + @Test + public void testGreyHeader() { + Column col = new Column(CONTENT_KEY, WIDTH, XPOS, false, HEADER_HEIGHT, null); + col.addHeader(HEADER_KEY, false, HEADER_HEIGHT, false, new CellFormat().setColor(COLOR)); + String headerStr = col.makeHeaders(); + assertThat(headerStr).isEqualTo(EXPECTED_GREY_HEADER); + } + + @Test + public void testAddToPreviousHeaderCellHeight() { + Column col = new Column(CONTENT_KEY, WIDTH, XPOS, false, HEADER_HEIGHT, null); + col.addHeader(HEADER_KEY, false, HEADER_HEIGHT, false, null); + col.addToPreviousHeaderCellHeight(EXTRA_HEIGHT); + assertThat(col.makeHeaders()).isEqualTo(EXPECTED_EXTRA_HIGH_HEADER); + } + + @Test + public void testGetParametersDeclaration() { + // No parameter yet (No header) + Column col = new Column(CONTENT_KEY, WIDTH, XPOS, false, HEADER_HEIGHT, null); + assertThat(col.getParametersDeclaration()).isEmpty(); + + // Still no parameters (header is static) + col.addHeader(HEADER_KEY, false, HEADER_HEIGHT, false, null); + assertThat(col.getParametersDeclaration()).isEmpty(); + + // Now there is a parameter + col.addHeader(HEADER_KEY, true, HEADER_HEIGHT, false, null); + String parametersDeclaration = col.getParametersDeclaration(); + assertThat(parametersDeclaration).isEqualTo("\n "); + } +} diff --git a/kurt-utility/src/test/java/com/capgemini/reports/templates/DynamicGridTemplateBuilderTest.java b/kurt-utility/src/test/java/com/capgemini/reports/templates/DynamicGridTemplateBuilderTest.java new file mode 100644 index 0000000..afddc98 --- /dev/null +++ b/kurt-utility/src/test/java/com/capgemini/reports/templates/DynamicGridTemplateBuilderTest.java @@ -0,0 +1,69 @@ +package com.capgemini.reports.templates; + +import com.capgemini.framework.common.ResourceHelper; +import com.capgemini.reports.exceptions.FileLoadingException; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.jasper.compilers.JasperCompiler; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperReport; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + + +public class DynamicGridTemplateBuilderTest { + + private static final String COLOR = "#E3E3E3"; + + @Test + public void generateCodeTest() throws JRException, FileLoadingException, InvalidInputException { + // iInitialise the data + String refContent = ResourceHelper.getResourceContent("/Jasper/template/dynamic_table/reference.jrxml"); + List header1 = new ArrayList<>(); + List header2 = new ArrayList<>(); + List dynamicHeader = new ArrayList<>(); + List widths = new ArrayList<>(); + List keys = new ArrayList<>(); + + Map aContentLine = new HashMap<>(); + Map parameters = new HashMap<>(); + for (int col = 0; col < 5; col++) { + if (col == 0) { + header1.add("Top Left"); + header2.add("Line Headers"); + dynamicHeader.add(false); + widths.add(200); + String key = "ROW_HEADER" + col; + keys.add(key); + aContentLine.put(key, "Row Number 0"); + } + else { + String headerKey = "COL_HEADER" + col; + header1.add(headerKey); + parameters.put(headerKey, "Column Number " + col); + header2.add(null); // Merge with the above + dynamicHeader.add(true); + widths.add(50); + String contentKey = "COL" + col; + keys.add(contentKey); + aContentLine.put(contentKey, "Value " + col); + } + } + + // Build the template + DynamicGridTemplateBuilder template = new DynamicGridTemplateBuilder(widths, keys, null, null, 13); + template.addHeaderLine(13, header1, dynamicHeader, new CellFormat().setColor(COLOR), null); + template.addHeaderLine(26, header2, dynamicHeader, new CellFormat().setColor(COLOR), null); + String generatedTemplate = template.generateCode(); + assertThat(refContent).isEqualTo(generatedTemplate); + + // Compile + JasperReport compiledTemplate = JasperCompiler.compile(generatedTemplate); + assertThat(compiledTemplate).isNotNull(); + } +} diff --git a/kurt-utility/src/test/resources/Jasper/template/dynamic_table/reference.jrxml b/kurt-utility/src/test/resources/Jasper/template/dynamic_table/reference.jrxml new file mode 100644 index 0000000..c1a4d6a --- /dev/null +++ b/kurt-utility/src/test/resources/Jasper/template/dynamic_table/reference.jrxml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/test/resources/Jasper/template/dynamic_table/template.jrxml b/kurt-utility/src/test/resources/Jasper/template/dynamic_table/template.jrxml new file mode 100644 index 0000000..509c616 --- /dev/null +++ b/kurt-utility/src/test/resources/Jasper/template/dynamic_table/template.jrxml @@ -0,0 +1,23 @@ + + + [[PARAMETERS]] + + + [[FIELDS]] + + + + + [[HEADERS]] + + + + [[CONTENT]] + + + diff --git a/kurt-utility/src/test/resources/hibernate.cfg.xml b/kurt-utility/src/test/resources/hibernate.cfg.xml new file mode 100644 index 0000000..be6101c --- /dev/null +++ b/kurt-utility/src/test/resources/hibernate.cfg.xml @@ -0,0 +1,49 @@ + + + + + + + + + org.hibernate.dialect.Oracle10gDialect + oracle.jdbc.OracleDriver + jdbc:oracle:thin:@10.24.192.36:1521:TC + PLIC + PLIC + PLIC + + + 1 + + + org.hibernate.cache.NoCacheProvider + + org.hibernate.transaction.JDBCTransactionFactory + + + thread + + + false + + + update + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/test/resources/html/email/template_email_bad_parameters.html b/kurt-utility/src/test/resources/html/email/template_email_bad_parameters.html new file mode 100644 index 0000000..5aa7682 --- /dev/null +++ b/kurt-utility/src/test/resources/html/email/template_email_bad_parameters.html @@ -0,0 +1,8 @@ +

    Notification de fin d'exécution du rapport

    +
    +Date/heure de lancement: [[POSTING_TIME]]
    +Nom du rapport: [[REPORT_NAME]]

    +Date/heure de début de génération: [[START_TIME]]

    +Date/heure de fin de génération: [[END_TIME]]
    +Aucune donnée n'a pu être extraite: Vérifier vos cirtères d'impression.
    +[[ERROR_MESSAGE]]
    \ No newline at end of file diff --git a/kurt-utility/src/test/resources/html/email/template_email_failed.html b/kurt-utility/src/test/resources/html/email/template_email_failed.html new file mode 100644 index 0000000..9fca525 --- /dev/null +++ b/kurt-utility/src/test/resources/html/email/template_email_failed.html @@ -0,0 +1,7 @@ +

    Ce rapport s'est terminé en erreur

    +
    +Date/heure de lancement: [[POSTING_TIME]]
    +Nom du rapport: [[REPORT_NAME]]

    +Date/heure de début de génération: [[START_TIME]]

    +Date/heure de fin de génération: [[END_TIME]]

    +[[ERROR_MESSAGE]]
    \ No newline at end of file diff --git a/kurt-utility/src/test/resources/html/email/template_email_failed_admin.html b/kurt-utility/src/test/resources/html/email/template_email_failed_admin.html new file mode 100644 index 0000000..347e21f --- /dev/null +++ b/kurt-utility/src/test/resources/html/email/template_email_failed_admin.html @@ -0,0 +1,7 @@ +

    Notification de fin d'exécution du rapport

    +
    +Date/heure de lancement: [[POSTING_TIME]]
    +Nom du rapport: [[REPORT_NAME]]

    +Date/heure de début de génération: [[START_TIME]]

    +Date/heure de fin de génération: [[END_TIME]]

    +[[ERROR_MESSAGE]]
    \ No newline at end of file diff --git a/kurt-utility/src/test/resources/html/email/template_email_finished.html b/kurt-utility/src/test/resources/html/email/template_email_finished.html new file mode 100644 index 0000000..2f037bf --- /dev/null +++ b/kurt-utility/src/test/resources/html/email/template_email_finished.html @@ -0,0 +1,7 @@ +

    Notification de fin d'exécution du rapport

    +
    +Date/heure de lancement: [[POSTING_TIME]]
    +Nom du rapport: [[REPORT_NAME]]

    +Date/heure de début de génération: [[START_TIME]]

    +Date/heure de fin de génération: [[END_TIME]]
    +Lien de récupération du rapport: [[REPORT_LOCATION]]
    diff --git a/kurt-utility/src/test/resources/html/email/template_email_posted.html b/kurt-utility/src/test/resources/html/email/template_email_posted.html new file mode 100644 index 0000000..2f3173a --- /dev/null +++ b/kurt-utility/src/test/resources/html/email/template_email_posted.html @@ -0,0 +1,4 @@ +

    Détails du lancement effectué

    +
    +Nom du rapport: [[REPORT_NAME]]
    +Nom de la file d'attente: [[QUEUE_NAME]]
    \ No newline at end of file diff --git a/kurt-utility/src/test/resources/html/email/template_email_started.html b/kurt-utility/src/test/resources/html/email/template_email_started.html new file mode 100644 index 0000000..f3ac27d --- /dev/null +++ b/kurt-utility/src/test/resources/html/email/template_email_started.html @@ -0,0 +1,5 @@ +

    Notification de début d'exécution du rapport

    +
    +Date/heure de lancement: [[POSTING_TIME]]
    +Nom du rapport: [[REPORT_NAME]]
    +Date/heure de début de génération: [[START_TIME]]

    diff --git a/kurt-utility/src/test/resources/log4j.properties b/kurt-utility/src/test/resources/log4j.properties new file mode 100644 index 0000000..8f372cd --- /dev/null +++ b/kurt-utility/src/test/resources/log4j.properties @@ -0,0 +1,13 @@ +log4j.logger.com.teamcenter.soa=WARN +log4j.logger.org.apache=WARN +log4j.logger.httpclient=WARN + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.threshold=DEBUG +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %c{1}:%L - %m%n + +# Root logger option +log4j.rootLogger=DEBUG, stdout diff --git a/kurt-utility/src/test/resources/xml/policies/PoliciesDomParserTest.xml b/kurt-utility/src/test/resources/xml/policies/PoliciesDomParserTest.xml new file mode 100644 index 0000000..735c1ee --- /dev/null +++ b/kurt-utility/src/test/resources/xml/policies/PoliciesDomParserTest.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/test/resources/xml/policies/bom_policy.xml b/kurt-utility/src/test/resources/xml/policies/bom_policy.xml new file mode 100644 index 0000000..761b32a --- /dev/null +++ b/kurt-utility/src/test/resources/xml/policies/bom_policy.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kurt-utility/src/test/resources/xml/policies/policy_full.xml b/kurt-utility/src/test/resources/xml/policies/policy_full.xml new file mode 100644 index 0000000..17d09f6 --- /dev/null +++ b/kurt-utility/src/test/resources/xml/policies/policy_full.xml @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kurt-utility/src/test/resources/xml/policies/policy_light.xml b/kurt-utility/src/test/resources/xml/policies/policy_light.xml new file mode 100644 index 0000000..1354d8a --- /dev/null +++ b/kurt-utility/src/test/resources/xml/policies/policy_light.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/test/resources/xml/policies/test_policy.xml b/kurt-utility/src/test/resources/xml/policies/test_policy.xml new file mode 100644 index 0000000..6c3eadd --- /dev/null +++ b/kurt-utility/src/test/resources/xml/policies/test_policy.xml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/test/resources/xml/ref/MultiStructureServiceCallerTest_item.xml b/kurt-utility/src/test/resources/xml/ref/MultiStructureServiceCallerTest_item.xml new file mode 100644 index 0000000..aa88d29 --- /dev/null +++ b/kurt-utility/src/test/resources/xml/ref/MultiStructureServiceCallerTest_item.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kurt-utility/src/test/resources/xml/ref/MultiStructureServiceCallerTest_item_revision.xml b/kurt-utility/src/test/resources/xml/ref/MultiStructureServiceCallerTest_item_revision.xml new file mode 100644 index 0000000..61544df --- /dev/null +++ b/kurt-utility/src/test/resources/xml/ref/MultiStructureServiceCallerTest_item_revision.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kurt-utility/src/test/resources/xml/ref/StructureServiceCallerTest_mono.xml b/kurt-utility/src/test/resources/xml/ref/StructureServiceCallerTest_mono.xml new file mode 100644 index 0000000..014572c --- /dev/null +++ b/kurt-utility/src/test/resources/xml/ref/StructureServiceCallerTest_mono.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/kurt-utility/src/test/resources/xml/ref/StructureServiceCallerTest_multi.xml b/kurt-utility/src/test/resources/xml/ref/StructureServiceCallerTest_multi.xml new file mode 100644 index 0000000..8658eda --- /dev/null +++ b/kurt-utility/src/test/resources/xml/ref/StructureServiceCallerTest_multi.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/test/resources/xml/ref/TripleStructureServiceCallerTest_item.xml b/kurt-utility/src/test/resources/xml/ref/TripleStructureServiceCallerTest_item.xml new file mode 100644 index 0000000..54187d9 --- /dev/null +++ b/kurt-utility/src/test/resources/xml/ref/TripleStructureServiceCallerTest_item.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/kurt-utility/src/test/resources/xml/ref/TripleStructureServiceCallerTest_item_revision.xml b/kurt-utility/src/test/resources/xml/ref/TripleStructureServiceCallerTest_item_revision.xml new file mode 100644 index 0000000..e69de29 diff --git a/kurt-utility/src/val/java/com/capgemini/reports/definition/r01report/Test_R01.java b/kurt-utility/src/val/java/com/capgemini/reports/definition/r01report/Test_R01.java new file mode 100644 index 0000000..e5ddd74 --- /dev/null +++ b/kurt-utility/src/val/java/com/capgemini/reports/definition/r01report/Test_R01.java @@ -0,0 +1,106 @@ +package com.capgemini.reports.definition.r01report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.builder.R01Builder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.DataFormatter; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.assertj.core.api.SoftAssertions; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Optional; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +@Slf4j +public class Test_R01 { + private static final TcSession session = new TcSession(); + private SoftAssertions softAssert = new SoftAssertions(); + // Dossier parent du fichier de référence + private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input"; + // Sous-dossier du fichier de référence + private static final String SPECIFIC_INPUT_FOLDER = "r01"; + // Dossier de stockage temporaire des fichiers générés initialement + private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output"; + // Type de fichier traités + private static final String SUFFIX = ".xlsx"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r01report/R01_policy_full.xml"); + private Properties localproperties; + + + @BeforeClass + public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + localproperties = new Properties(); + localproperties.load(getClass().getResourceAsStream("/reporting.properties")); + } + + @AfterClass + public void logout() { + session.close(); + } + + //@BeforeMethod + //TODO : Supprimer xls files dans Generated, checker Tempfile TempDirectory + + + @Parameters({"productID", "unit", "monomulti", "effectivityDate", "genericAssemb", "generic", "refFile"}) + @Test + public void test01(String productID, Integer unit, String monomulti, @Optional String + effectivityDate, @Optional String genericAssemb, @Optional String generic, String refFile) throws + KurtException, IOException { + // Génération du rapport de test + Map data = new HashMap<>(); + data.put(ReportCriteriaEnum.PRODUCT, productID); + data.put(ReportCriteriaEnum.UNIT, unit.toString()); + data.put(ReportCriteriaEnum.MONO_MULTI, monomulti); + data.put(ReportCriteriaEnum.GENERIC, generic); + data.put(ReportCriteriaEnum.GENERIC_ASSEMB, genericAssemb); + data.put(ReportCriteriaEnum.EFFECTIVITY_DATE, effectivityDate); + + ExecutionR01 execution = new R01Builder().build(data); + new DataReportPreparatorR01().print(session, execution, new ImmediateExecutionStrategy()); + + try (FileInputStream fileInput = new FileInputStream(new File((localproperties.getProperty(INPUT_FOLDER)) + SPECIFIC_INPUT_FOLDER + "/" + refFile)); + FileInputStream fileOutput = new FileInputStream(new File(localproperties.getProperty(TEMPORARY_OUTPUT_FOLDER) + execution.getFileNameOnDisc() + SUFFIX))) { + + XSSFWorkbook workbookRef = new XSSFWorkbook(fileInput); + XSSFWorkbook workbookGen = new XSSFWorkbook(fileOutput); + DataFormatter df = new DataFormatter(); + + softAssert.assertThat(workbookRef.getNumberOfSheets()).isEqualTo(workbookGen.getNumberOfSheets()); + for (int h = 0; h < workbookGen.getNumberOfSheets() && h < workbookRef.getNumberOfSheets(); h++) { + // Un fichier excel est composé de plusieurs feuilles, on y accède de la manière suivante + XSSFSheet sheetRef = workbookRef.getSheetAt(h); + XSSFSheet sheetGen = workbookGen.getSheetAt(h); + for (int i = 0; i <= sheetRef.getLastRowNum(); i++) { + XSSFRow rowRef = sheetRef.getRow(i); + XSSFRow rowGen = sheetGen.getRow(i); + for (int j = 0; j <= rowRef.getLastCellNum(); j++) { + XSSFCell cellRef = rowRef.getCell(j); + XSSFCell cellGen = rowGen.getCell(j); + softAssert.assertThat(df.formatCellValue(cellGen)).isEqualTo(df.formatCellValue(cellRef)); + } + } + } + } + softAssert.assertAll(); + } +} diff --git a/kurt-utility/src/val/java/com/capgemini/reports/definition/r03report/Test_R03.java b/kurt-utility/src/val/java/com/capgemini/reports/definition/r03report/Test_R03.java new file mode 100644 index 0000000..405f224 --- /dev/null +++ b/kurt-utility/src/val/java/com/capgemini/reports/definition/r03report/Test_R03.java @@ -0,0 +1,103 @@ +package com.capgemini.reports.definition.r03report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.builder.R03Builder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.DataFormatter; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.assertj.core.api.SoftAssertions; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + + +@Slf4j +public class Test_R03 { + private static final TcSession session = new TcSession(); + private SoftAssertions softAssert = new SoftAssertions(); + // Dossier parent du fichier de référence + private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input"; + // Sous-dossier du fichier de référence + private static final String SPECIFIC_INPUT_FOLDER = "r03"; + // Dossier de stockage temporaire des fichiers générés initialement + private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output"; + // Type de fichier traités + private static final String SUFFIX = ".xlsx"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r03report/R03_policy_full.xml"); + private Properties localproperties; + + + @BeforeClass + public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + localproperties = new Properties(); + localproperties.load(getClass().getResourceAsStream("/reporting.properties")); + } + + @AfterClass + public void logout() { + session.close(); + } + + //@BeforeMethod + //TODO : Supprimer xls files dans Generated, checker Tempfile TempDirectory + + + @Parameters({"partId", "partRev", "refFile"}) + @Test + + + public void test03(String partId, String partRev, String refFile) throws KurtException, IOException { + + // Génération du rapport de test + Map data = new HashMap<>(); + data.put(ReportCriteriaEnum.PART_ID, partId); + data.put(ReportCriteriaEnum.PART_REVISION, partRev); + + ExecutionR03 execution = new R03Builder().build(data); + new DataReportPreparatorR03().print(session, execution, new ImmediateExecutionStrategy()); + + try (FileInputStream fileInput = new FileInputStream(new File((localproperties.getProperty(INPUT_FOLDER)) + SPECIFIC_INPUT_FOLDER + "/" + refFile)); + FileInputStream fileOutput = new FileInputStream(new File(localproperties.getProperty(TEMPORARY_OUTPUT_FOLDER) + execution.getFileNameOnDisc() + SUFFIX))) { + + XSSFWorkbook workbookRef = new XSSFWorkbook(fileInput); + XSSFWorkbook workbookGen = new XSSFWorkbook(fileOutput); + DataFormatter df = new DataFormatter(); + + softAssert.assertThat(workbookRef.getNumberOfSheets()).isEqualTo(workbookGen.getNumberOfSheets()); + for (int h = 0; h < workbookGen.getNumberOfSheets() && h < workbookRef.getNumberOfSheets(); h++) { + // Un fichier excel est composé de plusieurs feuilles, on y accède de la manière suivante + XSSFSheet sheetRef = workbookRef.getSheetAt(h); + XSSFSheet sheetGen = workbookGen.getSheetAt(h); + for (int i = 0; i <= sheetRef.getLastRowNum(); i++) { + XSSFRow rowRef = sheetRef.getRow(i); + XSSFRow rowGen = sheetGen.getRow(i); + for (int j = 0; j <= rowRef.getLastCellNum(); j++) { + XSSFCell cellRef = rowRef.getCell(j); + XSSFCell cellGen = rowGen.getCell(j); + softAssert.assertThat(df.formatCellValue(cellGen)).isEqualTo(df.formatCellValue(cellRef)); + } + } + } + } + softAssert.assertAll(); + } +} \ No newline at end of file diff --git a/kurt-utility/src/val/java/com/capgemini/reports/definition/r07report/Test_R07.java b/kurt-utility/src/val/java/com/capgemini/reports/definition/r07report/Test_R07.java new file mode 100644 index 0000000..3bd3327 --- /dev/null +++ b/kurt-utility/src/val/java/com/capgemini/reports/definition/r07report/Test_R07.java @@ -0,0 +1,108 @@ +package com.capgemini.reports.definition.r07report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.builder.R07Builder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r07report.data.DataReportPreparatorR07; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.DataFormatter; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.assertj.core.api.SoftAssertions; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Optional; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + + +@Slf4j +public class Test_R07 { + private static final TcSession session = new TcSession(); + private SoftAssertions softAssert = new SoftAssertions(); + // Dossier parent du fichier de référence + private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input"; + // Sous-dossier du fichier de référence + private static final String SPECIFIC_INPUT_FOLDER = "r07"; + // Dossier de stockage temporaire des fichiers générés initialement + private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output"; + // Type de fichier traités + private static final String SUFFIX = ".xlsx"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r07report/R07_policy_full.xml"); + private Properties localproperties; + + + @BeforeClass + public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + localproperties = new Properties(); + localproperties.load(getClass().getResourceAsStream("/reporting.properties")); + } + + @AfterClass + public void logout() { + session.close(); + } + + //@BeforeMethod + //TODO : Supprimer xls files dans Generated, checker Tempfile TempDirectory + + + @Parameters({"productID", "unit1", "unit2", "generic", "genericAssemb", "refFile"}) + @Test + public void test07(String productID, String unit1, String unit2, + @Optional String generic, @Optional String genericAssemb, + String refFile) throws KurtException, IOException { + + // Génération du rapport de test + Map data = new HashMap<>(); + data.put(ReportCriteriaEnum.PRODUCT, productID); + data.put(ReportCriteriaEnum.UNIT_CONFIGURATION_1, unit1); + data.put(ReportCriteriaEnum.UNIT_CONFIGURATION_2, unit2); + data.put(ReportCriteriaEnum.GENERIC, generic); + data.put(ReportCriteriaEnum.GENERIC_ASSEMB, genericAssemb); + + ExecutionR07 execution = new R07Builder().build(data); + new DataReportPreparatorR07().print(session, execution, new ImmediateExecutionStrategy()); + + try (FileInputStream fileInput = new FileInputStream(new File((localproperties.getProperty(INPUT_FOLDER)) + SPECIFIC_INPUT_FOLDER + "/" + refFile)); + FileInputStream fileOutput = new FileInputStream(new File(localproperties.getProperty(TEMPORARY_OUTPUT_FOLDER) + execution.getFileNameOnDisc() + SUFFIX))) { + + XSSFWorkbook workbookRef = new XSSFWorkbook(fileInput); + XSSFWorkbook workbookGen = new XSSFWorkbook(fileOutput); + DataFormatter df = new DataFormatter(); + + softAssert.assertThat(workbookRef.getNumberOfSheets()).isEqualTo(workbookGen.getNumberOfSheets()); + for (int h = 0; h < workbookGen.getNumberOfSheets() && h < workbookRef.getNumberOfSheets(); h++) { + // Un fichier excel est composé de plusieurs feuilles, on y accède de la manière suivante + XSSFSheet sheetRef = workbookRef.getSheetAt(h); + XSSFSheet sheetGen = workbookGen.getSheetAt(h); + for (int i = 2; i <= sheetRef.getLastRowNum(); i++) { + XSSFRow rowRef = sheetRef.getRow(i); + XSSFRow rowGen = sheetGen.getRow(i); + for (int j = 1; j <= rowRef.getLastCellNum(); j++) { + XSSFCell cellRef = rowRef.getCell(j); + XSSFCell cellGen = rowGen.getCell(j); + softAssert.assertThat(df.formatCellValue(cellGen)).isEqualTo(df.formatCellValue(cellRef)); + } + } + } + } + softAssert.assertAll(); + } +} diff --git a/kurt-utility/src/val/java/com/capgemini/reports/definition/r10report/Test_R10.java b/kurt-utility/src/val/java/com/capgemini/reports/definition/r10report/Test_R10.java new file mode 100644 index 0000000..9857a60 --- /dev/null +++ b/kurt-utility/src/val/java/com/capgemini/reports/definition/r10report/Test_R10.java @@ -0,0 +1,115 @@ +package com.capgemini.reports.definition.r10report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.builder.R10Builder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.DataFormatter; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.assertj.core.api.SoftAssertions; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Optional; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + + +@Slf4j +public class Test_R10 { + private static final TcSession session = new TcSession(); + private SoftAssertions softAssert = new SoftAssertions(); + // Dossier parent du fichier de référence + private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input"; + // Sous-dossier du fichier de référence + private static final String SPECIFIC_INPUT_FOLDER = "r10"; + // Dossier de stockage temporaire des fichiers générés initialement + private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output"; + // Dossier de stockage final des fichiers + private static final String RECORDS_FOLDER = "com.capgemini.report.location.default.records"; + // Type de fichier traités + private static final String SUFFIX = ".xlsx"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r10report/R10_policy_full.xml"); + private Properties localproperties; + + + @BeforeClass + public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + localproperties = new Properties(); + localproperties.load(getClass().getResourceAsStream("/reporting.properties")); + } + + @AfterClass + public void logout() { + session.close(); + } + + //@BeforeMethod + //TODO : Supprimer xls files dans Generated, checker Tempfile TempDirectory + + + @Parameters({"productID", "unit", "monomulti", "generic", "genericAssemb", "effectivity", "refFile"}) + @Test + + public void test10(String productID, String unit, String monomulti, + @Optional String generic, @Optional String genericAssemb, @Optional String effectivity, String refFile) + throws KurtException, IOException { + + // Génération du rapport de test + Map data = new HashMap(); + data.put(ReportCriteriaEnum.PRODUCT, productID); + data.put(ReportCriteriaEnum.UNIT, unit); + data.put(ReportCriteriaEnum.MONO_MULTI, monomulti); + data.put(ReportCriteriaEnum.GENERIC, generic); + data.put(ReportCriteriaEnum.GENERIC_ASSEMB, genericAssemb); + data.put(ReportCriteriaEnum.EFFECTIVITY_DATE, effectivity); + + + ExecutionR10 execution = new R10Builder().build(data); + String print = new DataReportPreparatorR10().print(session, execution, new ImmediateExecutionStrategy()); + + try (FileInputStream fileInput = new FileInputStream(new File((localproperties.getProperty(INPUT_FOLDER)) + SPECIFIC_INPUT_FOLDER + "/" + refFile)); + FileInputStream fileOutput = new FileInputStream(new File(localproperties.getProperty(TEMPORARY_OUTPUT_FOLDER) + execution.getFileNameOnDisc() + SUFFIX))) { + + + XSSFWorkbook workbookRef = new XSSFWorkbook(fileInput); + XSSFWorkbook workbookGen = new XSSFWorkbook(fileOutput); + DataFormatter df = new DataFormatter(); + + softAssert.assertThat(workbookRef.getNumberOfSheets()).isEqualTo(workbookGen.getNumberOfSheets()); + for (int h = 0; h < workbookGen.getNumberOfSheets() && h < workbookRef.getNumberOfSheets(); h++) { + // Un fichier excel est composé de plusieurs feuilles, on y accède de la manière suivante + XSSFSheet sheetRef = workbookRef.getSheetAt(h); + XSSFSheet sheetGen = workbookGen.getSheetAt(h); + for (int i = 0; i <= sheetRef.getLastRowNum(); i++) { + XSSFRow rowRef = sheetRef.getRow(i); + XSSFRow rowGen = sheetGen.getRow(i); + for (int j = 0; j <= rowRef.getLastCellNum(); j++) { + XSSFCell cellRef = rowRef.getCell(j); + XSSFCell cellGen = rowGen.getCell(j); + softAssert.assertThat(df.formatCellValue(cellGen)).isEqualTo(df.formatCellValue(cellRef)); + } + } + } + } + softAssert.assertAll(); + } +} + + diff --git a/kurt-utility/src/val/java/com/capgemini/reports/definition/r11report/Test_R11.java b/kurt-utility/src/val/java/com/capgemini/reports/definition/r11report/Test_R11.java new file mode 100644 index 0000000..79de46f --- /dev/null +++ b/kurt-utility/src/val/java/com/capgemini/reports/definition/r11report/Test_R11.java @@ -0,0 +1,110 @@ +package com.capgemini.reports.definition.r11report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.builder.R11Builder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.DataFormatter; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.assertj.core.api.SoftAssertions; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Optional; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + + +@Slf4j +public class Test_R11 { + private static final TcSession session = new TcSession(); + private SoftAssertions softAssert = new SoftAssertions(); + // Dossier parent du fichier de référence + private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input"; + // Sous-dossier du fichier de référence + private static final String SPECIFIC_INPUT_FOLDER = "r11"; + // Dossier de stockage temporaire des fichiers générés initialement + private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output"; + // Type de fichier traités + private static final String SUFFIX = ".xlsx"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r11report/R11_policy_full.xml"); + private Properties localproperties; + + + @BeforeClass + public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + localproperties = new Properties(); + localproperties.load(getClass().getResourceAsStream("/reporting.properties")); + } + + @AfterClass + public void logout() { + session.close(); + } + + //@BeforeMethod + //TODO : Supprimer xls files dans Generated, checker Tempfile TempDirectory + + + @Parameters({"productID", "unit", "monomulti", "generic", "effectivity", "refFile"}) + @Test + + + public void test11 + (String productID, String unit, String monomulti, + @Optional String generic, String effectivity, String refFile) throws KurtException, IOException { + + // Génération du rapport de test + Map data = new HashMap<>(); + data.put(ReportCriteriaEnum.PRODUCT, productID); + data.put(ReportCriteriaEnum.UNIT, unit); + data.put(ReportCriteriaEnum.MONO_MULTI, monomulti); + data.put(ReportCriteriaEnum.GENERIC, generic); + data.put(ReportCriteriaEnum.EFFECTIVITY_DATE, effectivity); + + + ExecutionR11 execution = new R11Builder().build(data); + new DataReportPreparatorR11().print(session, execution, new ImmediateExecutionStrategy()); + + try (FileInputStream fileInput = new FileInputStream(new File((localproperties.getProperty(INPUT_FOLDER)) + SPECIFIC_INPUT_FOLDER + "/" + refFile)); + FileInputStream fileOutput = new FileInputStream(new File(localproperties.getProperty(TEMPORARY_OUTPUT_FOLDER) + execution.getFileNameOnDisc() + SUFFIX))) { + + XSSFWorkbook workbookRef = new XSSFWorkbook(fileInput); + XSSFWorkbook workbookGen = new XSSFWorkbook(fileOutput); + DataFormatter df = new DataFormatter(); + + softAssert.assertThat(workbookRef.getNumberOfSheets()).isEqualTo(workbookGen.getNumberOfSheets()); + for (int h = 0; h < workbookGen.getNumberOfSheets() && h < workbookRef.getNumberOfSheets(); h++) { + // Un fichier excel est composé de plusieurs feuilles, on y accède de la manière suivante + XSSFSheet sheetRef = workbookRef.getSheetAt(h); + XSSFSheet sheetGen = workbookGen.getSheetAt(h); + for (int i = 0; i <= sheetRef.getLastRowNum(); i++) { + XSSFRow rowRef = sheetRef.getRow(i); + XSSFRow rowGen = sheetGen.getRow(i); + for (int j = 0; j <= rowRef.getLastCellNum(); j++) { + XSSFCell cellRef = rowRef.getCell(j); + XSSFCell cellGen = rowGen.getCell(j); + softAssert.assertThat(df.formatCellValue(cellGen)).isEqualTo(df.formatCellValue(cellRef)); + } + } + } + } + softAssert.assertAll(); + } +} \ No newline at end of file diff --git a/kurt-utility/src/val/java/com/capgemini/reports/definition/r13report/Test_CrR13.java b/kurt-utility/src/val/java/com/capgemini/reports/definition/r13report/Test_CrR13.java new file mode 100644 index 0000000..3597cf0 --- /dev/null +++ b/kurt-utility/src/val/java/com/capgemini/reports/definition/r13report/Test_CrR13.java @@ -0,0 +1,105 @@ +package com.capgemini.reports.definition.r13report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.builder.R13CrBuilder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r13report.datapreparator.DataReportPreparatorR13CR; +import com.capgemini.reports.definition.r13report.execution.ExecutionR13CR; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.DataFormatter; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.assertj.core.api.SoftAssertions; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + + +@Slf4j +public class Test_CrR13 { + private static final TcSession session = new TcSession(); + private SoftAssertions softAssert = new SoftAssertions(); + // Dossier parent du fichier de référence + private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input"; + // Sous-dossier du fichier de référence + private static final String SPECIFIC_INPUT_FOLDER = "r13"; + // Dossier de stockage temporaire des fichiers générés initialement + private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output"; + // Type de fichier traités + private static final String SUFFIX = ".xlsx"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r13report/R13_policy_full.xml"); + private Properties localproperties; + + + @BeforeClass + public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + localproperties = new Properties(); + localproperties.load(getClass().getResourceAsStream("/reporting.properties")); + } + + @AfterClass + public void logout() { + session.close(); + } + + //@BeforeMethod + //TODO : Supprimer xls files dans Generated, checker Tempfile TempDirectory + + + @Parameters({"objectType", "beginDate", "endDate", "refFile"}) + @Test + public void test13_cr(String objectType, String beginDate, String endDate, String refFile) throws KurtException, IOException { + + // Génération du rapport de test + Map data = new HashMap<>(); + data.put(ReportCriteriaEnum.TYPE_OBJET, objectType); + data.put(ReportCriteriaEnum.DATE_DEBUT, beginDate); + data.put(ReportCriteriaEnum.DATE_FIN, endDate); + + ExecutionR13CR execution = new R13CrBuilder().build(data); + new DataReportPreparatorR13CR().print(session, execution, new ImmediateExecutionStrategy()); + + try (FileInputStream fileInput = new FileInputStream(new File((localproperties.getProperty(INPUT_FOLDER)) + SPECIFIC_INPUT_FOLDER + "/" + refFile)); + FileInputStream fileOutput = new FileInputStream(new File(localproperties.getProperty(TEMPORARY_OUTPUT_FOLDER) + execution.getFileNameOnDisc() + SUFFIX))) { + + + XSSFWorkbook workbookRef = new XSSFWorkbook(fileInput); + XSSFWorkbook workbookGen = new XSSFWorkbook(fileOutput); + DataFormatter df = new DataFormatter(); + + softAssert.assertThat(workbookRef.getNumberOfSheets()).isEqualTo(workbookGen.getNumberOfSheets()); + for (int h = 0; h < workbookGen.getNumberOfSheets() && h < workbookRef.getNumberOfSheets(); h++) { + // Un fichier excel est composé de plusieurs feuilles, on y accède de la manière suivante + XSSFSheet sheetRef = workbookRef.getSheetAt(h); + XSSFSheet sheetGen = workbookGen.getSheetAt(h); + for (int i = 0; i <= sheetRef.getLastRowNum(); i++) { + XSSFRow rowRef = sheetRef.getRow(i); + XSSFRow rowGen = sheetGen.getRow(i); + for (int j = 0; j <= 34; j++) { + XSSFCell cellRef = rowRef.getCell(j); + XSSFCell cellGen = rowGen.getCell(j); + softAssert.assertThat(df.formatCellValue(cellGen)).isEqualTo(df.formatCellValue(cellRef)); + } + } + } + } + softAssert.assertAll(); + } +} diff --git a/kurt-utility/src/val/java/com/capgemini/reports/definition/r13report/Test_FppR13.java b/kurt-utility/src/val/java/com/capgemini/reports/definition/r13report/Test_FppR13.java new file mode 100644 index 0000000..dfc8738 --- /dev/null +++ b/kurt-utility/src/val/java/com/capgemini/reports/definition/r13report/Test_FppR13.java @@ -0,0 +1,106 @@ +package com.capgemini.reports.definition.r13report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.builder.R13FppBuilder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r13report.datapreparator.DataReportPreparatorR13FPP; +import com.capgemini.reports.definition.r13report.execution.ExecutionR13FPP; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.DataFormatter; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.assertj.core.api.SoftAssertions; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + + +@Slf4j +public class Test_FppR13 { + private static final TcSession session = new TcSession(); + private SoftAssertions softAssert = new SoftAssertions(); + // Dossier parent du fichier de référence + private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input"; + // Sous-dossier du fichier de référence + private static final String SPECIFIC_INPUT_FOLDER = "r13"; + // Dossier de stockage temporaire des fichiers générés initialement + private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output"; + // Type de fichier traités + private static final String SUFFIX = ".xlsx"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r13report/R13_policy_full.xml"); + private Properties localproperties; + + + @BeforeClass + public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + localproperties = new Properties(); + localproperties.load(getClass().getResourceAsStream("/reporting.properties")); + } + + @AfterClass + public void logout() { + session.close(); + } + + //@BeforeMethod + //TODO : Supprimer xls files dans Generated, checker Tempfile TempDirectory + + + @Parameters({"objectType", "beginDate", "endDate", "refFile"}) + @Test + public void test13_fpp(String objectType, String beginDate, String endDate, String refFile) throws KurtException, IOException { + + // Génération du rapport de test + Map data = new HashMap(); + data.put(ReportCriteriaEnum.TYPE_OBJET, objectType); + data.put(ReportCriteriaEnum.DATE_DEBUT, beginDate); + data.put(ReportCriteriaEnum.DATE_FIN, endDate); + + ExecutionR13FPP execution = new R13FppBuilder().build(data); + new DataReportPreparatorR13FPP().print(session, execution, new ImmediateExecutionStrategy()); + + try (FileInputStream fileInput = new FileInputStream(new File((localproperties.getProperty(INPUT_FOLDER)) + SPECIFIC_INPUT_FOLDER + "/" + refFile)); + FileInputStream fileOutput = new FileInputStream(new File(localproperties.getProperty(TEMPORARY_OUTPUT_FOLDER) + execution.getFileNameOnDisc() + SUFFIX))) { + + + XSSFWorkbook workbookRef = new XSSFWorkbook(fileInput); + XSSFWorkbook workbookGen = new XSSFWorkbook(fileOutput); + DataFormatter df = new DataFormatter(); + + softAssert.assertThat(workbookRef.getNumberOfSheets()).isEqualTo(workbookGen.getNumberOfSheets()); + for (int h = 0; h < workbookGen.getNumberOfSheets() && h < workbookRef.getNumberOfSheets(); h++) { + // Un fichier excel est composé de plusieurs feuilles, on y accède de la manière suivante + XSSFSheet sheetRef = workbookRef.getSheetAt(h); + XSSFSheet sheetGen = workbookGen.getSheetAt(h); + for (int i = 0; i <= sheetRef.getLastRowNum(); i++) { + XSSFRow rowRef = sheetRef.getRow(i); + XSSFRow rowGen = sheetGen.getRow(i); + for (int j = 0; j <= 19; j++) { + XSSFCell cellRef = rowRef.getCell(j); + XSSFCell cellGen = rowGen.getCell(j); + softAssert.assertThat(df.formatCellValue(cellGen)).isEqualTo(df.formatCellValue(cellRef)); + } + } + } + } + softAssert.assertAll(); + } +} + diff --git a/kurt-utility/src/val/java/com/capgemini/reports/definition/r15report/Test_R15.java b/kurt-utility/src/val/java/com/capgemini/reports/definition/r15report/Test_R15.java new file mode 100644 index 0000000..585d916 --- /dev/null +++ b/kurt-utility/src/val/java/com/capgemini/reports/definition/r15report/Test_R15.java @@ -0,0 +1,94 @@ +package com.capgemini.reports.definition.r15report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.builder.R15Builder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r15r16r17reports.r15r17reports.r15report.DataReportPreparatorR15; +import com.capgemini.reports.definition.r15r16r17reports.r15r17reports.r15report.ExecutionR15; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import com.lowagie.text.pdf.PdfReader; +import com.lowagie.text.pdf.parser.PdfTextExtractor; +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.SoftAssertions; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + + +@Slf4j +public class Test_R15 { + private static final TcSession session = new TcSession(); + private SoftAssertions softAssert = new SoftAssertions(); + // Dossier parent du fichier de référence + private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input"; + // Sous-dossier du fichier de référence + private static final String SPECIFIC_INPUT_FOLDER = "r15"; + public static final String PRINTINGFOLDER = "com.capgemini.report.location.default.output"; + // Dossier de stockage temporaire des fichiers générés initialement + private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output"; + // Dossier de stockage final des fichiers + private static final String RECORDS_FOLDER = "com.capgemini.report.location.default.records"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r15report/R15_policy_full.xml"); + public static final String SUFFIX = ".pdf"; + public Properties localproperties; + + + @BeforeClass + public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + localproperties = new Properties(); + localproperties.load(getClass().getResourceAsStream("/reporting.properties")); + } + + @AfterClass + public void logout() { + session.close(); + } + + @BeforeMethod + //TODO : Supprimer pdf files dans Generated, checker Tempfile TempDirectory + + + @Parameters({"language", "partId", "partRevision", "refFile"}) + @Test + public void test15(String language, String partId, String partRevision, String refFile) throws KurtException, IOException { + + // Génération du rapport de test + Map data = new HashMap(); + data.put(ReportCriteriaEnum.PART_ID, partId); + data.put(ReportCriteriaEnum.PART_REVISION, partRevision); + data.put((ReportCriteriaEnum.LANGUAGE), language); + ExecutionR15 execution = new R15Builder().build(data); + new DataReportPreparatorR15().print(session, execution, new ImmediateExecutionStrategy()); + + + PdfReader readerRef = new PdfReader(localproperties.getProperty(INPUT_FOLDER) + SPECIFIC_INPUT_FOLDER + "/" + refFile); + PdfReader readerGen = new PdfReader(localproperties.getProperty((TEMPORARY_OUTPUT_FOLDER)) + execution.getFileNameOnDisc() + SUFFIX); + + try { + softAssert.assertThat(readerRef.getNumberOfPages()).isEqualTo(readerGen.getNumberOfPages()); + for (int i = 1; i < readerRef.getNumberOfPages(); i++) { + String textFromPageRef = new PdfTextExtractor(readerRef).getTextFromPage(i); + String textFromPageGen = new PdfTextExtractor(readerGen).getTextFromPage(i); + softAssert.assertThat(textFromPageRef).isEqualTo(textFromPageGen); + } + } + finally { + readerGen.close(); + readerRef.close(); + } + softAssert.assertAll(); + } +} diff --git a/kurt-utility/src/val/java/com/capgemini/reports/definition/r16report/Test_R16.java b/kurt-utility/src/val/java/com/capgemini/reports/definition/r16report/Test_R16.java new file mode 100644 index 0000000..0bcb5dc --- /dev/null +++ b/kurt-utility/src/val/java/com/capgemini/reports/definition/r16report/Test_R16.java @@ -0,0 +1,96 @@ +package com.capgemini.reports.definition.r16report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.builder.R16Builder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r15r16r17reports.r16report.DataReportPreparatorR16; +import com.capgemini.reports.definition.r15r16r17reports.r16report.ExecutionR16; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import com.lowagie.text.pdf.PdfReader; +import com.lowagie.text.pdf.parser.PdfTextExtractor; +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.SoftAssertions; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + + +@Slf4j +public class Test_R16 { + private static final TcSession session = new TcSession(); + private SoftAssertions softAssert = new SoftAssertions(); + // Dossier parent du fichier de référence + private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input"; + // Sous-dossier du fichier de référence + private static final String SPECIFIC_INPUT_FOLDER = "r16"; + public static final String PRINTINGFOLDER = "com.capgemini.report.location.default.output"; + // Dossier de stockage temporaire des fichiers générés initialement + private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r16report/R16_policy_full.xml"); + public static final String SUFFIX = ".pdf"; + public Properties localproperties; + + + @BeforeClass + public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + localproperties = new Properties(); + localproperties.load(getClass().getResourceAsStream("/reporting.properties")); + } + + @AfterClass + public void logout() { + session.close(); + } + + @BeforeMethod + //TODO : Supprimer pdf files dans Generated, checker Tempfile TempDirectory + + + @Parameters({"product", "unitStr", "idTopGeneric", "typeImpression", "language", "refFile"}) + @Test + public void test16(String product, String unitStr, String idTopGeneric, + String typeImpression, String language, String refFile) throws KurtException, IOException { + + // Génération du rapport de test + Map data = new HashMap<>(); + data.put(ReportCriteriaEnum.PRODUCT, product); + data.put(ReportCriteriaEnum.PART_ID, idTopGeneric); + data.put(ReportCriteriaEnum.UNIT, unitStr); + data.put(ReportCriteriaEnum.TYPE_IMPRESSION, typeImpression); + data.put(ReportCriteriaEnum.LANGUAGE, language); + + ExecutionR16 execution = new R16Builder().build(data); + new DataReportPreparatorR16().print(session, execution, new ImmediateExecutionStrategy()); + + + PdfReader readerRef = new PdfReader(localproperties.getProperty(INPUT_FOLDER) + SPECIFIC_INPUT_FOLDER + "/" + refFile); + PdfReader readerGen = new PdfReader(localproperties.getProperty((TEMPORARY_OUTPUT_FOLDER)) + execution.getFileNameOnDisc() + SUFFIX); + + try { + softAssert.assertThat(readerRef.getNumberOfPages()).isEqualTo(readerGen.getNumberOfPages()); + for (int i = 1; i < readerRef.getNumberOfPages(); i++) { + String textFromPageRef = new PdfTextExtractor(readerRef).getTextFromPage(i); + String textFromPageGen = new PdfTextExtractor(readerGen).getTextFromPage(i); + softAssert.assertThat(textFromPageRef).isEqualTo(textFromPageGen); + } + } + finally { + readerGen.close(); + readerRef.close(); + } + softAssert.assertAll(); + } +} \ No newline at end of file diff --git a/kurt-utility/src/val/java/com/capgemini/reports/definition/r17report/Test_R17.java b/kurt-utility/src/val/java/com/capgemini/reports/definition/r17report/Test_R17.java new file mode 100644 index 0000000..6957b43 --- /dev/null +++ b/kurt-utility/src/val/java/com/capgemini/reports/definition/r17report/Test_R17.java @@ -0,0 +1,91 @@ +package com.capgemini.reports.definition.r17report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.builder.R17Builder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.definition.r15r16r17reports.r15r17reports.r17report.DataReportPreparatorR17; +import com.capgemini.reports.definition.r15r16r17reports.r15r17reports.r17report.ExecutionR17; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import com.lowagie.text.pdf.PdfReader; +import com.lowagie.text.pdf.parser.PdfTextExtractor; +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.SoftAssertions; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + + +@Slf4j +public class Test_R17 { + private static final TcSession session = new TcSession(); + private SoftAssertions softAssert = new SoftAssertions(); + // Dossier parent du fichier de référence + private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input"; + // Sous-dossier du fichier de référence + private static final String SPECIFIC_INPUT_FOLDER = "r17"; + // Dossier de stockage temporaire des fichiers générés initialement + private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r17report/R17_policy_full.xml"); + public static final String SUFFIX = ".pdf"; + public Properties localproperties; + + + @BeforeClass + public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + localproperties = new Properties(); + localproperties.load(getClass().getResourceAsStream("/reporting.properties")); + } + + @AfterClass + public void logout() { + session.close(); + } + + @BeforeMethod + //TODO : Supprimer pdf files dans Generated, checker Tempfile TempDirectory + + + @Parameters({"language", "partId", "partRevision", "refFile"}) + @Test + public void test17(String language, String partId, String partRevision, String refFile) throws KurtException, IOException { + + // Génération du rapport de test + Map data = new HashMap<>(); + data.put(ReportCriteriaEnum.PART_ID, partId); + data.put(ReportCriteriaEnum.PART_REVISION, partRevision); + data.put((ReportCriteriaEnum.LANGUAGE), language); + ExecutionR17 execution = new R17Builder().build(data); + new DataReportPreparatorR17().print(session, execution, new ImmediateExecutionStrategy()); + + + PdfReader readerRef = new PdfReader(localproperties.getProperty(INPUT_FOLDER) + SPECIFIC_INPUT_FOLDER + "/" + refFile); + PdfReader readerGen = new PdfReader(localproperties.getProperty((TEMPORARY_OUTPUT_FOLDER)) + execution.getFileNameOnDisc() + SUFFIX); + + try { + softAssert.assertThat(readerRef.getNumberOfPages()).isEqualTo(readerGen.getNumberOfPages()); + for (int i = 1; i < readerRef.getNumberOfPages(); i++) { + String textFromPageRef = new PdfTextExtractor(readerRef).getTextFromPage(i); + String textFromPageGen = new PdfTextExtractor(readerGen).getTextFromPage(i); + softAssert.assertThat(textFromPageRef).isEqualTo(textFromPageGen); + } + } + finally { + readerGen.close(); + readerRef.close(); + } + softAssert.assertAll(); + } +} \ No newline at end of file diff --git a/kurt-utility/src/val/java/com/capgemini/reports/definition/r19report/Test_R19.java b/kurt-utility/src/val/java/com/capgemini/reports/definition/r19report/Test_R19.java new file mode 100644 index 0000000..3d39731 --- /dev/null +++ b/kurt-utility/src/val/java/com/capgemini/reports/definition/r19report/Test_R19.java @@ -0,0 +1,107 @@ +package com.capgemini.reports.definition.r19report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.builder.R19Builder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.DataFormatter; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.assertj.core.api.SoftAssertions; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + + +@Slf4j +public class Test_R19 { + private static final TcSession session = new TcSession(); + private SoftAssertions softAssert = new SoftAssertions(); + // Dossier parent du fichier de référence + private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input"; + // Sous-dossier du fichier de référence + private static final String SPECIFIC_INPUT_FOLDER = "r19"; + // Dossier de stockage temporaire des fichiers générés initialement + private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output"; + // Type de fichier traités + private static final String SUFFIX = ".xlsx"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r19report/R19_policy_full.xml"); + private Properties localproperties; + + + @BeforeClass + public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + localproperties = new Properties(); + localproperties.load(getClass().getResourceAsStream("/reporting.properties")); + } + + @AfterClass + public void logout() { + session.close(); + } + + //@BeforeMethod + //TODO : Supprimer xls files dans Generated, checker Tempfile TempDirectory + + + @Parameters({"docId", "revision", "typeObject", "refFile"}) + @Test + + public void test19(String docId, String revision, String typeObject, String refFile) + throws KurtException, IOException { + + // Génération du rapport de test + Map data = new HashMap<>(); + data.put(ReportCriteriaEnum.DOCUMENT_ID, docId); + data.put(ReportCriteriaEnum.DOCUMENT_REVISION, revision); + data.put(ReportCriteriaEnum.TYPE_OBJET, typeObject); + + + ExecutionR19 execution = new R19Builder().build(data); + new DataReportPreparatorR19().print(session, execution, new ImmediateExecutionStrategy()); + + try (FileInputStream fileInput = new FileInputStream(new File((localproperties.getProperty(INPUT_FOLDER)) + SPECIFIC_INPUT_FOLDER + "/" + refFile)); + FileInputStream fileOutput = new FileInputStream(new File(localproperties.getProperty(TEMPORARY_OUTPUT_FOLDER) + execution.getFileNameOnDisc() + SUFFIX))) { + + XSSFWorkbook workbookRef = new XSSFWorkbook(fileInput); + XSSFWorkbook workbookGen = new XSSFWorkbook(fileOutput); + DataFormatter df = new DataFormatter(); + + softAssert.assertThat(workbookRef.getNumberOfSheets()).isEqualTo(workbookGen.getNumberOfSheets()); + for (int h = 0; h < workbookGen.getNumberOfSheets() && h < workbookRef.getNumberOfSheets(); h++) { + // Un fichier excel est composé de plusieurs feuilles, on y accède de la manière suivante + XSSFSheet sheetRef = workbookRef.getSheetAt(h); + XSSFSheet sheetGen = workbookGen.getSheetAt(h); + for (int i = 0; i <= sheetRef.getLastRowNum(); i++) { + XSSFRow rowRef = sheetRef.getRow(i); + XSSFRow rowGen = sheetGen.getRow(i); + for (int j = 0; j <= rowRef.getLastCellNum(); j++) { + XSSFCell cellRef = rowRef.getCell(j); + XSSFCell cellGen = rowGen.getCell(j); + softAssert.assertThat(df.formatCellValue(cellGen)).isEqualTo(df.formatCellValue(cellRef)); + } + } + } + } + softAssert.assertAll(); + } +} + + diff --git a/kurt-utility/src/val/java/com/capgemini/reports/definition/r20report/Test_R20.java b/kurt-utility/src/val/java/com/capgemini/reports/definition/r20report/Test_R20.java new file mode 100644 index 0000000..d52faa9 --- /dev/null +++ b/kurt-utility/src/val/java/com/capgemini/reports/definition/r20report/Test_R20.java @@ -0,0 +1,96 @@ +package com.capgemini.reports.definition.r20report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.builder.R20Builder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import com.lowagie.text.pdf.PdfReader; +import com.lowagie.text.pdf.parser.PdfTextExtractor; +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.SoftAssertions; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Optional; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + + +@Slf4j +public class Test_R20 { + private static final TcSession session = new TcSession(); + private SoftAssertions softAssert = new SoftAssertions(); + // Dossier parent du fichier de référence + private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input"; + // Sous-dossier du fichier de référence + private static final String SPECIFIC_INPUT_FOLDER = "r20"; + // Dossier de stockage temporaire des fichiers générés initialement + private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r20report/R20_policy_full.xml"); + public static final String SUFFIX = ".pdf"; + public Properties localproperties; + + + @BeforeClass + public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + localproperties = new Properties(); + localproperties.load(getClass().getResourceAsStream("/reporting.properties")); + } + + @AfterClass + public void logout() { + session.close(); + } + + + @Test + @Parameters({"prodIDBefore", "prodIDAfter", "unitBefore", "unitAfter", "matricule", "listModif", "classe", "majMin", "conjoint", "refFile"}) + public void test20(String prodIDBefore, String prodIDAfter, String unitBefore, String unitAfter, + String matricule, @Optional String listModif, String classe, String majMin, String conjoint, + String refFile) throws KurtException, IOException { + + // Génération du rapport de test + Map data = new HashMap<>(); + data.put(ReportCriteriaEnum.PRODUCT_BEFORE, prodIDBefore); + data.put(ReportCriteriaEnum.PRODUCT_AFTER, prodIDAfter); + data.put(ReportCriteriaEnum.UNIT_BEFORE, unitBefore); + data.put(ReportCriteriaEnum.UNIT_AFTER, unitAfter); + data.put(ReportCriteriaEnum.MATRICULE, matricule); + data.put(ReportCriteriaEnum.LMR, listModif); + data.put(ReportCriteriaEnum.CLASSE, classe); + data.put(ReportCriteriaEnum.MAJOR_MINOR, majMin); + data.put(ReportCriteriaEnum.CONJOINT_UNIQUE, conjoint); + + + ExecutionR20 execution = new R20Builder().build(data); + new DataReportPreparatorR20().print(session, execution, new ImmediateExecutionStrategy()); + + + PdfReader readerRef = new PdfReader(localproperties.getProperty(INPUT_FOLDER) + SPECIFIC_INPUT_FOLDER + "/" + refFile); + PdfReader readerGen = new PdfReader(localproperties.getProperty((TEMPORARY_OUTPUT_FOLDER)) + execution.getFileNameOnDisc() + SUFFIX); + + try { + softAssert.assertThat(readerRef.getNumberOfPages()).isEqualTo(readerGen.getNumberOfPages()); + for (int i = 1; i < readerRef.getNumberOfPages(); i++) { + String textFromPageRef = new PdfTextExtractor(readerRef).getTextFromPage(i); + String textFromPageGen = new PdfTextExtractor(readerGen).getTextFromPage(i); + softAssert.assertThat(textFromPageRef).isEqualTo(textFromPageGen); + } + } + finally { + readerGen.close(); + readerRef.close(); + } + softAssert.assertAll(); + } +} diff --git a/kurt-utility/src/val/java/com/capgemini/reports/definition/r21report/Test_R21.java b/kurt-utility/src/val/java/com/capgemini/reports/definition/r21report/Test_R21.java new file mode 100644 index 0000000..5858e9e --- /dev/null +++ b/kurt-utility/src/val/java/com/capgemini/reports/definition/r21report/Test_R21.java @@ -0,0 +1,109 @@ +package com.capgemini.reports.definition.r21report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.builder.R21Builder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.DataFormatter; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.assertj.core.api.SoftAssertions; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Optional; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + + +@Slf4j +public class Test_R21 { + private static final TcSession session = new TcSession(); + private SoftAssertions softAssert = new SoftAssertions(); + // Dossier parent du fichier de référence + private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input"; + // Sous-dossier du fichier de référence + private static final String SPECIFIC_INPUT_FOLDER = "r21"; + // Dossier de stockage temporaire des fichiers générés initialement + private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output"; + // Type de fichier traités + private static final String SUFFIX = ".xlsx"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r21report/R21_policy_full.xml"); + private Properties localproperties; + + + @BeforeClass + public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + localproperties = new Properties(); + localproperties.load(getClass().getResourceAsStream("/reporting.properties")); + } + + @AfterClass + public void logout() { + session.close(); + } + + //@BeforeMethod + //TODO : Supprimer xls files dans Generated, checker Tempfile TempDirectory + + + @Parameters({"productID", "unit", "generic", "genericAssemb", "effectivity", "refFile"}) + @Test + + public void test21(String productID, String unit, String generic, String genericAssemb, @Optional String effectivity, String refFile) + throws KurtException, IOException { + + // Génération du rapport de test + Map data = new HashMap(); + data.put(ReportCriteriaEnum.PRODUCT, productID); + data.put(ReportCriteriaEnum.UNIT, unit); + data.put(ReportCriteriaEnum.GENERIC, generic); + data.put(ReportCriteriaEnum.GENERIC_ASSEMB, genericAssemb); + data.put(ReportCriteriaEnum.EFFECTIVITY_DATE, effectivity); + + + ExecutionR21 execution = new R21Builder().build(data); + new DataReportPreparatorR21().print(session, execution, new ImmediateExecutionStrategy()); + + try (FileInputStream fileInput = new FileInputStream(new File((localproperties.getProperty(INPUT_FOLDER)) + SPECIFIC_INPUT_FOLDER + "/" + refFile)); + FileInputStream fileOutput = new FileInputStream(new File(localproperties.getProperty(TEMPORARY_OUTPUT_FOLDER) + execution.getFileNameOnDisc() + SUFFIX))) { + + XSSFWorkbook workbookRef = new XSSFWorkbook(fileInput); + XSSFWorkbook workbookGen = new XSSFWorkbook(fileOutput); + DataFormatter df = new DataFormatter(); + + + softAssert.assertThat(workbookRef.getNumberOfSheets()).isEqualTo(workbookGen.getNumberOfSheets()); + for (int h = 0; h < workbookGen.getNumberOfSheets() && h < workbookRef.getNumberOfSheets(); h++) { + // Un fichier excel est composé de plusieurs feuilles, on y accède de la manière suivante + XSSFSheet sheetRef = workbookRef.getSheetAt(h); + XSSFSheet sheetGen = workbookGen.getSheetAt(h); + for (int i = 0; i <= sheetRef.getLastRowNum(); i++) { + XSSFRow rowRef = sheetRef.getRow(i); + XSSFRow rowGen = sheetGen.getRow(i); + for (int j = 0; j <= rowRef.getLastCellNum(); j++) { + XSSFCell cellRef = rowRef.getCell(j); + XSSFCell cellGen = rowGen.getCell(j); + softAssert.assertThat(df.formatCellValue(cellGen)).isEqualTo(df.formatCellValue(cellRef)); + } + } + } + } + softAssert.assertAll(); + } +} diff --git a/kurt-utility/src/val/java/com/capgemini/reports/definition/r22report/Test_R22.java b/kurt-utility/src/val/java/com/capgemini/reports/definition/r22report/Test_R22.java new file mode 100644 index 0000000..76ee2e8 --- /dev/null +++ b/kurt-utility/src/val/java/com/capgemini/reports/definition/r22report/Test_R22.java @@ -0,0 +1,98 @@ +package com.capgemini.reports.definition.r22report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.builder.R22Builder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import com.lowagie.text.pdf.PdfReader; +import com.lowagie.text.pdf.parser.PdfTextExtractor; +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.SoftAssertions; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + + +@Slf4j +public class Test_R22 { + private static final TcSession session = new TcSession(); + private SoftAssertions softAssert = new SoftAssertions(); + // Dossier parent du fichier de référence + private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input"; + // Sous-dossier du fichier de référence + private static final String SPECIFIC_INPUT_FOLDER = "r22"; + // Dossier de stockage temporaire des fichiers générés initialement + private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r22report/R22_policy_full.xml"); + public static final String SUFFIX = ".pdf"; + public Properties localproperties; + + + @BeforeClass + public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + localproperties = new Properties(); + localproperties.load(getClass().getResourceAsStream("/reporting.properties")); + } + + @AfterClass + public void logout() { + session.close(); + } + + @BeforeMethod + //TODO : Supprimer pdf files dans Generated, checker Tempfile TempDirectory + + + @Parameters({"partID", "partRevisionID", "refFile"}) + @Test + public void test22(String partID, String partRevisionID, String refFile) throws KurtException, IOException { + + // Génération du rapport de test + Map data = new HashMap<>(); + data.put(ReportCriteriaEnum.PART_ID, partID); + data.put(ReportCriteriaEnum.PART_REVISION, partRevisionID); + ExecutionR22 execution = new R22Builder().build(data); + new DataReportPreparatorR22().print(session, execution, new ImmediateExecutionStrategy()); + + + PdfReader readerRef = new PdfReader(localproperties.getProperty(INPUT_FOLDER) + SPECIFIC_INPUT_FOLDER + "/" + refFile); + PdfReader readerGen = new PdfReader(localproperties.getProperty((TEMPORARY_OUTPUT_FOLDER)) + execution.getFileNameOnDisc() + SUFFIX); + + String stringUncheckable = ".*[0-9]{1,2}\\s[a-z]{3,9}\\s[0-9]{4}.*"; + + try { + softAssert.assertThat(readerRef.getNumberOfPages()).isEqualTo(readerGen.getNumberOfPages()); + for (int i = 1; i < readerRef.getNumberOfPages(); i++) { + String textFromPageRef = new PdfTextExtractor(readerRef).getTextFromPage(i); + String textFromPageGen = new PdfTextExtractor(readerGen).getTextFromPage(i); + String[] tableauTextGen = textFromPageGen.split("\n"); + String[] tableauTextRef = textFromPageRef.split("\n"); + for (int j = 0; j < tableauTextGen.length; j++) { + if (tableauTextGen[j].matches(stringUncheckable) && tableauTextRef[j].matches(stringUncheckable)) { + // Dates of R22 reports are not compared + continue; + } + softAssert.assertThat(tableauTextGen[j]).isEqualTo(tableauTextRef[j]); + } + } + } + finally { + readerGen.close(); + readerRef.close(); + } + softAssert.assertAll(); + } +} diff --git a/kurt-utility/src/val/java/com/capgemini/reports/definition/r23report/Test_R23.java b/kurt-utility/src/val/java/com/capgemini/reports/definition/r23report/Test_R23.java new file mode 100644 index 0000000..0fcbc2c --- /dev/null +++ b/kurt-utility/src/val/java/com/capgemini/reports/definition/r23report/Test_R23.java @@ -0,0 +1,130 @@ +package com.capgemini.reports.definition.r23report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.builder.R23Builder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import lombok.extern.slf4j.Slf4j; +import net.lingala.zip4j.core.ZipFile; +import net.lingala.zip4j.exception.ZipException; +import org.apache.poi.ss.usermodel.DataFormatter; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.assertj.core.api.SoftAssertions; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Optional; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + + +@Slf4j +public class Test_R23 { + private static final TcSession session = new TcSession(); + private SoftAssertions softAssert = new SoftAssertions(); + private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input"; + private static final String SPECIFIC_INPUT_FOLDER = "r23"; + private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output"; + private static final String SUFFIX = ".zip"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r23report/R23_policy_full.xml"); + private Properties localproperties; + + + @BeforeClass + public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + localproperties = new Properties(); + localproperties.load(getClass().getResourceAsStream("/reporting.properties")); + } + + @AfterClass + public void logout() { + session.close(); + } + + //@BeforeMethod + //TODO : Supprimer xls files dans Generated, checker Tempfile TempDirectory + + + @Parameters({"productID", "monomulti", "effectivityDate", "genericAssemb", "generic", "refFile"}) + @Test + public void test23(String productID, String monomulti, @Optional String + effectivityDate, @Optional String genericAssemb, @Optional String generic, String refFile) throws + KurtException, IOException, ZipException { + // Génération du rapport de test + Map data = new HashMap<>(); + data.put(ReportCriteriaEnum.PRODUCT, productID); + data.put(ReportCriteriaEnum.MONO_MULTI, monomulti); + data.put(ReportCriteriaEnum.GENERIC, generic); + data.put(ReportCriteriaEnum.GENERIC_ASSEMB, genericAssemb); + data.put(ReportCriteriaEnum.EFFECTIVITY_DATE, effectivityDate); + + ExecutionR23 execution = new R23Builder().build(data); + new DataReportPreparatorR23().print(session, execution, new ImmediateExecutionStrategy()); + + List excelListRef = new ArrayList<>(); + List excelListGen = new ArrayList<>(); + + Path tempDirGenerated = Files.createTempDirectory("tempfilesGenerated"); + Path tempDirReferenced = Files.createTempDirectory("tempfilesReferenced"); + + + ZipFile sourceGen = new ZipFile(localproperties.getProperty(TEMPORARY_OUTPUT_FOLDER) + execution.getFileNameOnDisc() + SUFFIX); + sourceGen.extractAll(tempDirGenerated.toString()); + + ZipFile sourceRef = new ZipFile(localproperties.getProperty(INPUT_FOLDER) + SPECIFIC_INPUT_FOLDER + "/" + refFile); + sourceRef.extractAll(tempDirReferenced.toString()); + + + for (File fileInList : tempDirReferenced.toFile().listFiles()) { + try (FileInputStream fileInput = new FileInputStream(fileInList)) { + excelListRef.add(new XSSFWorkbook(fileInput)); + } + } + + for (File fileOutList : tempDirGenerated.toFile().listFiles()) { + try (FileInputStream fileOutput = new FileInputStream(fileOutList)) { + excelListGen.add(new XSSFWorkbook(fileOutput)); + } + } + + softAssert.assertThat(excelListGen.size()).isEqualTo(excelListRef.size()); + for (int a = 0; a < excelListGen.size() && a < excelListRef.size(); a++) { + if (excelListGen.get(a).getNumberOfSheets() == excelListRef.get(a).getNumberOfSheets()) { + for (int b = 0; b < excelListGen.get(a).getNumberOfSheets(); b++) { + XSSFSheet sheetRef = excelListRef.get(a).getSheetAt(b); + XSSFSheet sheetGen = excelListGen.get(a).getSheetAt(b); + DataFormatter df = new DataFormatter(); + for (int i = 1; i < sheetRef.getLastRowNum(); i++) { + XSSFRow rowRef = sheetRef.getRow(i); + XSSFRow rowGen = sheetGen.getRow(i); + for (int j = 0; j < rowRef.getLastCellNum(); j++) { + XSSFCell cellRef = rowRef.getCell(j); + XSSFCell cellGen = rowGen.getCell(j); + softAssert.assertThat(df.formatCellValue(cellGen)).isEqualTo(df.formatCellValue(cellRef)); + } + } + } + } + } + softAssert.assertAll(); + } +} diff --git a/kurt-utility/src/val/java/com/capgemini/reports/definition/r24report/Test_R24.java b/kurt-utility/src/val/java/com/capgemini/reports/definition/r24report/Test_R24.java new file mode 100644 index 0000000..f542d29 --- /dev/null +++ b/kurt-utility/src/val/java/com/capgemini/reports/definition/r24report/Test_R24.java @@ -0,0 +1,138 @@ +package com.capgemini.reports.definition.r24report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.builder.R24Builder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import lombok.extern.slf4j.Slf4j; +import net.lingala.zip4j.core.ZipFile; +import net.lingala.zip4j.exception.ZipException; +import org.apache.poi.ss.usermodel.DataFormatter; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.assertj.core.api.SoftAssertions; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + + +@Slf4j +public class Test_R24 { + private static final TcSession session = new TcSession(); + private SoftAssertions softAssert = new SoftAssertions(); + private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input"; + private static final String SPECIFIC_INPUT_FOLDER = "r24"; + private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output"; + private static final String SUFFIX = ".zip"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r24report/R24_policy_full.xml"); + private Properties localproperties; + + + @BeforeClass + public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + localproperties = new Properties(); + localproperties.load(getClass().getResourceAsStream("/reporting.properties")); + } + + @AfterClass + public void logout() { + session.close(); + } + + //@BeforeMethod + //TODO : Supprimer xls files dans Generated, checker Tempfile TempDirectory + + + @Parameters({"productID", "unit", "typeImpr", "language", "refFile"}) + @Test + public void test24(String productID, String unit, String typeImpr, String language, String refFile) throws + KurtException, IOException, ZipException { + // Génération du rapport de test + Map data = new HashMap<>(); + data.put(ReportCriteriaEnum.PRODUCT, productID); + data.put(ReportCriteriaEnum.UNIT, unit); + data.put(ReportCriteriaEnum.TYPE_IMPRESSION, typeImpr); + data.put(ReportCriteriaEnum.LANGUAGE, language); + + ExecutionR24 execution = (ExecutionR24) new R24Builder().build(data); + new DataReportPreparatorR24().print(session, execution, new ImmediateExecutionStrategy()); + + List excelListRef = new ArrayList<>(); + List excelListGen = new ArrayList<>(); + + Path tempDirGenerated = Files.createTempDirectory("tempfilesGenerated"); + Path tempDirReferenced = Files.createTempDirectory("tempfilesReferenced"); + + + ZipFile sourceGen = new ZipFile(localproperties.getProperty(TEMPORARY_OUTPUT_FOLDER) + execution.getFileNameOnDisc() + SUFFIX); + sourceGen.extractAll(tempDirGenerated.toString()); + + ZipFile sourceRef = new ZipFile(localproperties.getProperty(INPUT_FOLDER) + SPECIFIC_INPUT_FOLDER + "/" + refFile); + sourceRef.extractAll(tempDirReferenced.toString()); + + + for (File fileInList : tempDirReferenced.toFile().listFiles()) { + try (FileInputStream fileInput = new FileInputStream(fileInList)) { + excelListRef.add(new XSSFWorkbook(fileInput)); + } + } + + for (File fileOutList : tempDirGenerated.toFile().listFiles()) { + try (FileInputStream fileOutput = new FileInputStream(fileOutList)) { + excelListGen.add(new XSSFWorkbook(fileOutput)); + } + } + + softAssert.assertThat(excelListGen.size()).isEqualTo(excelListRef.size()); + for (int a = 0; a < excelListGen.size() && a < excelListRef.size(); a++) { + if (excelListGen.get(a).getNumberOfSheets() == excelListRef.get(a).getNumberOfSheets()) { + for (int b = 0; b < excelListGen.get(a).getNumberOfSheets(); b++) { + XSSFSheet sheetRef = excelListRef.get(a).getSheetAt(b); + XSSFSheet sheetGen = excelListGen.get(a).getSheetAt(b); + DataFormatter df = new DataFormatter(); + for (int i = 1; i < sheetRef.getLastRowNum(); i++) { + XSSFRow rowRef = sheetRef.getRow(i); + XSSFRow rowGen = sheetGen.getRow(i); + for (int j = 0; j < rowRef.getLastCellNum(); j++) { + XSSFCell cellRef = rowRef.getCell(j); + XSSFCell cellGen = rowGen.getCell(j); + softAssert.assertThat(df.formatCellValue(cellGen)).isEqualTo(df.formatCellValue(cellRef)); + } + } + } + } + } + softAssert.assertAll(); + } +} + + + + + + + + + + + diff --git a/kurt-utility/src/val/java/com/capgemini/reports/definition/r25report/Test_R25.java b/kurt-utility/src/val/java/com/capgemini/reports/definition/r25report/Test_R25.java new file mode 100644 index 0000000..2bab021 --- /dev/null +++ b/kurt-utility/src/val/java/com/capgemini/reports/definition/r25report/Test_R25.java @@ -0,0 +1,161 @@ +package com.capgemini.reports.definition.r25report; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.builder.R25Builder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import lombok.extern.slf4j.Slf4j; +import net.lingala.zip4j.core.ZipFile; +import net.lingala.zip4j.exception.ZipException; +import org.apache.poi.ss.usermodel.DataFormatter; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.assertj.core.api.SoftAssertions; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Optional; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + + +@Slf4j +public class Test_R25 { + private static final TcSession session = new TcSession(); + private SoftAssertions softAssert = new SoftAssertions(); + private static final String ZIP_INPUT_FOLDER = "com.capgemini.report.location.default.input"; + private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output"; + private static final String SUFFIX = ".zip"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r25report/R25_policy_full.xml"); + private Properties localproperties; + + + @BeforeClass + public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + localproperties = new Properties(); + localproperties.load(getClass().getResourceAsStream("/reporting.properties")); + } + + @AfterClass + public void logout() { + session.close(); + } + + + @Parameters({"productID", "unit", "typeImpression", "language", "refFile"}) + @Test + public void test25(String productID, @Optional String unit, String typeImpression, String language, String refFile) throws + KurtException, IOException, ZipException { + // Génération du rapport de test + Map data = new HashMap<>(); + data.put(ReportCriteriaEnum.PRODUCT, productID); + data.put(ReportCriteriaEnum.UNIT, unit); + data.put(ReportCriteriaEnum.TYPE_IMPRESSION, typeImpression); + data.put(ReportCriteriaEnum.LANGUAGE, language); + + ExecutionR25 execution = (ExecutionR25) new R25Builder().build(data); + new DataReportPreparatorR25().print(session, execution, new ImmediateExecutionStrategy()); + + + ArrayList excelListRef = new ArrayList<>(); + ArrayList excelListGen = new ArrayList<>(); + Path tempDirZipGenerated = Files.createTempDirectory("tempfilesZipGenerated"); + Path tempDirExcelGenerated = Files.createTempDirectory("tempfilesExcelGenerated"); + Path tempDirExcelReferenced = Files.createTempDirectory("tempfilesExcelReferenced"); + Path tempDirZipReferenced = Files.createTempDirectory("tempfilesZipReferenced"); + + DataFormatter df = new DataFormatter(); + + // Extraction du Zip parent Fichier Generated + ZipFile sourceGen2 = new ZipFile(localproperties.getProperty(TEMPORARY_OUTPUT_FOLDER) + execution.getFileNameOnDisc() + SUFFIX); + sourceGen2.extractAll(tempDirZipGenerated.toString()); + + // Extraction des Zips enfants Fichier Generated + + for (File aFileGen : tempDirZipGenerated.toFile().listFiles()) { + ZipFile sourceGen = new ZipFile(String.valueOf(aFileGen)); + sourceGen.extractAll(tempDirExcelGenerated.toString()); + } + + + System.out.println("<------------- FICHIERS GENERES ------------------>"); + + + // Extraction des données Excel du Fichier Generated + for (File fileListExcelGen : tempDirExcelGenerated.toFile().listFiles()) { + if (fileListExcelGen.getAbsolutePath().endsWith(".xlsx")) { + System.out.println("NOM DU FICHIER GENERE: " + fileListExcelGen); + FileInputStream fileInput = new FileInputStream( + new File(String.valueOf(fileListExcelGen))); + XSSFWorkbook workbookGen = new XSSFWorkbook(fileInput); + excelListGen.add(workbookGen); + } + } + + // Extraction du Zip parent Fichier Referenced + ZipFile sourceRef2 = new ZipFile(localproperties.getProperty(ZIP_INPUT_FOLDER) + "/r25/" + refFile); + sourceRef2.extractAll(tempDirZipReferenced.toString()); + + // Extraction des Zips enfants Fichier Referenced + for (File aFileRef : tempDirZipReferenced.toFile().listFiles()) { + ZipFile sourceRef = new ZipFile(String.valueOf(aFileRef)); + sourceRef.extractAll(tempDirExcelReferenced.toString()); + } + + System.out.println("<------------- FICHIERS DE REFERENCE ------------------>"); + + // Extraction des données Excel du Fichier Referenced + for (File fileListExcelRef : tempDirExcelReferenced.toFile().listFiles()) { + if (fileListExcelRef.getAbsolutePath().endsWith(".xlsx")) { + System.out.println("NOM DU FICHIER DE REFERENCE: " + fileListExcelRef); + FileInputStream fileInput = new FileInputStream( + new File(String.valueOf(fileListExcelRef))); + XSSFWorkbook workbookRef = new XSSFWorkbook(fileInput); + excelListRef.add(workbookRef); + } + } + + softAssert.assertThat(excelListGen.size()).isEqualTo(excelListRef.size()); + for (int a = 0; a < excelListGen.size() && a < excelListRef.size(); a++) { + if (excelListGen.get(a).getNumberOfSheets() == excelListRef.get(a).getNumberOfSheets()) { + for (int b = 0; b < excelListGen.get(a).getNumberOfSheets(); b++) { + System.out.println(excelListRef.get(a)); + System.out.println(excelListGen.get(a)); + System.out.println("WORKBOOKREF = " + excelListRef.get(a).getCTWorkbook()); + System.out.println("WORKBOOKGEN = " + excelListGen.get(a).getCTWorkbook()); + XSSFSheet sheetRef = excelListRef.get(a).getSheetAt(b); + XSSFSheet sheetGen = excelListGen.get(a).getSheetAt(b); + for (int i = 2; i < sheetRef.getLastRowNum(); i++) { + XSSFRow rowRef = sheetRef.getRow(i); + XSSFRow rowGen = sheetGen.getRow(i); + for (int j = 0; j < rowRef.getLastCellNum(); j++) { + XSSFCell cellRef = rowRef.getCell(j); + XSSFCell cellGen = rowGen.getCell(j); + System.out.println(cellRef.getReference()); + System.out.println(cellGen.getReference()); + softAssert.assertThat(df.formatCellValue(cellGen)).isEqualTo(df.formatCellValue(cellRef)); + } + } + } + } + } + softAssert.assertAll(); + } +} \ No newline at end of file diff --git a/kurt-utility/src/val/java/compare/Comparer_XML.java b/kurt-utility/src/val/java/compare/Comparer_XML.java new file mode 100644 index 0000000..4454aa7 --- /dev/null +++ b/kurt-utility/src/val/java/compare/Comparer_XML.java @@ -0,0 +1,112 @@ +package compare; + +import javax.xml.parsers.DocumentBuilderFactory; + +import com.capgemini.framework.teamcenter.authent.AuthentPropLoader; +import lombok.val; +import org.w3c.dom.*; +import org.xml.sax.SAXException; +import javax.xml.parsers.*; +import javax.xml.transform.*; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.File; +import java.io.IOException; + + + +public class Comparer_XML { + + private static String URLXmlComp = AuthentPropLoader.getString("com.capgemini.report.location.default.outputXml");; + + + public static void writerFile(String entry, CriteresComparaison criteresComparaison){ + + String filePath = entry; + File xmlFile = new File(filePath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder; + try { + dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(xmlFile); + doc.getDocumentElement().normalize(); + NodeList node = doc.getElementsByTagName("TestUnitaire"); + Element rap = null; + Element plateforme; + Element report; + Element typeFile; + Element UseCase; + Element nameFileWithDate; + Element locationFileReference; + Element nameSheetFileReference; + + for (int i = 0; i < node.getLength(); i++) { + rap = (Element) node.item(i); + plateforme = doc.createElement("plateforme"); + plateforme.setAttribute("name",criteresComparaison.getPlateforme()); + report = doc.createElement("report"); + report.setAttribute("id",criteresComparaison.getReport()); + typeFile = doc.createElement("typeFile"); + typeFile.setAttribute("name",criteresComparaison.getTypeFile()); + UseCase = doc.createElement("UseCase"); + UseCase.setAttribute("id",criteresComparaison.getUseCase()); + nameFileWithDate = doc.createElement("nameFileWithDate"); + nameFileWithDate.appendChild(doc.createTextNode(criteresComparaison.getNameFileWithDate())); + locationFileReference = doc.createElement("locationFileGenerated"); + locationFileReference.appendChild(doc.createTextNode(criteresComparaison.getLocationFileReference())); + nameSheetFileReference = doc.createElement("nameSheetFileGenerated"); + nameSheetFileReference.appendChild(doc.createTextNode(criteresComparaison.getNameSheetFileReference())); + UseCase.appendChild(nameFileWithDate); + UseCase.appendChild(locationFileReference); + UseCase.appendChild(nameSheetFileReference); + typeFile.appendChild(UseCase); + report.appendChild(typeFile); + plateforme.appendChild(report); + rap.appendChild(plateforme); + + } + + doc.getDocumentElement().normalize(); + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + DOMSource source = new DOMSource(doc); + StreamResult result = new StreamResult(new File(URLXmlComp)); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.transform(source, result); + + + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (SAXException e) { + e.printStackTrace(); + } catch (TransformerConfigurationException e) { + e.printStackTrace(); + } catch (TransformerException e) { + e.printStackTrace(); + } + } + + + public static void creerEntry(String nomEntre) { + + try { + DocumentBuilderFactory XML_Comparaison = DocumentBuilderFactory.newInstance(); + DocumentBuilder XML_Comp = XML_Comparaison.newDocumentBuilder(); + Document XML_Document = XML_Comp.newDocument(); + Element TestUnitaire = XML_Document.createElement("TestUnitaire"); + XML_Document.appendChild(TestUnitaire); + TransformerFactory XMLTransformeur = TransformerFactory.newInstance(); + Transformer XML_Transformeur = XMLTransformeur.newTransformer(); + DOMSource source = new DOMSource(XML_Document); + StreamResult resultat = new StreamResult(new File(nomEntre)); + XML_Transformeur.transform(source, resultat); + } catch (ParserConfigurationException pce) { + pce.printStackTrace(); + } catch (TransformerException tfe) { + tfe.printStackTrace(); + } + } + +} diff --git a/kurt-utility/src/val/java/compare/CriteresComparaison.java b/kurt-utility/src/val/java/compare/CriteresComparaison.java new file mode 100644 index 0000000..123262a --- /dev/null +++ b/kurt-utility/src/val/java/compare/CriteresComparaison.java @@ -0,0 +1,54 @@ +package compare; + +/** + * Created by mfarouj on 21/06/2017. + */ +public class CriteresComparaison { + + String plateforme; + String report; + String typeFile; + String UseCase; + String nameFileWithDate; + String locationFileReference; + String nameSheetFileReference; + + public CriteresComparaison(String plateforme, String report, String typeFile, String useCase, + String nameFileWithDate, String locationFileReference, String nameSheetFileReference) { + this.plateforme = plateforme; + this.report = report; + this.typeFile = typeFile; + UseCase = useCase; + this.nameFileWithDate = nameFileWithDate; + this.locationFileReference = locationFileReference; + this.nameSheetFileReference = nameSheetFileReference; + } + + public String getPlateforme() { + return plateforme; + } + + public String getReport() { + return report; + } + + public String getTypeFile() { + return typeFile; + } + + public String getUseCase() { + return UseCase; + } + + public String getNameFileWithDate() { + return nameFileWithDate; + } + + public String getLocationFileReference() { + return locationFileReference; + } + + public String getNameSheetFileReference() { + return nameSheetFileReference; + } +} diff --git a/kurt-utility/src/val/java/compare/ExcelTest.java b/kurt-utility/src/val/java/compare/ExcelTest.java new file mode 100644 index 0000000..6cf8d63 --- /dev/null +++ b/kurt-utility/src/val/java/compare/ExcelTest.java @@ -0,0 +1,152 @@ +/* +package compare; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.builder.R01Builder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.DataFormatter; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.testng.annotations.*; +import org.testng.annotations.Optional; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.*; + +import static org.assertj.core.api.Assertions.assertThat; + + +@Slf4j +public abstract class ExcelTest { + private static final TcSession session = new TcSession(); + // Dossier parent du fichier de référence + private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input"; + // Sous-dossier du fichier de référence + private static final String SPECIFIC_INPUT_FOLDER = ""; + // Dossier de stockage temporaire des fichiers générés initialement + private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output"; + // Dossier de stockage final des fichiers + private static final String RECORDS_FOLDER = "com.capgemini.report.location.default.records"; + // Type de fichier traités + private static final String SUFFIX = ""; + private static final PolicyLocation XML_POLICY = + PolicyLocation.make("test_policy", "/test_policy.xml"); + private Properties localproperties; + + + @BeforeClass + public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + localproperties = new Properties(); + localproperties.load(getClass().getResourceAsStream("/reporting.properties")); + } + + @AfterClass + public void logout() { + session.close(); + } + + //@BeforeMethod + //TODO : Supprimer xls files dans Generated, checker Tempfile TempDirectory + + + @Parameters({"productID", "unit", "monomulti", "effectivityDate", "genericAssemb", "generic", "refFile"}) + @Test + public void test01 (String productID, Integer unit, String monomulti, @Optional String + effectivityDate, @Optional String genericAssemb, @Optional String generic, String refFile) throws + KurtException, IOException { + // Génération du rapport de test + Map data = new HashMap<>(); + data.put(ReportCriteriaEnum.PRODUCT, productID); + data.put(ReportCriteriaEnum.UNIT, unit.toString()); + data.put(ReportCriteriaEnum.MONO_MULTI, monomulti); + data.put(ReportCriteriaEnum.GENERIC, generic); + data.put(ReportCriteriaEnum.GENERIC_ASSEMB, genericAssemb); + data.put(ReportCriteriaEnum.EFFECTIVITY_DATE, effectivityDate); + + ExecutionR01 execution = new R01Builder().build(data); + String print = new DataReportPreparatorR01().print(session, execution, new ImmediateExecutionStrategy()); + + FileInputStream fileInput = new FileInputStream( + new File(localproperties.getProperty(INPUT_FOLDER) + "/" + SPECIFIC_INPUT_FOLDER + "/" + refFile)); + XSSFWorkbook workbookRef = new XSSFWorkbook(fileInput); + + File generatedFile = new File(localproperties.getProperty(TEMPORARY_OUTPUT_FOLDER) + execution.getFileNameOnDisc() + SUFFIX); + FileInputStream fileOutput = new FileInputStream(generatedFile); + XSSFWorkbook workbookGen = new XSSFWorkbook(fileOutput); + + if (workbookRef.getNumberOfSheets() == workbookGen.getNumberOfSheets()) { + for (int h = 0; h < workbookGen.getNumberOfSheets() && h < workbookRef.getNumberOfSheets(); h++) { + // Un fichier excel est composé de plusieurs feuilles, on y accède de la manière suivante + XSSFSheet sheetRef = workbookRef.getSheetAt(h); + XSSFSheet sheetGen = workbookRef.getSheetAt(h); + DataFormatter df = new DataFormatter(); + for (int i = 2; i < sheetRef.getLastRowNum(); i++) { + XSSFRow rowRef = sheetRef.getRow(i); + XSSFRow rowGen = sheetGen.getRow(i); + for (int j = 0; j < rowRef.getLastCellNum(); j++) { + XSSFCell cellRef = rowRef.getCell(j); + XSSFCell cellGen = rowGen.getCell(j); + assertThat(df.formatCellValue(cellGen)).isEqualTo(df.formatCellValue(cellRef)); + } + } + } + } + move(generatedFile); + } + + private void move (File file) { + file.renameTo(new File (localproperties.getProperty(RECORDS_FOLDER) + SPECIFIC_INPUT_FOLDER + "/" + file.getName())); + System.out.println("File is moved successfully!"); + } +} + + + + +*/ +/* for (int i = 2; i < sheetRef.getLastRowNum() + 1; i++) { + Cell cell = sheetRef.getRow(i).getCell(i); + if (df.formatCellValue(cell).equals(df.formatCellValue(sheetGen.getRow(i).getCell(0)))) + { //If cell is the same value as the one in the row below it + System.out.println("Test réussi"); + } else + {//If cell has a different value as the one in the row below it + System.out.println("Test échec"); + } + }*//* + + + +*/ +/* for (int i = 0; i < sheetRef.getPhysicalNumberOfRows(); i++) { + assertThat(sheetRef.getRow(i).equals(sheetGen.getRow(i))).isTrue(); + }*//* + + +*/ +/* + List sheetNamesRef = new ArrayList(); + List sheetNamesGen = new ArrayList(); + for (int i=0; i +com.capgemini.report.common.MailHelper.defaultSmtpPort=25 +com.capgemini.report.common.MailHelper.defaultExpeditorMail=reporting.tool@capgemini.com +com.capgemini.report.common.MailHelper.defaultExpeditorPassword= +# Default recipient eMail addresses (comma-separated) +com.capgemini.report.common.MailHelper.defaultDestinatorMail=${email.defaultDestinatorMail} + +# Printing locations +com.capgemini.report.location.default.input=D:/Users/jpaulino/Documents/PV_Snecma/Reports/kurt/kurt-utility/src/val/resources/FolderFilesReferenced/ +com.capgemini.report.location.default.output=D:/kurt/compare/FolderFilesGenerated/ +com.capgemini.report.location.default.extract.folder.r23=D:/kurt/compare/FolderFilesGenerated/r23 +com.capgemini.report.location.default.extract.folder.r24=D:/kurt/compare/FolderFilesGenerated/r24 + +com.capgemini.report.location.scheduling.output=C:/kurt/Jasper/scheduling/output/ +com.capgemini.report.location.scheduling.history.output=C:/kurt/Jasper/scheduling/history/ +com.capgemini.report.download.URL=${download.URL} + +# Configuration resolution parameters +com.capgemini.report.common.bom.revisionRule.default=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R01=\ DMA Configuration Interface + +com.capgemini.report.common.bom.revisionRule.REPORT_R03=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R05=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R06=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R07=\ DMA Configuration Rapport PU +com.capgemini.report.common.bom.revisionRule.REPORT_R10=\ DMA Configuration Validated +com.capgemini.report.common.bom.revisionRule.REPORT_R11=\ DMA Configuration Mockup Best So Far +com.capgemini.report.common.bom.revisionRule.REPORT_R13=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R15=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_W15=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R16=\ DMA Configuration Validated +com.capgemini.report.common.bom.revisionRule.REPORT_R17=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R19=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R20=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R21=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R22=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_W22=\ DMA Configuration Interface +com.capgemini.report.common.bom.revisionRule.REPORT_R23=\ DMA Configuration Rapport PU +com.capgemini.report.common.bom.revisionRule.REPORT_R24=\ DMA Configuration Validated +com.capgemini.report.common.bom.revisionRule.REPORT_R25=\ DMA Configuration Descriptif R25 +com.capgemini.report.common.bom.revisionRule.REPORT_R26=\ DMA Configuration Interface + + +# Teamcenter limit for retrieving records from a saved query +com.capgemini.report.teamcenter.queries.methods.maxQuery=50 +com.capgemini.report.teamcenter.queries.methods.paging=25 + +com.capgemini.report.jsp.defaultPaging=12 + +# List of Product types available (comma-separated, like '120,238,410,700,80C,80E,850,8LM,900,970', without the ''): +com.capgemini.report.product.list=120,238,410,700,80C,80E,850,8LM,900,970 + +# Report titles +com.capgemini.report.title.REPORT_R01=BOM assemblage PU +com.capgemini.report.title.REPORT_R03=BOM fabrication date +com.capgemini.report.title.REPORT_R05=BOM Multi récepteursPU +com.capgemini.report.title.REPORT_R06=Statut Def et Indus PU +com.capgemini.report.title.REPORT_R07=Comparaison BOM PU +com.capgemini.report.title.REPORT_R10=Documents associés générique +com.capgemini.report.title.REPORT_R11=Mise en maquette et cohérence +com.capgemini.report.title.REPORT_R13=Etat avancement processus +com.capgemini.report.title.REPORT_R15=Fiche article +com.capgemini.report.title.REPORT_W15=Fiche article +com.capgemini.report.title.REPORT_R16=Fiche générique +com.capgemini.report.title.REPORT_R17=Liste documents associés article +com.capgemini.report.title.REPORT_R19=Cas utilisation document +com.capgemini.report.title.REPORT_R20=Gel de UNIT +com.capgemini.report.title.REPORT_R21=Compare Net +com.capgemini.report.title.REPORT_R22=BOM fabrication date PDF eDOC +com.capgemini.report.title.REPORT_W22=BOM fabrication date PDF eDOC +com.capgemini.report.title.REPORT_R23=Bom assemblage PU(s) +com.capgemini.report.title.REPORT_R24=Fiche(s) générique(s) +com.capgemini.report.title.REPORT_R25=Liste des documents des génériques +com.capgemini.report.title.REPORT_R26=Cas d'emploi d'un article + + +# Report priorities (1=High, 2=Medium, 3=Low) +com.capgemini.report.priority.REPORT_R01=2 +com.capgemini.report.priority.REPORT_R03=1 +com.capgemini.report.priority.REPORT_R05=3 +com.capgemini.report.priority.REPORT_R06=3 +com.capgemini.report.priority.REPORT_R07=3 +com.capgemini.report.priority.REPORT_R10=3 +com.capgemini.report.priority.REPORT_R11=2 +com.capgemini.report.priority.REPORT_R13=2 +com.capgemini.report.priority.REPORT_R15=1 +com.capgemini.report.priority.REPORT_W15=1 +com.capgemini.report.priority.REPORT_R16=1 +com.capgemini.report.priority.REPORT_R17=1 +com.capgemini.report.priority.REPORT_R19=1 +com.capgemini.report.priority.REPORT_R20=2 +com.capgemini.report.priority.REPORT_R21=3 +com.capgemini.report.priority.REPORT_R22=1 +com.capgemini.report.priority.REPORT_W22=1 +com.capgemini.report.priority.REPORT_R23=2 +com.capgemini.report.priority.REPORT_R24=1 +com.capgemini.report.priority.REPORT_R25=1 +com.capgemini.report.priority.REPORT_R26=1 + + +# Report launch type parameters (immediate or delayed) +com.capgemini.report.common.launch.launchType.default=immediate +com.capgemini.report.common.launch.launchType.REPORT_R01=immediate +com.capgemini.report.common.launch.launchType.REPORT_R03=immediate +com.capgemini.report.common.launch.launchType.REPORT_R05=immediate +com.capgemini.report.common.launch.launchType.REPORT_R06=immediate +com.capgemini.report.common.launch.launchType.REPORT_R07=immediate +com.capgemini.report.common.launch.launchType.REPORT_R10=immediate +com.capgemini.report.common.launch.launchType.REPORT_R11=immediate +com.capgemini.report.common.launch.launchType.REPORT_R13=immediate +com.capgemini.report.common.launch.launchType.REPORT_R15=immediate +com.capgemini.report.common.launch.launchType.REPORT_W15=immediate +com.capgemini.report.common.launch.launchType.REPORT_R16=immediate +com.capgemini.report.common.launch.launchType.REPORT_R17=immediate +com.capgemini.report.common.launch.launchType.REPORT_R19=immediate +com.capgemini.report.common.launch.launchType.REPORT_R20=immediate +com.capgemini.report.common.launch.launchType.REPORT_R21=immediate +com.capgemini.report.common.launch.launchType.REPORT_R22=immediate +com.capgemini.report.common.launch.launchType.REPORT_W22=immediate +com.capgemini.report.common.launch.launchType.REPORT_R23=immediate +com.capgemini.report.common.launch.launchType.REPORT_R24=immediate +com.capgemini.report.common.launch.launchType.REPORT_R25=immediate +com.capgemini.report.common.launch.launchType.REPORT_R26=immediate + + +# Report delayed hour (HH:mm) +com.capgemini.report.common.launch.delayed.hour=16:03 + +# Purge hour (HH:mm) +com.capgemini.report.common.launch.purge.hour=11:01 + +# Number days for purge on report and scheduling report +com.capgemini.report.nb.days=60 +com.capgemini.report.nb.days.scheduling=60 + +# Technical settings for memory monitoring +com.capgemini.report.MngMemMonitor.maxTraceCount=50 +com.capgemini.report.MngMemMonitor.frequency=10 + +#com.capgemini.report.devmode=${devmode} +#com.capgemini.report.valmode=${valmode} +com.capgemini.report.devmode=true +com.capgemini.report.valmode=true +com.capgemini.report.cleanup=false + +# PIC FTP accesses for uploading generated files +com.capgemini.report.FTPUtility.host=${ftp.pic.host} +com.capgemini.report.FTPUtility.port=${ftp.pic.port} +com.capgemini.report.FTPUtility.login=${ftp.pic.login} +com.capgemini.report.FTPUtility.password=${ftp.pic.password} +com.capgemini.report.FTPUtility.targetFolder=${ftp.pic.targetFolder} +com.capgemini.report.optimized.folder.R23=C:/kurt/input/R23 +com.capgemini.report.optimized.folder.R24=C:/kurt/input/R24 diff --git a/kurt-utility/src/val/resources/testng.xml b/kurt-utility/src/val/resources/testng.xml new file mode 100644 index 0000000..701d5f8 --- /dev/null +++ b/kurt-utility/src/val/resources/testng.xml @@ -0,0 +1,694 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-utility/src/val/resources/testng.yaml b/kurt-utility/src/val/resources/testng.yaml new file mode 100644 index 0000000..f05c161 --- /dev/null +++ b/kurt-utility/src/val/resources/testng.yaml @@ -0,0 +1,179 @@ +name: Validation Test Suite +threadCount: 4 + +tests: + - name: test01 + parameters: + productID: 65A1 + unit: 20 + monomulti: Mono + generic: + genericAssemb: + effectivityDate: 01-01-2015 + refFile: r01.xlsx + classes: + - com.capgemini.reports.definition.r01report.Test_R01 + + - name: test03 + parameters: + partId: 307-084-738-0 + partRev: A + refFile: r03.xlsx + classes: + - com.capgemini.reports.definition.r03report.Test_R03 + + - name: test07 + parameters: + productID: 35R0 + unit1: 30 + unit2: 60 + generic: N24 + genericAssemb: + refFile: r07.xlsx + classes: + - com.capgemini.reports.definition.r07report.Test_R07 + + - name: test10 + parameters: + productID: ZZ01 + unit: 1 + monomulti: Mono + effectivity: 14-07-2014 + generic: A10 + genericAssemb: + refFile: r10.xlsx + classes: + - com.capgemini.reports.definition.r10report.Test_R10 + + - name: test11 + parameters: + productID: SS01 + unit: 1 + monomulti: Mono + effectivity: 15-09-2015 + generic: A11 + vueMont: + refFile: r11.xlsx + classes: + - com.capgemini.reports.definition.r11report.Test_R11 + + - name: test13_cr + parameters: + objectType: CR + beginDate: 01-10-2015 + endDate: 27-10-2015 + refFile: r13_cr.xlsx + classes: + - com.capgemini.reports.definition.r13report.Test_CrR13 + + - name: test13_fpp + parameters: + objectType: FPP + beginDate: 01-10-2015 + endDate: 27-10-2015 + refFile: r13_fpp.xlsx + classes: + - com.capgemini.reports.definition.r13report.Test_FppR13 + + - name: test15 + parameters: + language: Francais + partId: 307-084-738-0 + partRevision: A + refFile: r15.pdf + classes: + - com.capgemini.reports.definition.r15report.Test_R15 + + - name: test16 + parameters: + product: 29R0 + unitStr: 245 + idTopGeneric: C25 + typeImpression: Def_certifiee + language: Francais + refFile: r16.pdf + classes: + - com.capgemini.reports.definition.r16report.Test_R16 + + - name: test17 + parameters: + partId: 307-098-542-0 + partRevision: A + language: Francais + refFile: r17.pdf + classes: + - com.capgemini.reports.definition.r17report.Test_R17 + + - name: test19 + parameters: + docId: 00065451 + revision: --A + typeObject: DocDrawing Revision + refFile: r19.xlsx + classes: + - com.capgemini.reports.definition.r19report.Test_R19 + + - name: test20 + parameters: + prodIDBefore: R201 + prodIDAfter: R201 + unitBefore: 1 + unitAfter: 5 + matricule: Moteurs n°204-209 + listModif: '-' + classe: 1 + majMin: Mineur + conjoint: CONJOINT + refFile: r20.pdf + classes: + - com.capgemini.reports.definition.r20report.Test_R20 + + - name: test21 + parameters: + generic: E24 + genericAssemb: 24E + productID: 30E0 + unit: 20 + effectivity: 01-01-2015 + refFile: r21.xlsx + classes: + - com.capgemini.reports.definition.r21report.Test_R21 + + - name: test22 + parameters: + partID: 307-084-738-0 + partRevisionID: A + refFile: r22.pdf + classes: + - com.capgemini.reports.definition.r22report.Test_R22 + + - name: test23 + parameters: + productID: RP23 + genericTech: + genericMontage: + monomulti: Multi + EffectivityDate: 05-01-2017 + refFile: r23.zip + classes: + - com.capgemini.reports.definition.r23report.Test_R23 + + - name: test24 + parameters: + productID: RP24 + unit: 10 + typeImpr: Def_realisation + language: Anglais + refFile: r24.zip + classes: + - com.capgemini.reports.definition.r24report.Test_R24 + + - name: test25 + parameters: + productID: 35R0 + unit: + typeImpression: Définition certifiée + language: Francais + refFile: r25.zip + classes: + - com.capgemini.reports.definition.r25report.Test_R25 \ No newline at end of file diff --git a/kurt-web/pom.xml b/kurt-web/pom.xml new file mode 100644 index 0000000..43efeb9 --- /dev/null +++ b/kurt-web/pom.xml @@ -0,0 +1,136 @@ + + + 4.0.0 + kurt-web + war + kurt-web + + + com.capgemini.reports + kurt + 1.32.9 + + + + + com.capgemini.reports + kurt-ejb + 1.32.9 + + + + junit + junit + test + + + org.mockito + mockito-core + test + + + + org.slf4j + slf4j-api + + + + org.projectlombok + lombok + + + + org.json + json + + + + org.jboss.spec.javax.annotation + jboss-annotations-api_1.1_spec + + + + + org.jboss.spec.javax.servlet + jboss-servlet-api_3.0_spec + + + + + + + + + org.springframework + spring-test + 2.5 + test + + + org.springframework + spring-core + 4.1.1.RELEASE + test + + + + + + org.hibernate + hibernate-entitymanager + 4.0.1.Final + + + org.hibernate + hibernate-validator + 4.2.0.Final + + + org.hibernate + hibernate-core + 4.0.1.Final + + + + com.hp.gagawa + gagawa + 1.0.1 + + + + + org.jboss.netty + netty + provided + + + com.capgemini + spnegobasic + 1.0.0 + + + + + + + + org.apache.maven.plugins + maven-war-plugin + + true + + + true + src/main/webapp + + index.jsp + + + + + + + + + + diff --git a/kurt-web/src/main/java/com/capgemini/reports/DispatcherServlet.java b/kurt-web/src/main/java/com/capgemini/reports/DispatcherServlet.java new file mode 100644 index 0000000..cb360f2 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/DispatcherServlet.java @@ -0,0 +1,91 @@ +package com.capgemini.reports; + +import com.capgemini.reports.formatting.ErrorPageTemplate; +import lombok.extern.slf4j.Slf4j; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** Forwards the request to the report's own jsp. */ +@Slf4j +@WebServlet("/dispatcherServlet") +public class DispatcherServlet extends HttpServlet { + + private static final long serialVersionUID = 490514018643346053L; + + /** + * URL pattern.
    + * There are 3 matching possibilities: + *

      + *
    1. "REPORT_R" followed by an optional "B" for RB01 reports followed by a two-digit number "XX"
    2. + *
    3. An optional series of all-alpha words preceded by whitespace like "_Document_Revision"
    4. + *
    5. "&" separator then anything that isn't a whitespace, then the end of the string
    6. + *
    + * + * So these work: + *
      + *
    • REPORT_R01
    • + *
    • REPORT_R20
    • + *
    • REPORT_R19
    • + *
    • REPORT_R15_A
    • + *
    • REPORT_R15_B
    • + *
    • REPORT_R19_Document_Revision
    • + *
    • REPORT_R19_Document
    • + *
    • REPORT_R19_Document_Revision
    • + *
    • REPORT_R19&truc=machin
    • + *
    • REPORT_RB05
    • + *
    • REPORT_RB01
    • + *
    + * And these don't: + *
      + *
    • REPORT_R011
    • + *
    • RAPORT_R01
    • + *
    • REPORT_RB1
    • + *
    • REPORT_RB6
    • + *
    • REPORT_R15A
    • + *
    • REPORT_R19_Document-Revision
    • + *
    + */ + private static final String URL_PATTERN = "(REPORT_RB?[0-9][0-9])(_[A-Za-z]+)*(&[\\S]*)?$"; + + /** + * Forwards the request to the appropriate web page. + * + * @param aRequest The user request + * @param aResponse The expected response + * @throws ServletException + * @throws IOException + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) + */ + @Override + protected void doGet(final HttpServletRequest aRequest, final HttpServletResponse aResponse) throws ServletException, IOException { + ServletContext context = getServletContext(); + + String theUrl = aRequest.getQueryString(); + Pattern pattern = Pattern.compile(URL_PATTERN); + Matcher matcher = pattern.matcher(theUrl); + if (matcher.find()) { + final String reportId = matcher.group(1); // Group 0 is the whole string, group 1 is REPORT_RXX + String target = "/index.jsp?rd_id=" + reportId.toLowerCase(Locale.FRENCH); + RequestDispatcher dispatcher = context.getRequestDispatcher(target); + // Will go to each report's report_rXX.html + dispatcher.forward(aRequest, aResponse); + } + else { + String theErrorTitle = "Unable to download file"; + String theErroMessage = "Could not extract target report of the form \"" + URL_PATTERN + "\" in request URL parameters"; + log.error(theErrorTitle + ": " + theErroMessage + " = " + theUrl); + ErrorPageTemplate theErrorTemplate = new ErrorPageTemplate(theErrorTitle, theErroMessage); + aResponse.getWriter().write(theErrorTemplate.generateCode()); + } + } +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/auto/AbstractAutoLaunchServlet.java b/kurt-web/src/main/java/com/capgemini/reports/auto/AbstractAutoLaunchServlet.java new file mode 100644 index 0000000..8022522 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/auto/AbstractAutoLaunchServlet.java @@ -0,0 +1,160 @@ +package com.capgemini.reports.auto; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.framework.common.activedirectory.ActiveDirectory; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.database.DataBaseReportHelper; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.database.javabean.DbUser.UserData; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.database.manager.MngUser; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.exceptions.InvalidActiveDirectorySearchException; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.NoConnectionToActiveDirectoryException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.logging.ReportLoggerHelper; +import com.capgemini.reports.queuing.EmbeddedServer; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.HibernateException; +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +import javax.jms.JMSException; +import javax.naming.NamingException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +/** + * An abstract {@link HttpServlet} for classes that launch a report from an automatic Workflow request.
    + * This servlet expects the Tc workflow owner to be passed as parameter: http:\\[URL]?[parameters]&userID=toto[&...] + * + * @param the exact {@link AbstractExecutionReport} report type + */ +@Slf4j +public abstract class AbstractAutoLaunchServlet> extends HttpServlet { + + private static final long serialVersionUID = -8586399099581830304L; + + private static final String URL_PARAMETER_OWNER_LOGIN = "userID"; + + private static final boolean DEV_MODE = SettingsHelper.isDevMode(); + + @Override + protected void doGet(final HttpServletRequest aRequest, final HttpServletResponse aResponse) throws IOException { + String relaunchURL = makeRelaunchURL(aRequest); + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + // Register owner + final DbUser dbUser = retrieveUserInAdAndDb(session, aRequest); + + // Generate the report definition + T report = processFunctionalParams(aRequest); + + // Prepare execution roadmap + setupSchedulingStrategy(relaunchURL, report); + + // Prepare the report execution parameters + List launchData = report.getLaunchData(); + String reportCode = report.getReportIdentifier().getReportCode(); + log.info("Server received a request to perform a {} report from WKF, owned by user {} with parameters: {}", reportCode, dbUser.getLogin(), + launchData); + + // Register current time as the posting time + report.setPostingTime(TeamcenterDateFormatter.getCurrentTime()); + + // Post the report into the queues + EmbeddedServer.produce(report); + + // Record the report launch in the database, and log this + DbReport theReportEntry = DataBaseReportHelper.registerLaunch(report, dbUser); + + // Log the report request (AFTER the email is sent, so that the report knows its startTime) + ReportLoggerHelper.logRequest(dbUser, theReportEntry, report); + // Normal processing termination, return success code + aResponse.setStatus(HttpServletResponse.SC_NO_CONTENT); // Successful, but no content to return + } + catch (KurtException | JMSException | NamingException e) { + aResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST); // 400 Bad Request + aResponse.getWriter().write(e.getMessage()); + log.warn(e.getMessage(), e); + } + finally { + try { + session.close(); + } + catch (HibernateException e) { + log.error(e.getMessage(), e); + } + } + } + + protected abstract void setupSchedulingStrategy(String relaunchURL, T report); + + private String makeRelaunchURL(HttpServletRequest aRequest) { + StringBuffer requestURL = aRequest.getRequestURL(); + String queryString = aRequest.getQueryString(); + String fullURL; + if (queryString == null) { + fullURL = requestURL.toString(); + } + else { + fullURL = requestURL.append('?').append(queryString).toString(); + } + return fullURL; + } + + @Override + protected void doPost(final HttpServletRequest aRequest, final HttpServletResponse aResponse) throws IOException { + doGet(aRequest, aResponse); + } + + /** + * Retrieve/update the DB User.
    + * Steps followed: + *
      + *
    1. fetch the user UID in the URL
    2. + *
    3. Obtain the TC object 'User' with this UID
    4. + *
    5. Read user login from Tc user
    6. + *
    7. Request ActiveDirectory for Data about this login (email, names etc.)
    8. + *
    9. Fetch/Update/Create the user in the DB accordingly.
    10. + *
    + */ + private DbUser retrieveUserInAdAndDb(Session session, final HttpServletRequest aRequest) throws InsufficientParametersException, + NoConnectionToActiveDirectoryException, InvalidActiveDirectorySearchException, InvalidInputException { + // Parse user ID + String ownerLogin = aRequest.getParameter(URL_PARAMETER_OWNER_LOGIN); + if (ownerLogin == null || ownerLogin.isEmpty()) { + throw new InsufficientParametersException("No user UID was provided in URL"); + } + + // Find this same login in the ActiveDirectory + UserData adUser; + if (DEV_MODE) { + adUser = ActiveDirectory.getGuestUser(); + } + else { + adUser = ActiveDirectory.obtainUserData(ownerLogin); + } + + // Find / update / create corresponding user in DB + return new MngUser().fetchOrUpdateOrCreateUser(session, adUser); + } + + /** + * Generates a report according the the request. + * + * @param aRequest the {@link HttpServletRequest} + * @return a report Execution + * @throws InsufficientParametersException + */ + protected abstract T processFunctionalParams(final HttpServletRequest aRequest) throws InsufficientParametersException; + +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/AbstractKurtServlet.java b/kurt-web/src/main/java/com/capgemini/reports/common/AbstractKurtServlet.java new file mode 100644 index 0000000..cbc4857 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/AbstractKurtServlet.java @@ -0,0 +1,165 @@ +package com.capgemini.reports.common; + +import com.capgemini.framework.common.MapHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.exceptions.runtime.ConnectionLostException; +import com.capgemini.reports.exceptions.DuplicateReportEntryFound; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import lombok.extern.slf4j.Slf4j; +import org.json.JSONObject; +import org.quartz.SchedulerException; + +import javax.jms.JMSException; +import javax.naming.NamingException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +/** Abstract class providing a framework for all servlets communicating with the application. **/ +@Slf4j +public abstract class AbstractKurtServlet extends HttpServlet { + private static final long serialVersionUID = 7233193093588056531L; + + private static final String CONTENT_TYPE_JSON = "application/json"; + + /** + * Receives user input, forwards to the actual implementation in .
    + * If the report could not be posted in the queue, then the resulting {@link JMSException} will be caught here, and a standardized failure message will be sent back to the server. + * + * @param request the user request + * @param response the response (a JSON object) + * @throws ServletException + * @throws IOException + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) + */ + @Override + protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { + // Parse server request parameters + processParams(request); + + JSONObject computedResponse; + try (TcSession session = new TcSession()) { + session.login(); + computedResponse = perform(request, session); + response.setContentType(CONTENT_TYPE_JSON); + response.getWriter().write(computedResponse.toString()); + } catch (DuplicateReportEntryFound e) { + // The user is requesting a report with specific criteria, but a similar request has been made recently. + log.debug("A Previous similar report execution request has been found, adding user to wishlist for this report.", e); + response.setContentType(CONTENT_TYPE_JSON); + response.getWriter().write(ServletMessageHelper.successMessage(e.getErrorMessageForUser()).toString()); + } catch (InvalidUserInputException e) { + // A nice error message will be sent to the user to tell him what he did wrong + log.error(e.getMessage(), e); + response.setContentType(CONTENT_TYPE_JSON); + response.getWriter().write(ServletMessageHelper.errorMessage(e).toString()); + } catch (NamingException e) { + // Error due to miscommunication with the JMS queuing system + log.error(ServletMessageHelper.POSTING_ERROR_MESSAGE_EN, e); + response.getWriter().write(ServletMessageHelper.errorMessage(e).toString()); + } catch (JMSException e) { + // Error due to miscommunication with the JMS queuing system + log.error(ServletMessageHelper.POSTING_ERROR_MESSAGE_EN, e); + response.getWriter().write(ServletMessageHelper.errorMessage(e).toString()); + } catch (SchedulerException e) { + // Error due to miscommunication with the scheduler system + log.error("Error caught while trying to delay the report.", e); + response.getWriter().write(ServletMessageHelper.errorMessage(e).toString()); + } catch (NoTeamcenterConnectionException e) { + // Error due to miscommunication with the Teamcenter servers + log.error("Unable to connect to the Teamcenter server", e); + response.getWriter().write(ServletMessageHelper.errorMessage(e).toString()); + } catch (ConnectionLostException e) { + // Runtime exception, happens when connection is suddenly lost and not recovered despite attempts to do so + log.error("Connection lost to Teamcenter server", e); + response.getWriter().write(ServletMessageHelper.errorMessage(e).toString()); + } + } + + /** + * Forwarder of GET access to POST. + * + * @param request the user request + * @param response the response (a JSON object) + * @throws ServletException + * @throws IOException + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) + */ + @Override + protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { + doPost(request, response); + } + + /** + * Parsing method for JSP request parameters. + * + * @param aRequest + */ + private void processParams(final HttpServletRequest aRequest) { + if (!log.isDebugEnabled()) { + return; + } + // Parse headers + Map theParsingMap = new HashMap<>(); + Enumeration headerEnum = aRequest.getHeaderNames(); + while (headerEnum.hasMoreElements()) { + String currentHeader = headerEnum.nextElement(); + Object attribute = aRequest.getAttribute(currentHeader); + String currentValue = attribute == null ? "" : attribute.toString(); + theParsingMap.put(currentHeader, currentValue); + } + log.debug("Request headers: " + MapHelper.toString(theParsingMap)); + + // Parse attributes + theParsingMap = new HashMap<>(); + Enumeration attNameEnum = aRequest.getAttributeNames(); + while (attNameEnum.hasMoreElements()) { + String currentAtt = attNameEnum.nextElement(); + Object attribute = aRequest.getAttribute(currentAtt); + String currentValue = attribute == null ? "" : attribute.toString(); + theParsingMap.put(currentAtt, currentValue); + } + log.debug("Request attributes: " + MapHelper.toString(theParsingMap)); + + // Parse parameters + theParsingMap = new HashMap<>(); + Map parameterMap = aRequest.getParameterMap(); + for (Entry entry : parameterMap.entrySet()) { + String[] currentParamArray = entry.getValue(); + if (currentParamArray.length == 1) { + theParsingMap.put(entry.getKey(), currentParamArray[0]); + } else { + for (int i = 0; i < currentParamArray.length; i++) { + theParsingMap.put(entry.getKey() + "[" + i + "]", currentParamArray[i]); + } + } + } + log.debug("Request parameters: " + MapHelper.toString(theParsingMap)); + } + + /** + * This method will perform the job of the application.
    + * This method may throw a {@link InvalidInputException} with a nice failure message to the user.
    + * This method may throw any {@link KurtException} but, the user will receive a standardized failure message. + * + * @param request the request + * + * @return A {@link JSONObject} containing the response + * + * @throws JMSException can be thrown if the job could not be posted into the queues. + * @throws NamingException can be thrown when the required Queue could not be found + * @throws InvalidInputException when the user gave bad inputs. The exceptions should contain a nice error message, which will be sent to the user. + * @throws KurtException when some bug occurred. A generic error message will be sent to the user. + */ + protected abstract JSONObject perform(final HttpServletRequest request, final TcSession session) + throws JMSException, InvalidUserInputException, NamingException, SchedulerException; +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/AbstractSubmitServlet.java b/kurt-web/src/main/java/com/capgemini/reports/common/AbstractSubmitServlet.java new file mode 100644 index 0000000..ed471b3 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/AbstractSubmitServlet.java @@ -0,0 +1,177 @@ +package com.capgemini.reports.common; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.framework.common.activedirectory.ActiveDirectory; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.checkdata.CheckingDataHelper; +import com.capgemini.reports.database.DataBaseReportHelper; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.database.javabean.DbUser.UserData; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.database.manager.MngReport; +import com.capgemini.reports.database.manager.MngReport.RunningReportEntry; +import com.capgemini.reports.database.manager.MngReportOwner; +import com.capgemini.reports.database.manager.MngUser; +import com.capgemini.reports.exceptions.*; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.posting.DelayedPostingStategy; +import com.capgemini.reports.execution.posting.ImmediatePostingStrategy; +import com.capgemini.reports.logging.ReportLoggerHelper; +import com.capgemini.reports.quartz.SchedulerServer; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.json.JSONObject; +import org.quartz.SchedulerException; + +import javax.ejb.EJB; +import javax.jms.JMSException; +import javax.naming.NamingException; +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +/** + * Abstract class providing the framework for submitting and checking the necessary parameters to produce a report. + * + * @param the sub-class of AbstractExecutionReport that this servlet will generate + */ +@Slf4j +public abstract class AbstractSubmitServlet> extends AbstractKurtServlet { + private static final long serialVersionUID = -9065306729627250134L; + + @Getter + @EJB + protected SchedulerServer schedulingServer; + + @Override + protected JSONObject perform(final HttpServletRequest request, final TcSession tcSession) throws JMSException, + InvalidUserInputException, NamingException, SchedulerException { + // Identify the user using the LDAP + UserData adUser = identifyUser(request); + + // Prepare the report execution parameters + AbstractExecutionReport report = prepareReport(request); + List launchData = report.getLaunchData(); + String reportCode = report.getReportIdentifier().getReportCode(); + + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + // Find / update / create corresponding user in DB + DbUser dbUser = new MngUser().fetchOrUpdateOrCreateUser(session, adUser); + log.info("Server received a request to perform a {} report from user {} with parameters: {}", reportCode, dbUser.getLogin(), launchData); + + // Verify that the report has not been already requested not too long ago + List duplicates = new MngReport().searchQueuedReportsWithCriteria(session, report.getReportIdentifier(), launchData); + if (!duplicates.isEmpty()) { + // Previous report execution detected: this report is a duplicate + if (userOwnsOneReport(dbUser, duplicates)) { + // Forbidding same user to submit report twice + throw new DuplicateReportEntryFound(); + } + RunningReportEntry dupe = duplicates.get(0); + // Subscribing user to existing report execution + new MngReportOwner().subscribe(session, dbUser, dupe); + if (dbUser.getEmail() == null || dbUser.getEmail().isEmpty()) { + // This user does not have an email Address, send a warning email to the user + log.warn("Cet utilisateur abonné au résultat de ce rapport n’a pas d’adresse mail : {} {}", report.getReportIdentifier().getReportName(), dbUser.getLogin()); + } + throw new DuplicateReportEntryFound(dupe.getSafeName()); + } + + // Do a quick Check. If it fails, the exception thrown will carry a message to the user's webpage + log.debug("Report {} is not a duplicate, Beginning quick checks...", reportCode); + try { + CheckingDataHelper.doQuickCheck(tcSession, report); + } + catch (FileLoadingException e) { + log.error("Policy file could not be read", e); + return ServletMessageHelper.errorMessage(e); + } + log.debug("All quick checks have passed for {}", reportCode); + + // Register current time as the posting time + report.setPostingTime(TeamcenterDateFormatter.getCurrentTime()); + + // Perform the requested strategy: post immediately, or wait some delay + switch (report.getLaunchType()) { + case DELAYED: + new DelayedPostingStategy(schedulingServer).handleRequest(report); + break; + case IMMEDIATE: + new ImmediatePostingStrategy().handleRequest(report); + break; + default: + final String msg = + StringHelper.concatToString("Unable to perform the SUBMIT request, the execution strategy ", report.getLaunchType() + .toString(), " is unknwon for report ", report.getReportTechnicalUid()); + throw new UnsupportedOperationException(msg); + } + + // Record the report launch in the database, and log this + DbReport theReportEntry = DataBaseReportHelper.registerLaunch(report, dbUser); + + // Log the report request (AFTER the email is sent, so that the report knows its startTime) + ReportLoggerHelper.logRequest(dbUser, theReportEntry, report); + + // Return a success message + return sendSuccessMsg(report); + } + finally { + session.close(); + } + } + + private JSONObject sendSuccessMsg(final AbstractExecutionReport report) { + switch (report.getLaunchType()) { + case DELAYED: + // Return a nice success message to the user + return ServletMessageHelper.successMessage("Le rapport \"" + report.getReportIdentifier().getReportTitle() + + "\" est différé"); + default: + // This case is for IMMEDIATE type + return ServletMessageHelper.successMessage("Le rapport \"" + report.getReportIdentifier().getReportTitle() + + "\" a bien été soumis"); + } + } + + private boolean userOwnsOneReport(final DbUser dbUser, final List duplicates) { + for (RunningReportEntry report : duplicates) { + if (dbUser.getLogin() != null && dbUser.getLogin().equals(report.getLogin())) { + return true; + } + } + return false; + } + + private UserData identifyUser(final HttpServletRequest request) { + // Obtain userName, and user email through authentication + String userName = request.getRemoteUser(); + try { + return ActiveDirectory.obtainUserData(userName); + } + catch (NoConnectionToActiveDirectoryException e) { + log.warn("Could not connect to the AD to authenticate the user, using GUEST", e); + } + catch (InvalidInputException e) { + log.warn("AD Could not authenticate the user, using GUEST", e); + } + catch (InvalidActiveDirectorySearchException e) { + log.warn("Could not perform a search on the AD, using GUEST", e); + } + // Guest user when authentication failed + return ActiveDirectory.getGuestUser(); + } + + /** + * Provide the {@link AbstractExecutionReport} with the parameters. + * + * @param request the client request. + * @return the report execution, with its parameters checked, to be posted in the queues. + */ + public abstract T prepareReport(final HttpServletRequest request); +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/AbstractSubmitServletForItemRevision.java b/kurt-web/src/main/java/com/capgemini/reports/common/AbstractSubmitServletForItemRevision.java new file mode 100644 index 0000000..d93cd53 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/AbstractSubmitServletForItemRevision.java @@ -0,0 +1,35 @@ +package com.capgemini.reports.common; + +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import javax.servlet.http.HttpServletRequest; + +/** + * Abstract class providing the framework for submitting and checking the necessary parameters to produce a report on an {@link ItemRevision}. + * + * @param a subType of {@link AbstractExecutionReport} + */ +public abstract class AbstractSubmitServletForItemRevision> extends AbstractSubmitServlet { + + private static final long serialVersionUID = -3114366972057429074L; + + @Override + public T prepareReport(final HttpServletRequest request) { + // findAll parameters for KurtItemRevision + String partId = request.getParameter("num_article"); + String partRevision = request.getParameter("rev_article"); + return prepareReport(partId, partRevision, request); + } + + /** + * The main method. Builds an {@link AbstractExecutionReport} using the itemId, item Revision, and the request to eventually obtain additional parameters. + * + * @param itemId + * @param itemRev + * @param request + * @return + */ + protected abstract T prepareReport(final String itemId, final String itemRev, final HttpServletRequest request); + +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/DownloadServlet.java b/kurt-web/src/main/java/com/capgemini/reports/common/DownloadServlet.java new file mode 100644 index 0000000..1ae9a5d --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/DownloadServlet.java @@ -0,0 +1,127 @@ +package com.capgemini.reports.common; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbReport; +import com.capgemini.reports.database.manager.MngReport; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.formatting.ErrorPageTemplate; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +/** + * JSP Servlet for downloading file content from web GUI. + */ +@Slf4j +@WebServlet("/downloadServlet") +public class DownloadServlet extends HttpServlet { + private static final long serialVersionUID = 4856158363304758345L; + + private static final String OUTPUT_FOLDER = SettingsHelper.getReportLocation(); + private static final String OUTPUT_FOLDER_SCHEDULING_HISTORY = SettingsHelper.getSchedulingHistoryLocation(); + + private static final String UNABLE_TO_DOWNLOAD_FILE = "Unable to download the file"; + + @Override + protected void doGet(final HttpServletRequest aRequest, final HttpServletResponse aResponse) throws ServletException, IOException { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + // Check URL argument + String theReportUid = getMandatoryArg(aRequest, "reportUid"); + + MngReport theMngReport = new MngReport(); + DbReport theReport = theMngReport.searchByUid(theReportUid, session); + if (theReport == null) { + throw new NotFoundException("The report has not been found for uid: " + theReportUid); + } + + // Build file path + String theFilePathValue = makeFileName(theReport); + + // Secure file path + theFilePathValue = theFilePathValue.replace("..", "").replace("//", "/"); + + // Extract binary content + downloadFile(aResponse, theFilePathValue, theReport.getFileName()); + } + catch (KurtException e) { + String theErrorTitle = UNABLE_TO_DOWNLOAD_FILE; + log.error(theErrorTitle, e); + ErrorPageTemplate theErrorTemplate = new ErrorPageTemplate(theErrorTitle, e.getMessage()); + aResponse.getWriter().write(theErrorTemplate.generateCode()); + } + finally { + session.close(); + } + } + + private String makeFileName(final DbReport theReport) throws NotFoundException { + String[] split = theReport.getFileName().split("\\."); + if (split.length != 2) { + throw new NotFoundException("Could not extract file name and extension from DB: " + theReport.getFileName()); + } + String fileNameNoExtension = split[0]; + String extension = split[1]; + + // Define which folder to findAll + if (theReport.getSchedulingReportId() == null) { + return StringHelper.concatToString(OUTPUT_FOLDER, "/", fileNameNoExtension, "_", theReport.getReportUid(), ".", extension); + } + else { + return StringHelper.concatToString(OUTPUT_FOLDER_SCHEDULING_HISTORY, "/", fileNameNoExtension, ".", extension); + } + } + + /** + * Try to download a file from the output directory. + */ + private void downloadFile(final HttpServletResponse aResponse, final String aFilePathValue, final String fileName) + throws IOException, InsufficientParametersException, NotFoundException { + final File theSourceFile = new File(aFilePathValue); + if (!theSourceFile.exists() || theSourceFile.isDirectory()) { + throw new NotFoundException("The source file does not exist: " + aFilePathValue); + } + + long theFileSize = theSourceFile.length(); + if (theFileSize == 0) { + throw new NotFoundException("The source file is empty: " + aFilePathValue); + } + + try (FileInputStream input = new FileInputStream(theSourceFile); ServletOutputStream out = aResponse.getOutputStream()) { + aResponse.setContentType("application/download"); + aResponse.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\""); + aResponse.setContentLength((int) theFileSize); + IOUtils.copy(input, out); + } + catch (IOException e) { + log.error(UNABLE_TO_DOWNLOAD_FILE, e); + } + } + + /** + * Try to findAll an argument value in the URL and return an error message in JSP when it failed. + */ + private static String getMandatoryArg(final HttpServletRequest aRequest, final String anArgName) throws ServletException, IOException, InsufficientParametersException { + String theArgValue = aRequest.getParameter(anArgName); + if (theArgValue == null) { + throw new InsufficientParametersException("Missing required argument in URL: " + anArgName); + } + return theArgValue; + } +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/ServletMessageHelper.java b/kurt-web/src/main/java/com/capgemini/reports/common/ServletMessageHelper.java new file mode 100644 index 0000000..a40042a --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/ServletMessageHelper.java @@ -0,0 +1,146 @@ +package com.capgemini.reports.common; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.exceptions.runtime.ConnectionLostException; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import org.json.JSONObject; +import org.quartz.SchedulerException; + +import javax.jms.JMSException; +import javax.naming.NamingException; + +/** Helper class that provides several error and success messages with standardized KEYS and TOKENS that are understood by the HMI. */ +public final class ServletMessageHelper { + + private ServletMessageHelper() { + + } + + /** + * TOKEN to obtain request TcReleaseStatus from the JSON response. + */ + public static final String TOKEN_STATUS = "status"; + /** TOKEN to obtain error explanation from the JSON response when STATUS is FAILED. */ + public static final String TOKEN_ERROR = "error"; + /** TOKEN to obtain success message from the JSON response. */ + public static final String TOKEN_SUCCESS_MSG = "success"; + + /** STATUS value for the JSON response when posting is successful. */ + public static final String STATUS_SUCCESS = TOKEN_SUCCESS_MSG; + /** STATUS value for the JSON response when posting has failed. */ + public static final String STATUS_FAILED = "failed"; + /** STATUS value for the JSON response when user should be prompted before actually launching the report. */ + public static final String STATUS_PROMPT = "prompt"; + + protected static final String POSTING_ERROR_MESSAGE_EN = "Error caught while trying to submit the report into the Queue"; + protected static final String POSTING_ERROR_MESSAGE_FR = + new InvalidUserInputException(UserInputErrorEnum.INTERNAL_ERROR).getErrorMessageForUser(); + private static final String DELAY_ERROR_MESSAGE_FR = "Impossible de planifier une exécution"; + private static final String TEAMCENTER_UNAVAILABLE_EXCEPTION_MSG_FR = "Impossible de communiquer avec le serveur Teamcenter"; + private static final String TEAMCENTER_CONNECTION_LOST_EXCEPTION_MSG_FR = + "Le serveur Teamcenter a cessé de répondre, réessayez ultérieurement. Si le problème persiste, contactez l'administrateur."; + + /** + * Helper function to return standardized success messages to the client. + * + * @param msg the message + * @return the {@link JSONObject} + */ + public static JSONObject successMessage(final String msg) { + return new JSONObject().put(TOKEN_STATUS, STATUS_SUCCESS).put(TOKEN_SUCCESS_MSG, msg); + } + + /** + * Helper function for producing standardized JSON error messages to be sent to server in case a fault is found. + * + * @param msg the message + * @return the {@link JSONObject} + */ + public static JSONObject errorMessage(final String msg) { + return new JSONObject().put(TOKEN_STATUS, STATUS_FAILED).put(TOKEN_ERROR, msg); + } + + /** + * Helper function for producing standardized JSON error messages to be sent to server in case a InvalidUserInputException is triggered by a user. + * + * @param exception the {@link InvalidUserInputException} that caused the failure and contains a nice error message for the user + * @return the {@link JSONObject} containing the status and a nice error message for the user + */ + public static JSONObject errorMessage(final InvalidUserInputException exception) { + return new JSONObject().put(TOKEN_STATUS, STATUS_FAILED).put(TOKEN_ERROR, exception.getErrorMessageForUser()); + } + + /** + * Helper function for producing standardized JSON error messages to be sent to server in case a InvalidInputException occurred. + * + * @param exception the {@link InvalidInputException} that caused the failure and contains a nice error message for the user + * @return the {@link JSONObject} containing the status and a nice error message for the user + */ + public static JSONObject errorMessage(final InvalidInputException exception) { + return new JSONObject().put(TOKEN_STATUS, STATUS_FAILED).put(TOKEN_ERROR, exception.getErrorMessageForUser()); + } + + /** + * Helper function for producing standardized JSON error messages to be sent to server in case a fault is found. + * + * @param exception the generic {@link KurtException} that caused the failure + * @return the {@link JSONObject} containing the status and a generic error message + */ + public static JSONObject errorMessage(final KurtException exception) { + return new JSONObject().put(TOKEN_STATUS, STATUS_FAILED).put(TOKEN_ERROR, exception.getMessage()); + } + + /** + * Helper function for producing standardized JSON error messages to be sent to server in case a NamingException occurred. + * + * @param exception the {@link NamingException} that caused the failure + * @return the {@link JSONObject} containing the status and an error message + */ + public static JSONObject errorMessage(final NamingException exception) { + return new JSONObject().put(TOKEN_STATUS, STATUS_FAILED).put(TOKEN_ERROR, ServletMessageHelper.POSTING_ERROR_MESSAGE_FR); + } + + /** + * Helper function for producing standardized JSON error messages to be sent to server in case a JMSException occurred. + * + * @param exception the {@link JMSException} that caused the failure + * @return the {@link JSONObject} containing the status and an error message + */ + public static JSONObject errorMessage(final JMSException exception) { + return new JSONObject().put(TOKEN_STATUS, STATUS_FAILED).put(TOKEN_ERROR, ServletMessageHelper.POSTING_ERROR_MESSAGE_FR); + } + + /** + * Helper function for producing standardized JSON error messages to be sent to server in case a SchedulerException occurred. + * + * @param exception the {@link SchedulerException} that caused the failure + * @return the {@link JSONObject} containing the status and an error message + */ + public static JSONObject errorMessage(final SchedulerException exception) { + return new JSONObject().put(TOKEN_STATUS, STATUS_FAILED).put(TOKEN_ERROR, ServletMessageHelper.DELAY_ERROR_MESSAGE_FR); + } + + /** + * Helper function for producing standardized JSON error messages to be sent to server in case a NoTeamcenterConnectionException occurred. + * + * @param exception the {@link NoTeamcenterConnectionException} that caused the failure + * @return the {@link JSONObject} containing the status and an error message + */ + public static JSONObject errorMessage(final NoTeamcenterConnectionException exception) { + return new JSONObject().put(TOKEN_STATUS, STATUS_FAILED).put(TOKEN_ERROR, ServletMessageHelper.TEAMCENTER_UNAVAILABLE_EXCEPTION_MSG_FR); + } + + /** + * Helper function for producing standardized JSON error messages to be sent to server in case a ConnectionLostException occurred. + * + * @param exception the {@link ConnectionLostException} that caused the failure + * @return the {@link JSONObject} containing the status and an error message + */ + public static JSONObject errorMessage(final ConnectionLostException exception) { + return new JSONObject().put(TOKEN_STATUS, STATUS_FAILED).put(TOKEN_ERROR, ServletMessageHelper.TEAMCENTER_CONNECTION_LOST_EXCEPTION_MSG_FR); + } + +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/TestServlet.java b/kurt-web/src/main/java/com/capgemini/reports/common/TestServlet.java new file mode 100644 index 0000000..4d9349d --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/TestServlet.java @@ -0,0 +1,77 @@ +package com.capgemini.reports.common; + +import java.io.IOException; +import java.util.Enumeration; +import java.util.Map; +import java.util.Map.Entry; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import lombok.extern.slf4j.Slf4j; + +/** + * JSP Servlet for downloading file content from web GUI. + */ +@Slf4j +@WebServlet("/testServlet") +public class TestServlet extends HttpServlet { + + /** Default serial UID. **/ + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(final HttpServletRequest aRequest, final HttpServletResponse aResponse) throws ServletException, IOException { + + log.info("GET RECEIVED"); + processParams(aRequest, aResponse); + } + + @Override + protected void doPost(final HttpServletRequest aRequest, final HttpServletResponse aResponse) throws ServletException, IOException { + log.info("POST RECEIVED"); + + processParams(aRequest, aResponse); + } + + + private void processParams(final HttpServletRequest aRequest, final HttpServletResponse aResponse) { + + Enumeration attNameEnum = aRequest.getAttributeNames(); + while (attNameEnum.hasMoreElements()) { + String currentAtt = attNameEnum.nextElement(); + log.info("\t - Att: " + currentAtt + "=" + aRequest.getAttribute(currentAtt)); + } + + Enumeration headerEnum = aRequest.getHeaderNames(); + while (headerEnum.hasMoreElements()) { + String currentHeader = headerEnum.nextElement(); + log.info("\t - Head: " + currentHeader + "=" + aRequest.getHeader(currentHeader)); + } + + Map parameterMap = aRequest.getParameterMap(); + + for (Entry entry : parameterMap.entrySet()) { + + String[] currentParamArray = entry.getValue(); + if (currentParamArray.length == 1) { + log.info(entry.getKey() + "=" + currentParamArray[0]); + } + else { + for (int i = 0; i < currentParamArray.length; i++) { + log.info(entry.getKey() + "[" + i + "] =" + currentParamArray[i]); + } + } + } + + try { + aResponse.getWriter().write("FINISHED"); + } + catch (IOException e) { + log.error("Error", e); + } + } +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/obtaindata/AbstractObtainDataFromItemRevision.java b/kurt-web/src/main/java/com/capgemini/reports/common/obtaindata/AbstractObtainDataFromItemRevision.java new file mode 100644 index 0000000..6be1ee0 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/obtaindata/AbstractObtainDataFromItemRevision.java @@ -0,0 +1,95 @@ +package com.capgemini.reports.common.obtaindata; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.teamcenter.queries.DirectQuery; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; +import org.json.JSONObject; + +import javax.servlet.http.HttpServletRequest; + +/** + * This class is a servlet that handles requests to perform a report on an ItemRevision. + */ +@Slf4j +public abstract class AbstractObtainDataFromItemRevision extends AbstractObtainDataServlet { + private static final long serialVersionUID = 7666172651622505390L; + + @Override + protected JSONObject obtainData(final HttpServletRequest request, final TcSession session) throws InvalidUserInputException { + // Obtain the URL parameters + String objectUID = request.getParameter("dataValues"); + + ItemRevision itemRev = getItemRevisionByIUD(objectUID, session); + + String itemID = getItemID(itemRev); + String itemRevisionID = getItemRevisionID(itemRev); + String itemType = itemRev.getTypeObject().getName(); + return obtainDataFromItemRevision(itemID, itemRevisionID, itemType, session); + } + + /** + * Obtains the ItemID of the {@link ItemRevision}. Handles errors nicely. + * + * @param itemRev the Revision ID of the object + * @return the item Id + * @throws InvalidUserInputException thrown in case of internal errors: some properties might not be loaded + */ + private String getItemID(final ItemRevision itemRev) throws InvalidUserInputException { + return itemRev.get_item_id(); + } + + /** + * The main method of this class: receives and stores information on an ItemRevision. + */ + protected abstract JSONObject obtainDataFromItemRevision(final String itemID, final String itemRevisionID, final String itemType, + final TcSession session) throws InvalidUserInputException; + + + /** + * Obtains the revision ID of the {@link ItemRevision}. Handles errors nicely. + * + * @param itemRev the ItemRevision + * @return the itemRevision Id + * @throws InvalidUserInputException thrown in case of internal errors: some properties might not be loaded + */ + private String getItemRevisionID(final ItemRevision itemRev) throws InvalidUserInputException { + return itemRev.get_item_revision_id(); + } + + /** + * Verifies that the UID provided is not corrupt. + * + * @param objectUID the object UID + * @throws InvalidUserInputException thrown if the UID is corrupt (empty, or null) + */ + private void validateInputUID(final String objectUID) throws InvalidUserInputException { + if (objectUID == null) { + throw new InvalidUserInputException("dataValues uid is null"); + } + if (objectUID.isEmpty()) { + throw new InvalidUserInputException(UserInputErrorEnum.OBJECT_DOES_NOT_EXIST); + } + log.info("Server validated parameter dataValues \"{}\"", objectUID); + } + + /** + * Returns the ItemRevision matching the UID provided. Handles errors nicely. + * + * @param uid the item UID + * @param session the Tc session to make the query + * @return the {@link ItemRevision} + * @throws InvalidUserInputException thrown if the object couldn't be found + */ + private ItemRevision getItemRevisionByIUD(final String uid, final TcSession session) throws InvalidUserInputException { + validateInputUID(uid); + try { + return new DirectQuery(session).searchByUID(uid); + } catch (NotFoundException e) { + throw new InvalidUserInputException("Object not found with UID '" + uid + "'", e); + } + } +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/obtaindata/AbstractObtainDataFromModelObject.java b/kurt-web/src/main/java/com/capgemini/reports/common/obtaindata/AbstractObtainDataFromModelObject.java new file mode 100644 index 0000000..0967cc5 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/obtaindata/AbstractObtainDataFromModelObject.java @@ -0,0 +1,86 @@ +package com.capgemini.reports.common.obtaindata; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.teamcenter.queries.DirectQuery; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.json.JSONObject; + +import javax.servlet.http.HttpServletRequest; + +/** + * This class is a servlet that handles requests to perform a report on an ModelObject. + */ +@Slf4j +public abstract class AbstractObtainDataFromModelObject extends AbstractObtainDataServlet { + + + private static final long serialVersionUID = 7451192554668264900L; + + private static final String OBJECT_NOT_FOUND_PREFIX = "Object not found with UID '"; + private static final String OBJECT_NOT_FOUND_SUFFIX = "'"; + + @Getter + private String uid; + + @Override + protected JSONObject obtainData(final HttpServletRequest request, final TcSession session) throws InvalidUserInputException { + + // Obtain the URL parameters + uid = request.getParameter("dataValues"); + log.info("Report - search uid for {}", uid); + // findAll model object by uid + ModelObject modelObject = getModelObject(session); + + return obtainDataFromModelObject(modelObject, session); + } + + /** + * The main method of this class: receives and stores information on an ModelObject. + * + * @param modelObject + * @param session a Tc session to validate the input + * @return a {@link JSONObject} contaidning the server response that will be sent back to the browser + * @throws InvalidUserInputException thrown when user posted invalid input parameters + */ + protected abstract JSONObject obtainDataFromModelObject(final ModelObject modelObject, final TcSession session) + throws InvalidUserInputException; + + /** + * Verifies that the UID provided is not corrupt. + * + * @param objectUID + * @throws InvalidUserInputException thrown if the UID is corrupt (empty, or null) + */ + protected void validateInputUID(final String objectUID) throws InvalidUserInputException { + if (objectUID == null) { + throw new InvalidUserInputException("dataValues uid is null"); + } + if (objectUID.isEmpty()) { + throw new InvalidUserInputException(UserInputErrorEnum.OBJECT_DOES_NOT_EXIST); + } + log.info("Server validated parameter dataValues \"{}\"", objectUID); + } + + /** + * Returns the ModelObject matching the UID. Handles errors nicely. + * + * @param session the Tc session to make the query + * @return the {@link ItemRevision} + * @throws InvalidUserInputException thrown if the object couldn't be found + */ + protected ModelObject getModelObject(final TcSession session) throws InvalidUserInputException { + validateInputUID(uid); + try { + return new DirectQuery<>(session).searchByUID(uid); + } catch (NotFoundException e) { + throw new InvalidUserInputException(OBJECT_NOT_FOUND_PREFIX + uid + OBJECT_NOT_FOUND_SUFFIX, e); + } + } + +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/obtaindata/AbstractObtainDataFromPartRevision.java b/kurt-web/src/main/java/com/capgemini/reports/common/obtaindata/AbstractObtainDataFromPartRevision.java new file mode 100644 index 0000000..bc0250c --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/obtaindata/AbstractObtainDataFromPartRevision.java @@ -0,0 +1,38 @@ +package com.capgemini.reports.common.obtaindata; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import org.json.JSONObject; + +/** This class is a servlet that handles requests to perform a report on a Part. */ +public abstract class AbstractObtainDataFromPartRevision extends AbstractObtainDataFromItemRevision { + + private static final long serialVersionUID = 3679669481879532713L; + + @Override + public JSONObject obtainDataFromItemRevision(final String itemID, final String itemRevisionID, final String itemType, + final TcSession session) throws InvalidUserInputException { + + if (!SnecmaObjectTypes.isPartRevision(itemType)) { + throw new InvalidUserInputException(UserInputErrorEnum.THE_SELECTED_OBJECT_IS_NOT_PERMITTED_ON_THIS_REPORT); + } + return obtainDataFromPartRevision(itemID, itemRevisionID, itemType, session); + } + + /** + * The main method of this class: receives and stores information on a Part Revision. + * + * @param partID the ID of the Part + * @param partRevisionID the revision ID of the Part + * @param partType the type of the Part + * @param session a Tc session to validate the input + * @return a {@link JSONObject} containing the server response that will be sent back to the browser + * @throws InvalidUserInputException thrown when user posted invalid input parameters + */ + public abstract JSONObject obtainDataFromPartRevision(final String partID, final String partRevisionID, final String partType, + final TcSession session) throws InvalidUserInputException; + + +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/obtaindata/AbstractObtainDataServlet.java b/kurt-web/src/main/java/com/capgemini/reports/common/obtaindata/AbstractObtainDataServlet.java new file mode 100644 index 0000000..93f8388 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/obtaindata/AbstractObtainDataServlet.java @@ -0,0 +1,50 @@ +package com.capgemini.reports.common.obtaindata; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.common.AbstractKurtServlet; +import com.capgemini.reports.common.ServletMessageHelper; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import lombok.extern.slf4j.Slf4j; +import org.json.JSONObject; + +import javax.servlet.http.HttpServletRequest; + +/** + * Abstract class providing the framework for request of ajax client. + */ +@Slf4j +public abstract class AbstractObtainDataServlet extends AbstractKurtServlet { + + private static final long serialVersionUID = 7803067312625585174L; + + @Override + protected JSONObject perform(final HttpServletRequest request, final TcSession session) throws InvalidUserInputException { + try { + PolicyLocation policyLocation = obtainLocation(); + session.setObjectPropPolicy(policyLocation); + } catch (KurtException e) { + log.error("Unable to findAll data for request Ajax Client", e); + return ServletMessageHelper.errorMessage("Impossible de retrouver les données, merci de contacter l'administrateur système."); + } + return obtainData(request, session); + } + + /** + * The main method of this class: sets up the environment required to valdiate user input before a report execution. + * + * @param request the web request containing various user inputs + * @param session a Tc session to validate the input + * @return a {@link JSONObject} containing this server's response to the browser + * @throws InvalidUserInputException thrown when user posted invalid input parameters + */ + protected abstract JSONObject obtainData(final HttpServletRequest request, final TcSession session) throws InvalidUserInputException; + + /** + * Returns the {@link PolicyLocation} of the policy to be used to perform some validation on the user inputs. + * + * @return the {@link PolicyLocation} + */ + protected abstract PolicyLocation obtainLocation(); +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/AbstractGenerateScheduledTemplateServlet.java b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/AbstractGenerateScheduledTemplateServlet.java new file mode 100644 index 0000000..f4afa92 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/AbstractGenerateScheduledTemplateServlet.java @@ -0,0 +1,240 @@ +package com.capgemini.reports.common.scheduling; + +import com.capgemini.framework.common.ReflectionHelper; +import com.capgemini.framework.common.activedirectory.ActiveDirectory; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.exceptions.runtime.ConnectionLostException; +import com.capgemini.reports.common.AbstractSubmitServlet; +import com.capgemini.reports.common.ServletMessageHelper; +import com.capgemini.reports.database.javabean.DbUser.UserData; +import com.capgemini.reports.database.javabean.enumeration.SchedulingEnum; +import com.capgemini.reports.exceptions.*; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.periodicity.PeriodFactory; +import com.capgemini.reports.periodicity.SchedulingPeriod; +import com.capgemini.reports.quartz.SchedulerServer; +import com.google.common.base.Joiner; +import com.teamcenter.schemas.soa._2006_03.exceptions.ServiceException; +import lombok.extern.slf4j.Slf4j; +import org.json.JSONObject; +import org.quartz.SchedulerException; + +import javax.ejb.EJB; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.text.ParseException; +import java.util.Map.Entry; + +/** Abstract class which contains the framework for submitting and checking the necessary parameters to produce a scheduled report. **/ +@Slf4j +public abstract class AbstractGenerateScheduledTemplateServlet extends HttpServlet { + private static final long serialVersionUID = -1942251448070464203L; + + private static final String KEY_DATE = "datepicker_planification"; + private static final String KEY_PERIOD = "period"; + + @EJB + protected SchedulerServer schedulingServer; + + // Configuration for reflection + private static final String CLASS_IMPL_PACKAGE = "com.capgemini.reports."; + private static final String PREFIX_SUBMIT_SERVLET_CLASS = "SubmitServlet"; + private static final String CONTENT_TYPE_JSON = "application/json"; + private static final String INTERNAL_ERROR_MESSAGE_FR = UserInputErrorEnum.INTERNAL_ERROR.getMsgFr(); + + // Keys to findAll data from the HttpServletRequest + private static final String KEY_REPORT_CODE = "report_code"; + private static final String KEY_PLANIFICATION_NAME = "scheduling_name"; + static final String KEY_SCHEDULING_REPORT_ID = "scheduling_report_id"; + + /** + * Forwarder of GET access to POST. + * + * @param request the user request + * @param response the response (a JSON object) + * @throws ServletException + * @throws IOException + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) + */ + @Override + protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { + doPost(request, response); + } + + @Override + protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { + try (TcSession session = new TcSession()) { + session.login(); + JSONObject computedResponse = perform(request, session); + response.setContentType(CONTENT_TYPE_JSON); + response.getWriter().write(computedResponse.toString()); + } catch (DuplicateSchedulingEntryFound e) { + // Error due to miscommunication with the scheduler system + log.error("A Scheduling with the same name already exists.", e); + response.getWriter().write(ServletMessageHelper.errorMessage(e).toString()); + } catch (InvalidUserInputException e) { + // Error due to miscommunication with the scheduler system + log.error("The report parameters were invalid.", e); + response.getWriter().write(ServletMessageHelper.errorMessage(e).toString()); + } catch (SchedulerException e) { + // Error due to miscommunication with the scheduler system + log.error("Error caught while trying to schedule the report.", e); + response.getWriter().write(ServletMessageHelper.errorMessage(e).toString()); + } catch (NotSupportedException e) { + log.error("Unable to find the requested report definition.", e); + response.getWriter().write(ServletMessageHelper.errorMessage(INTERNAL_ERROR_MESSAGE_FR).toString()); + } catch (FileLoadingException e) { + log.error("Unable to read the policies file.", e); + response.getWriter().write(ServletMessageHelper.errorMessage(INTERNAL_ERROR_MESSAGE_FR).toString()); + } catch (NoTeamcenterConnectionException e) { + // Error due to miscommunication with the Teamcenter servers + log.error("Unable to connect to the Teamcenter server", e); + response.getWriter().write(ServletMessageHelper.errorMessage(e).toString()); + } catch (ConnectionLostException e) { + // Runtime exception, happens when connection is suddenly lost and not recovered despite attempts to do so + log.error("Connection lost to Teamcenter server", e); + response.getWriter().write(ServletMessageHelper.errorMessage(e).toString()); + } catch (ServiceException e) { + String msg = "Servlet could not logout the Teamcenter connection Properly, some session might still be running..."; + log.error(msg, e); + } catch (KurtException e) { + log.error("Unable to perform the request.", e); + response.getWriter().write(ServletMessageHelper.errorMessage(INTERNAL_ERROR_MESSAGE_FR).toString()); + } + } + + /** + * Perform a scheduling operation (new/update/delete).
    + * If the method is successful, returns a {@link JSONObject} success message.
    + * If the method fails in any way, an exception must be thrown. + * + * @throws NotSupportedException If the report instance could not be created (not developped yet?) + * @throws FileLoadingException If unable to load policies to perform the quick checks + * @throws InvalidUserInputException If any report parameter or scheduling parameter could not be understood + * @throws SchedulerException if a scheduling operation failed. + * @throws NotFoundException if elements potentially affected by the request could not be found (DB etc.) + * @throws InsufficientParametersException if not enough parameters or attribute were passed in the http request + */ + protected abstract JSONObject perform(final HttpServletRequest request, final TcSession session) + throws SchedulerException, NotSupportedException, InvalidUserInputException, FileLoadingException, NotFoundException, + InsufficientParametersException, DuplicateSchedulingEntryFound; + + /** Obtains the name of the planification from the {@link HttpServletRequest}. */ + String getPlanificationName(final HttpServletRequest request) { + return request.getParameter(KEY_PLANIFICATION_NAME); + } + + /** Obtains dynamically an instance of ExecutionReport to match the {@link HttpServletRequest request} parameters. */ + AbstractExecutionReport getExecutionReportImpl(final HttpServletRequest request) throws NotSupportedException { + String reportCode = request.getParameter(KEY_REPORT_CODE); + if (reportCode == null) { + String aMessage = "Unable find key [" + KEY_REPORT_CODE + "] in request parameter map: " + request.getParameterMap().toString(); + throw new NotSupportedException(aMessage); + } + // Recovery of the name of a not known class because of the package + String className = getBuilderClassName(reportCode); + + // Research and recovery of the builder class using Reflection + Object invokedObj = ReflectionHelper.newFromClassForName(className); + + if ((invokedObj == null) || (!(invokedObj instanceof AbstractSubmitServlet))) { + String aMessage = "Unable to invoke the servlet: " + className + " of the report " + reportCode; + throw new NotSupportedException(aMessage); + } else { + // Use the builder + AbstractSubmitServlet submitServlet = (AbstractSubmitServlet) invokedObj; + return submitServlet.prepareReport(request); + } + } + + /** + * Get the name of the SubmitServlet class of the appropriate report thanks to his code. + * + * @param reportCode String - the report code + * @return theClassNameBuilder String + */ + private String getBuilderClassName(final String reportCode) { + return CLASS_IMPL_PACKAGE + reportCode.replace("R", "r") + "." + PREFIX_SUBMIT_SERVLET_CLASS + reportCode; + } + + SchedulingPeriod getSchedulingData(final HttpServletRequest request) throws InvalidUserInputException { + if (log.isTraceEnabled()) { + StringBuilder result = new StringBuilder("Parsing http Request for scheduling periodicity:"); + for (Entry paramEntry : request.getParameterMap().entrySet()) { + result.append(paramEntry.getKey()).append("="); + String paramValues = Joiner.on(", ").join(paramEntry.getValue()); + result.append(paramValues).append('|'); + } + log.trace(result.toString()); + } + SchedulingEnum periodicityEnum = getPeriodicity(request); + switch (periodicityEnum) { + case DAILY: + log.trace("Daily periodicity requested"); + return PeriodFactory.daily(); + case DATE: + final String date = request.getParameter(KEY_DATE); + log.trace("Date periodicity requested: date={}", date); + try { + return PeriodFactory.day(date); + } catch (ParseException e) { + throw new InvalidUserInputException("Unable to parse date: " + date, e); + } + case DAY_IN_MONTH_VALUE: + final String dayInMonthStr = request.getParameter(SchedulingEnum.DAY_IN_MONTH_VALUE.getCriteriaName()); + log.trace("Monthly periodicity requested: day in month={}", dayInMonthStr); + try { + int dayInMonth = Integer.parseInt(dayInMonthStr); + return PeriodFactory.dayInMonth(dayInMonth); + } catch (NumberFormatException e) { + throw new InvalidUserInputException("Unable to parse day of month number (int): " + dayInMonthStr, e); + } + case WEEKEND: + final String weekend = request.getParameter(SchedulingEnum.WEEKEND.getCriteriaName()); + log.trace("Monthly periodicity requested: weekend={}", weekend); + return PeriodFactory.weekend(weekend); + case WEEKLY: + final String weekdayNum = request.getParameter(SchedulingEnum.WEEKLY.getCriteriaName()); + log.trace("Weekly periodicity requested: weekDay={}", weekdayNum); + try { + int dayInWeek = Integer.parseInt(weekdayNum); + return PeriodFactory.weekly(dayInWeek); + } catch (NumberFormatException e) { + throw new InvalidUserInputException("Unable to parse day of week number (int): " + weekdayNum, e); + } + default: + throw new InvalidUserInputException("Unable to understand periodicity value:" + request.getParameter(KEY_PERIOD)); + } + } + + private SchedulingEnum getPeriodicity(HttpServletRequest request) { + final String initialPeriodicity = request.getParameter(KEY_PERIOD); + String periodicityValue = request.getParameter(initialPeriodicity); + if (SchedulingEnum.DAY_IN_MONTH_VALUE.getCriteriaName().equals(periodicityValue)) { + return SchedulingEnum.DAY_IN_MONTH_VALUE; + } else { + return SchedulingEnum.getEnum(initialPeriodicity); + } + } + + UserData identifyUser(final HttpServletRequest request) { + // Obtain userName, and user email through authentication + String userName = request.getRemoteUser(); + try { + return ActiveDirectory.obtainUserData(userName); + } catch (NoConnectionToActiveDirectoryException e) { + log.warn("Could not connect to the AD to authenticate the user for scheduling, using GUEST", e); + } catch (InvalidInputException e) { + log.warn("AD Could not authenticate the user for scheduling, using GUEST", e); + } catch (InvalidActiveDirectorySearchException e) { + log.warn("Could not perform a search on the AD for scheduling, using GUEST", e); + } + // Guest user when authentication failed + return ActiveDirectory.getGuestUser(); + } +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/DeleteServletScheduling.java b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/DeleteServletScheduling.java new file mode 100644 index 0000000..db612b3 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/DeleteServletScheduling.java @@ -0,0 +1,64 @@ +package com.capgemini.reports.common.scheduling; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.common.ServletMessageHelper; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbSchedulingReport; +import com.capgemini.reports.database.manager.MngSchedulingReport; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.exceptions.NotFoundException; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.json.JSONObject; +import org.quartz.SchedulerException; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServletRequest; + +/** + * Class providing the framework for deleting a scheduling. + */ +@WebServlet("/scheduling/delete") +public class DeleteServletScheduling extends AbstractGenerateScheduledTemplateServlet { + private static final long serialVersionUID = -8856096872281102308L; + + @Override + protected JSONObject perform(final HttpServletRequest request, final TcSession tcSession) throws SchedulerException, NotFoundException, InsufficientParametersException { + + // Obtain all parameters from the request + String schedulingReportIdStr = request.getParameter(KEY_SCHEDULING_REPORT_ID); + Long schedulingReportId; + if (schedulingReportIdStr == null) { + throw new InsufficientParametersException("No scheduling Identifier passed to DeleteServletScheduling, aborting..."); + } + try { + schedulingReportId = Long.valueOf(schedulingReportIdStr); + } + catch (NumberFormatException e) { + throw new InsufficientParametersException("Input scheduling Identifier passed to DeleteServletScheduling could not be understood: " + + schedulingReportIdStr, e); + } + + // Delete the Job and all of its triggers + schedulingServer.deleteScheduledJobAndKeys(schedulingReportId); + + // Update the DB + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + MngSchedulingReport mngSchedulingReport = new MngSchedulingReport(); + DbSchedulingReport report = mngSchedulingReport.searchById(session, schedulingReportId); + mngSchedulingReport.deleteSchedulingReport(schedulingReportId); + + // Return a success message + return successMessage(report.getReportCode()); + } + finally { + session.close(); + } + } + + private JSONObject successMessage(final String reportCode) { + return ServletMessageHelper.successMessage("Le rapport \"" + reportCode + "\" a bien été supprimé"); + } +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/ModifyServletScheduling.java b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/ModifyServletScheduling.java new file mode 100644 index 0000000..c43e6b6 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/ModifyServletScheduling.java @@ -0,0 +1,90 @@ +package com.capgemini.reports.common.scheduling; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.checkdata.CheckingDataHelper; +import com.capgemini.reports.common.ServletMessageHelper; +import com.capgemini.reports.database.DataBaseReportHelper; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbSchedulingReport; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.database.javabean.DbUser.UserData; +import com.capgemini.reports.database.manager.MngSchedulingReport; +import com.capgemini.reports.database.manager.MngUser; +import com.capgemini.reports.exceptions.*; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.periodicity.SchedulingPeriod; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.json.JSONObject; +import org.quartz.SchedulerException; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServletRequest; + +/** + * Class providing the framework for modifying a scheduling.
    + * The old scheduled report will be destroyed and the new scheduled report will be submitted and checked.
    + */ +@Slf4j +@WebServlet("/scheduling/modify") +public class ModifyServletScheduling extends AbstractGenerateScheduledTemplateServlet { + + private static final long serialVersionUID = 3233963187725874998L; + + @Override + protected JSONObject perform(final HttpServletRequest request, final TcSession tcSession) throws SchedulerException, NotSupportedException, + InvalidUserInputException, DuplicateSchedulingEntryFound, FileLoadingException { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + // Identify the requestor + UserData adUser = identifyUser(request); + final DbUser dbUser = new MngUser().fetchOrUpdateOrCreateUser(session, adUser); + + // Obtain all parameters from the request + String schedulingReportIdStr = request.getParameter(KEY_SCHEDULING_REPORT_ID); + Long schedulingReportId = Long.valueOf(schedulingReportIdStr); + String planifName = super.getPlanificationName(request); + AbstractExecutionReport report = super.getExecutionReportImpl(request); + report.setScheduling(schedulingReportId, planifName); + SchedulingPeriod period = super.getSchedulingData(request); + + checkDuplicateName(session, schedulingReportId, planifName); + + // Check the report is STILL valid + CheckingDataHelper.doQuickCheck(tcSession, report); + + // Update the DB + DataBaseReportHelper.updateScheduling(schedulingReportId, report, planifName, period, dbUser); + + // Update the functional (JobDetail) and temporal (Trigger) parameters + schedulingServer.replaceJob(schedulingReportId, report, report.getPriorityCode(), period, planifName); + + // Return a success message + return successMessage(report); + } + finally { + session.close(); + } + } + + /** + * Fails if the name has changed AND the new name is already used. + */ + private void checkDuplicateName(Session session, Long schedulingReportId, String planifName) throws DuplicateSchedulingEntryFound { + MngSchedulingReport mngScheduling = new MngSchedulingReport(); + DbSchedulingReport oldScheduling = mngScheduling.searchById(session, schedulingReportId); + if (!planifName.equals(oldScheduling.getSchedulingName())) { + // the scheduling name has changed, check that it doesn't interfere with an other one! + DbSchedulingReport potentialDuplicate = mngScheduling.searchByName(session, planifName); + if (potentialDuplicate != null) { + throw new DuplicateSchedulingEntryFound("La planification " + planifName + " existe déjà. veuillez saisir un autre nom."); + } + } + } + + private JSONObject successMessage(final AbstractExecutionReport reportImpl) { + return ServletMessageHelper.successMessage("Le rapport \"" + reportImpl.getReportIdentifier().getReportTitle() + "\" planifié est modifié"); + } +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/SubmitServletScheduling.java b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/SubmitServletScheduling.java new file mode 100644 index 0000000..7e017af --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/SubmitServletScheduling.java @@ -0,0 +1,132 @@ +package com.capgemini.reports.common.scheduling; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.checkdata.CheckingDataHelper; +import com.capgemini.reports.common.ServletMessageHelper; +import com.capgemini.reports.database.DataBaseReportHelper; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbSchedulingReport; +import com.capgemini.reports.database.javabean.DbUser; +import com.capgemini.reports.database.javabean.DbUser.UserData; +import com.capgemini.reports.database.manager.MngSchedulingCriteriaVal.SchedulingCriteriaValue; +import com.capgemini.reports.database.manager.MngSchedulingReport; +import com.capgemini.reports.database.manager.MngUser; +import com.capgemini.reports.exceptions.*; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.posting.SchedulingPostingStrategy; +import com.capgemini.reports.execution.strategies.ScheduledExecutionStrategy; +import com.capgemini.reports.logging.ReportLoggerHelper; +import com.capgemini.reports.periodicity.SchedulingPeriod; +import com.capgemini.reports.quartz.TriggerPreparator; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.json.JSONObject; +import org.quartz.SchedulerException; +import org.quartz.Trigger; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +/** + * Class providing the framework for submitting a new report Scheduling request.
    + * Also checks in advance the parameters to produce the scheduled report.
    + * Note: The reports generated from a right click on a TC object cannot be scheduled.
    + * For examples : R15, R17,... + */ +@Slf4j +@WebServlet("/scheduling/submit") +public class SubmitServletScheduling extends AbstractGenerateScheduledTemplateServlet { + + private static final long serialVersionUID = -7776388563908130383L; + + /** + * Record a new Scheduling job into Quartz and the DB. + * + * @throws NotSupportedException If the report instance could not be created (not developped yet?) + * @throws FileLoadingException If unable to load policies to perform the quick checks + * @throws InvalidUserInputException If any report parameter or scheduling parameter could not be understood + * @throws SchedulerException if a scheduling operation failed. + * @throws DuplicateSchedulingEntryFound + */ + @Override + protected JSONObject perform(final HttpServletRequest request, final TcSession tcSession) + throws SchedulerException, NotSupportedException, InvalidUserInputException, FileLoadingException, DuplicateSchedulingEntryFound { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + String schedulingName = getPlanificationName(request); + DbSchedulingReport previous = new MngSchedulingReport().searchByName(session, schedulingName); + if (previous != null) { + throw new DuplicateSchedulingEntryFound( + "La planification " + schedulingName + " existe déjà. veuillez saisir un autre nom."); + } + + // Get the implementation of the report by reflection thanks to his code and the request + AbstractExecutionReport reportImpl = getExecutionReportImpl(request); + + // Prepare a Session in order to perform the quick checks + String reportCode = reportImpl.getReportIdentifier().getReportCode(); + log.debug("Beginning quick checks for the report {}...", reportCode); + + // Do a quick Check. If it fails, the exception thrown will carry a message to the user's webpage + CheckingDataHelper.doQuickCheck(tcSession, reportImpl); + log.debug("All quick checks have passed for {}", reportCode); + + // Get scheduling parameters + SchedulingPeriod schedulingPeriod = getSchedulingData(request); + + // Record which admin has asked for this job + DbSchedulingReport theSchedulingEntry = recordSchedulingRequest(request, reportImpl, schedulingName, schedulingPeriod.asCriteriaValues()); + + // Get the trigger thanks to the scheduling parameters from the request + Trigger trigger; + try { + trigger = TriggerPreparator.prepareScheduledTrigger(theSchedulingEntry.getId(), reportImpl.getPriorityCode(), schedulingName, + schedulingPeriod); + } + catch (InvalidInputException e) { + throw new InvalidUserInputException("Some scheduling parameters could ntot be understood", e); + } + // Setup the scheduling parameters + log.info("Scheduling name={}, id={}", theSchedulingEntry.getSchedulingName(), theSchedulingEntry.getId()); + reportImpl.setScheduling(theSchedulingEntry.getId(), theSchedulingEntry.getSchedulingName()); + reportImpl.setExecutionStrategy(new ScheduledExecutionStrategy()); + + // POST the report + new SchedulingPostingStrategy(schedulingServer, trigger).handleRequest(reportImpl); + return successMessage(reportImpl); + } + finally { + session.close(); + } + } + + private DbSchedulingReport recordSchedulingRequest(final HttpServletRequest request, final AbstractExecutionReport reportImpl, + final String schedulingName, final List schedulingCriteriaValues) { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + // Identify the user using the LDAP + UserData adUser = identifyUser(request); + + // Find / update / create corresponding user in DB if it doesn't already exist + DbUser dbUser = new MngUser().fetchOrUpdateOrCreateUser(session, adUser); + + // Record the report launch in the database + DbSchedulingReport theSchedulingEntry = DataBaseReportHelper.registerScheduledTemplate(reportImpl, dbUser, schedulingCriteriaValues, schedulingName); + + // Log the scheduling request + ReportLoggerHelper.logSchedulingRequestWaiting(session, dbUser, theSchedulingEntry, reportImpl); + return theSchedulingEntry; + } + finally { + session.close(); + } + } + + private JSONObject successMessage(final AbstractExecutionReport reportImpl) { + return ServletMessageHelper.successMessage("Le rapport \"" + reportImpl.getReportIdentifier().getReportTitle() + "\" est planifié"); + } +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/controller/QueueReaderServlet.java b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/controller/QueueReaderServlet.java new file mode 100644 index 0000000..5abe29c --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/controller/QueueReaderServlet.java @@ -0,0 +1,91 @@ +package com.capgemini.reports.common.scheduling.controller; + +import java.io.IOException; +import java.util.List; + +import javax.ejb.EJB; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.capgemini.reports.database.HibernateUtil; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.json.JSONObject; +import org.quartz.SchedulerException; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.common.ServletMessageHelper; +import com.capgemini.reports.database.manager.MngReport; +import com.capgemini.reports.database.manager.MngReport.RunningReportEntry; +import com.capgemini.reports.quartz.SchedulerServer; +import com.capgemini.reports.quartz.SchedulerServer.JobExecution; + +import lombok.extern.slf4j.Slf4j; + +/** + * A {@link HttpServlet} that reads data from the DB and Quartz to retrieve queue status, then forwards the data t oa JSP for pretty-printing. + */ +@Slf4j +@WebServlet("/queueReader") +public class QueueReaderServlet extends HttpServlet { + private static final long serialVersionUID = -1471984298116642565L; + + // Output attribute keys + private static final String KEY_REPORTS_IN_QUARTZ = "quartzJobList"; + private static final String KEY_REPORTS_IN_QUEUE = "waitingReports"; + + private static final String CONTENT_TYPE_JSON = "application/json"; + private static final String FORMATTING_JSP_URL = "/frames/queue.jsp"; + + @EJB + SchedulerServer quartz; + + @Override + protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { + // Parse server request parameters + try { + perform(request, response); + JSONObject successMessage = ServletMessageHelper.successMessage("success"); + response.setContentType(CONTENT_TYPE_JSON); + response.getWriter().write(successMessage.toString()); + } + catch (SchedulerException e) { + // A nice error message will be sent to the user to tell him what he did wrong + log.error(e.getMessage(), e); + response.setContentType(CONTENT_TYPE_JSON); + response.getWriter().write(ServletMessageHelper.errorMessage(new KurtException("Unable to post a message", e)).toString()); + } + } + + @Override + protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { + doPost(request, response); + } + + private void perform(final HttpServletRequest request, final HttpServletResponse response) + throws ServletException, IOException, SchedulerException { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + // Obtain all reports currently queueing + MngReport theMngRep = new MngReport(); + List theWaitingReports = theMngRep.searchWaitingReports(session); + request.setAttribute(KEY_REPORTS_IN_QUEUE, theWaitingReports); + + // Obtain all report planification jobs stored + List tonightJobs = quartz.listAllScheduledJobsForTonight(session); + request.setAttribute(KEY_REPORTS_IN_QUARTZ, tonightJobs); + + // Add data to the request + RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(FORMATTING_JSP_URL); + dispatcher.forward(request, response); + } + finally { + session.close(); + } + } +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/controller/SchedulingReaderServlet.java b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/controller/SchedulingReaderServlet.java new file mode 100644 index 0000000..f825fcf --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/controller/SchedulingReaderServlet.java @@ -0,0 +1,227 @@ +package com.capgemini.reports.common.scheduling.controller; + +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.common.ServletMessageHelper; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbReportType; +import com.capgemini.reports.database.javabean.DbSchedulingReport; +import com.capgemini.reports.database.manager.MngReportType; +import com.capgemini.reports.database.manager.MngSchedulingCriteriaVal; +import com.capgemini.reports.database.manager.MngSchedulingReport; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.periodicity.SchedulingPeriod; +import com.capgemini.reports.quartz.SchedulerServer; +import com.google.common.base.Optional; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.json.JSONObject; +import org.quartz.SchedulerException; + +import javax.ejb.EJB; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.sql.Timestamp; +import java.util.*; +import java.util.Map.Entry; + +/** + * Controller servlet used during all transactions made to show the schedulings summary page.
    + * Entry parameters: + *
      + *
    • reportCode (MANDATORY) contains a usueal report code ('R01', 'R19') or 'TOUS' to show all report schedulings.
    • + *
    • page (OPTIONAL) may contain an integer for the result page number [1..n]
    • + *
    + * This servlet correlates the DB entries and the quartz entries to produce a {@link Set} of {@link SchedulingReportEntry}.
    + * The request is enriched with this Set, and forwarded to a JSP for printing. + *

    + * Output attributes: + *

      + *
    • schedulings : contains a {@link List} of {@link SchedulingReportEntry}
    • + *
    + */ +@Slf4j +@WebServlet("/schedulingReader") +public class SchedulingReaderServlet extends HttpServlet { + private static final long serialVersionUID = -8848572431950894775L; + + private static final String FR_HUMAN_DATE = "Par date"; + private static final String FR_HUMAN_MONTHLY = "Tous les mois"; + private static final String FR_HUMAN_WEEKLY = "Toutes les semaines"; + private static final String FR_HUMAN_DAILY = "Tous les jours"; + + // Key to output attributes + private static final String KEY_SCHEDULINGS = "schedulings"; + + private static final String CONTENT_TYPE_JSON = "application/json"; + private static final String FORMATTING_JSP_URL = "/frames/all_scheduling_reports.jsp"; + + private static final String PARAM_REPORT_CODE = "reportCode"; + private static final String PARAM_PAGE = "page"; + + @EJB + SchedulerServer quartz; + + @Override + protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { + // Parse server request parameters + try { + perform(request, response); + JSONObject successMessage = ServletMessageHelper.successMessage("success"); + response.setContentType(CONTENT_TYPE_JSON); + response.getWriter().write(successMessage.toString()); + } + catch (InvalidInputException e) { + // A nice error message will be sent to the user to tell him what he did wrong + log.error(e.getMessage(), e); + response.setContentType(CONTENT_TYPE_JSON); + response.getWriter().write(ServletMessageHelper.errorMessage(e).toString()); + } + catch (SchedulerException e) { + // An error message will be sent to the user to tell him an error occurred + log.error(e.getMessage(), e); + response.setContentType(CONTENT_TYPE_JSON); + response.getWriter().write(ServletMessageHelper.errorMessage(e.getMessage()).toString()); + } + } + + @Override + protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { + doPost(request, response); + } + + /** + * Performs the request: obtains data then forwards to a JSP for printing. + * + * @param request the http request + * @param response the http response + * @throws ServletException if the forward to JSP action fails + * @throws IOException if the forward to JSP action fails + * @throws SchedulerException if unable to schedule the report + * @throws InvalidInputException if something went wrong while parsing TEMPORAL parameters (technical error) + */ + private void perform(final HttpServletRequest request, final HttpServletResponse response) + throws ServletException, IOException, SchedulerException, InvalidInputException { + String reportCodeParamStr = request.getParameter(PARAM_REPORT_CODE); + String pageStr = request.getParameter(PARAM_PAGE); + + // Parse page num + int page; + if (pageStr != null) { + page = Integer.parseInt(pageStr); + } + else { + page = 1; + } + + // Obtain the db data + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + Map dbData; + MngSchedulingReport theMngSchedRep = new MngSchedulingReport(); + if (reportCodeParamStr != null && !"TOUS".equals(reportCodeParamStr)) { + ReportEnum reportCodeParam = ReportEnum.fromCode(reportCodeParamStr); + dbData = theMngSchedRep.searchSchedulingReportByReportCode(session, reportCodeParam, page); + } + else { + dbData = theMngSchedRep.searchAllSchedulingReports(session, page); + } + + // Obtain all reports currently queueing + MngSchedulingCriteriaVal mngSchedulingCriteriaValues = new MngSchedulingCriteriaVal(); + Set schedulings = new TreeSet<>(); + for (Entry entry : dbData.entrySet()) { + DbSchedulingReport dbSchedulingReport = entry.getKey(); + String owner = entry.getValue(); + Long schedulingId = dbSchedulingReport.getId(); + // Find additional scheduling data + Optional nextFireTime = quartz.nextExecutionOfJob(schedulingId); + SchedulingPeriod period = mngSchedulingCriteriaValues.getPeriod(session, schedulingId); + String periodStr = parseToFrench(period); + + // Find authorization status + String reportEntryCode = dbSchedulingReport.getReportCode(); + ReportEnum reportEntryEnum = ReportEnum.fromCode(reportEntryCode); + DbReportType dbReporttype = new MngReportType().search(session, reportEntryEnum); + String authorized = dbReporttype.getReportAuthorized(); + boolean isReportAuthorized = "true".equalsIgnoreCase(authorized); + + // Make a line with all this data + schedulings.add(new SchedulingReportEntry(schedulingId, dbSchedulingReport.getSchedulingName(), reportEntryEnum, + dbSchedulingReport.getLastUpdate(), owner, periodStr, nextFireTime, isReportAuthorized)); + } + + // Add data to the request + request.setAttribute(KEY_SCHEDULINGS, schedulings); + // Forward to the relevant JSP + RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(FORMATTING_JSP_URL); + dispatcher.forward(request, response); + } + finally { + session.close(); + } + } + + private static String parseToFrench(final SchedulingPeriod period) { + String periodStr; + switch (period.getPeriodicity()) { + case DAILY: + periodStr = FR_HUMAN_DAILY; + break; + case DATE: + periodStr = FR_HUMAN_DATE; + break; + case DAY_IN_MONTH_VALUE: + periodStr = FR_HUMAN_MONTHLY; + break; + case WEEKEND: + periodStr = FR_HUMAN_MONTHLY; + break; + case WEEKLY: + periodStr = FR_HUMAN_WEEKLY; + break; + default: + periodStr = "Unknown periodicity"; + break; + } + return periodStr; + } + + /** + * Represents a scheduling report entry. + */ + @Getter + @AllArgsConstructor + public static class SchedulingReportEntry implements Comparable { + + // Data + private final Long id; + private final String planificationName; + private final ReportEnum reportCode; + private final Timestamp lastUpdate; + private final String userResponsable; + private final String period; + private final Optional nextFireTime; + private final boolean isReportAuthorized; + + @Override + public String toString() { + return "SchedulingReportEntry [id=" + id + ", planificationName=" + planificationName + ", reportCode=" + reportCode + ", lastUpdate=" + + lastUpdate + ", userResponsable=" + userResponsable + ", period=" + period + ", nextStart=" + nextFireTime + + ", isReportAuthorized=" + isReportAuthorized + "]"; + } + + @Override + public int compareTo(final SchedulingReportEntry other) { + return this.getPlanificationName().compareTo(other.getPlanificationName()); + } + } +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/utilities/AbstractActionManager.java b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/utilities/AbstractActionManager.java new file mode 100644 index 0000000..cd32254 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/utilities/AbstractActionManager.java @@ -0,0 +1,118 @@ +package com.capgemini.reports.common.scheduling.utilities; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.exceptions.InvalidInputException; +import lombok.extern.slf4j.Slf4j; +import org.json.JSONObject; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * Class used to perform operations on Schedulings.
    + * Example operations: + *
      + *
    • get_sub_period used to obtain the existing parameters of a scheduling when updating it from HMI
    • + *
    • save used to set activation status of a particular report
    • + *
    • is_authorised_report used to obtain activation status of a particular report
    • + *
    + */ +@Slf4j +public abstract class AbstractActionManager extends HttpServlet { + + private static final long serialVersionUID = 3744965867042379548L; + + private static final String CONTENT_TYPE_JSON = "application/json"; + + /** This key can be found in the URL. i.e. 'kurt-web/activateDeactivate?reportCode=R01&reportAuthorized=true' etc. */ + protected static final String URL_KEY_REPORT_CODE = "reportCode"; + + /** + * TOKEN to obtain request TcReleaseStatus from the JSON response. + */ + public static final String TOKEN_STATUS = "status"; + /** TOKEN to obtain error explanation from the JSON response when STATUS is FAILED. */ + public static final String TOKEN_ERROR = "error"; + /** TOKEN to obtain success message from the JSON response. */ + public static final String TOKEN_SUCCESS_MSG = "success"; + + /** STATUS value for the JSON response when posting is successful. */ + public static final String STATUS_SUCCESS = TOKEN_SUCCESS_MSG; + /** STATUS value for the JSON response when posting has failed. */ + public static final String STATUS_FAILED = "failed"; + /** STATUS value for the JSON response when user should be prompted before actually launching the report. */ + public static final String STATUS_PROMPT = "prompt"; + + @Override + protected void doGet(final HttpServletRequest aRequest, final HttpServletResponse aResponse) throws ServletException, IOException { + doPost(aRequest, aResponse); + } + + @Override + protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { + try { + String json = perform(request, response).toString(); + response.getWriter().write(json); + } catch (InsufficientParametersException | InvalidInputException e) { + log.error(e.getMessage(), e); + response.setContentType(CONTENT_TYPE_JSON); + response.getWriter().write(errorMessage(e).toString()); + } + } + + protected abstract JSONObject perform(final HttpServletRequest request, final HttpServletResponse response) + throws InsufficientParametersException, InvalidInputException; + + /** + * Helper function to return standardized success messages to the client. + * + * @param msg the message + * @return the {@link JSONObject} + */ + protected static JSONObject successMessage(final String msg) { + return new JSONObject().put(TOKEN_STATUS, STATUS_SUCCESS).put(TOKEN_SUCCESS_MSG, msg); + } + + /** + * Helper function for producing standardized JSON error messages to be sent to server in case a fault is found. + * + * @param msg the message + * @return the {@link JSONObject} + */ + public static JSONObject errorMessage(final String msg) { + return new JSONObject().put(TOKEN_STATUS, STATUS_FAILED).put(TOKEN_ERROR, msg); + } + + /** + * Helper function for producing standardized JSON error messages to be sent to server in case a fault is found. + * + * @param exception the generic {@link KurtException} that caused the failure + * @return the {@link JSONObject} containing the status and a generic error message + */ + protected static JSONObject errorMessage(final KurtException exception) { + return new JSONObject().put(TOKEN_STATUS, STATUS_FAILED).put(TOKEN_ERROR, exception.getMessage()); + } + + /** + * Try to findAll an argument value in the URL and return an error message in JSP when it failed. + * + * @param aRequest the {@link HttpServletRequest} + * @param anArgName the argument you're looking for + * @return the argument's value + * @throws InsufficientParametersException if the URL argument requested couldn't be found in the {@link HttpServletRequest} + */ + protected static String getMandatoryArg(final HttpServletRequest aRequest, final String anArgName) throws InsufficientParametersException { + String theArgValue = aRequest.getParameter(anArgName); + log.debug("Arg name {}\targ Value {}", anArgName, theArgValue); + if (theArgValue == null) { + String theErrorMessage = "Missing required argument in URL: " + anArgName; + throw new InsufficientParametersException(theErrorMessage); + } + return theArgValue; + } + +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/utilities/ReportActivationReaderServlet.java b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/utilities/ReportActivationReaderServlet.java new file mode 100644 index 0000000..bbf1bec --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/utilities/ReportActivationReaderServlet.java @@ -0,0 +1,58 @@ +package com.capgemini.reports.common.scheduling.utilities; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.manager.MngReportType; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.exceptions.InvalidInputException; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.json.JSONObject; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Servlet handling requests to read activation status of the report in DB.
    + * Receives http requests with URL parameters: + *
      + *
    • reportCode={REPORT_CODE}
    • + *
    + * Example:
    + * {@code kurt-web/reportActivation?reportCode=R01} + */ +@Slf4j +@WebServlet("/reportActivation") +public class ReportActivationReaderServlet extends AbstractActionManager { + + private static final long serialVersionUID = -3288930443279088612L; + + private static final String SUCESS_MESSAGE_IS_AUTHORIZED = "La demande a bien été prise en compte"; + private static final String ERROR_MESSAGE_IS_AUTHORIZED = "Le lancement de ce rapport n'est pas autorisé"; + + @Override + protected JSONObject perform(final HttpServletRequest request, final HttpServletResponse response) + throws InsufficientParametersException { + log.info("Start Manager scheduling Report ...."); + return isAuthorizedReport(request); + } + + private JSONObject isAuthorizedReport(final HttpServletRequest request) throws InsufficientParametersException { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + MngReportType mngReportType = new MngReportType(); + if (mngReportType.isAuthorized(session, getMandatoryArg(request, URL_KEY_REPORT_CODE))) { + return successMessage(SUCESS_MESSAGE_IS_AUTHORIZED); + } + else { + return errorMessage(new KurtException(ERROR_MESSAGE_IS_AUTHORIZED)); + } + } + finally { + session.close(); + } + } +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/utilities/ReportActivatorServlet.java b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/utilities/ReportActivatorServlet.java new file mode 100644 index 0000000..ef776a2 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/utilities/ReportActivatorServlet.java @@ -0,0 +1,53 @@ +package com.capgemini.reports.common.scheduling.utilities; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.json.JSONObject; + +import com.capgemini.reports.database.javabean.DbReportType; +import com.capgemini.reports.database.manager.MngReportType; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.exceptions.InvalidInputException; + +import lombok.extern.slf4j.Slf4j; + +/** + * Servlet handling requests to chachge activation status of the report in DB.
    + * Receives http requests with URL parameters: + *
      + *
    • reportCode={REPORT_CODE}
    • + *
    • reportAuthorized={AUTHORIZATION}
    • + *
    + * Example:
    + * {@code kurt-web/activateDeactivate?reportCode=R01&reportAuthorized=true} + */ +@Slf4j +@WebServlet("/activateDeactivate") +public class ReportActivatorServlet extends AbstractActionManager { + + private static final long serialVersionUID = 403605177414500576L; + + private static final String URL_KEY_REPORT_AUTHORIZED = "reportAuthorized"; + + @Override + protected JSONObject perform(final HttpServletRequest request, final HttpServletResponse response) + throws InsufficientParametersException, InvalidInputException { + log.info("Start Manager scheduling Report ...."); + return enableDisableAuthorizedReport(request); + } + + /*Save or Unsaved scheduling report */ + private JSONObject enableDisableAuthorizedReport(final HttpServletRequest request) throws InsufficientParametersException { + String reportCode = getMandatoryArg(request, URL_KEY_REPORT_CODE); + String reportAuthorized = getMandatoryArg(request, URL_KEY_REPORT_AUTHORIZED); + + log.info("Update {} activation with value {}", reportCode, reportAuthorized); + + DbReportType dbReportType = new MngReportType().setReportActivation(reportCode, reportAuthorized); + + return successMessage("La modification a bien été prise en compte pour le rapport " + dbReportType.getTitle()); + } + +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/utilities/SchedulingPeriodReaderServlet.java b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/utilities/SchedulingPeriodReaderServlet.java new file mode 100644 index 0000000..d897a49 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/utilities/SchedulingPeriodReaderServlet.java @@ -0,0 +1,70 @@ +package com.capgemini.reports.common.scheduling.utilities; + +import com.capgemini.reports.common.scheduling.view.SchedulingParametersReader; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.enumeration.SchedulingEnum; +import com.capgemini.reports.database.manager.MngSchedulingCriteriaVal; +import com.capgemini.reports.exceptions.InsufficientParametersException; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.periodicity.PeriodFactory; +import com.capgemini.reports.periodicity.SchedulingPeriod; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.json.JSONObject; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Servlet handling requests for periodicity data.
    + * Receives http requests with URL parameters: + *
      + *
    • subPeriod={SUB_PERIOD} The period that is currently selected (daily/weekly/monthly/date)
    • + *
    • isUpdate={BOOLEAN} True if an existing scheduling is being update (existing values should be retreived in DB), false if it is a brand new scheduling.
    • + *
    • id={ID} (OPTIONAL) the identifier of the updating report, only present if isUpdate is true
    • + *
    + */ +@Slf4j +@WebServlet("/getScheduling") +public class SchedulingPeriodReaderServlet extends AbstractActionManager { + private static final long serialVersionUID = 6495163507120953894L; + private static final String SUCESS_MESSAGE = ""; // No need for a message to the user, it is sufficient to simply update the page + + @Override + protected JSONObject perform(final HttpServletRequest request, final HttpServletResponse response) + throws InsufficientParametersException, InvalidInputException { + log.info("Start Manager scheduling Report ...."); + return getSubPeriod(request); + } + + /* Return sub period of current period */ + private JSONObject getSubPeriod(final HttpServletRequest request) throws InsufficientParametersException, InvalidInputException { + String subPeriod = getMandatoryArg(request, "subPeriod"); + String isUpdateStr = getMandatoryArg(request, "isUpdate"); + Boolean isUpdate = Boolean.valueOf(isUpdateStr); + SchedulingPeriod period; + if (isUpdate) { + String schedulingIdStr = getMandatoryArg(request, "id"); + Long schedulingId = Long.valueOf(schedulingIdStr); + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + period = new MngSchedulingCriteriaVal().getPeriod(session, schedulingId); + } + finally { + session.close(); + } + } + else { + period = PeriodFactory.daily(); + } + log.info("subPeriod {} active={} id={}", subPeriod, isUpdate, period.toString()); + SchedulingEnum periodicity = SchedulingEnum.getEnum(subPeriod); + String content = new SchedulingParametersReader().getSubPeriod(periodicity, period, isUpdate); + log.info("Content [" + content + "]"); + + return successMessage(SUCESS_MESSAGE).put("content", content); + } +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/view/NewSchedulingFormatter.java b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/view/NewSchedulingFormatter.java new file mode 100644 index 0000000..e6093ea --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/view/NewSchedulingFormatter.java @@ -0,0 +1,37 @@ +package com.capgemini.reports.common.scheduling.view; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.reports.database.javabean.enumeration.SchedulingEnum; +import com.hp.gagawa.java.elements.Div; + +/** This formatter page can display an empty scheduling data page. It is used in the 'new scheduling' page. */ +public class NewSchedulingFormatter extends SchedulingFormatter { + + + /** + * Builds the html content that will show the page, in html. + * + * @return the page contents (html) + */ + public String showNewReportSchedulingPage() { + // Parent + Div parent = new Div(); + parent.setId("div_temporal"); + + // scheduling name + Div containerSchedulingName = getSchedulingName(StringHelper.EMPTY); + parent.appendChild(containerSchedulingName); + + // period + Div containerPeriod = getPeriod(SchedulingEnum.DAILY, null).setId("div_container_period").setCSSClass(SUB_TITLE_PLANIFICATION); + parent.appendChild(containerPeriod); + + Div containerSubPeriod = new Div(); + containerSubPeriod.setId("div_container_subPeriod").setStyle(MARGIN_TOP_10PX).setCSSClass(SUB_TITLE_SUB_PERIOD); + parent.appendChild(containerSubPeriod); + + return parent.write(); + } + + +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/view/SchedulingFormatter.java b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/view/SchedulingFormatter.java new file mode 100644 index 0000000..ef044d8 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/view/SchedulingFormatter.java @@ -0,0 +1,306 @@ +package com.capgemini.reports.common.scheduling.view; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.enumeration.SchedulingEnum; +import com.capgemini.reports.database.manager.MngSchedulingCriteriaVal; +import com.capgemini.reports.periodicity.*; +import com.capgemini.reports.periodicity.SchedulingPeriod.PeriodVisitor; +import com.hp.gagawa.java.elements.*; +import lombok.Getter; +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +import java.text.SimpleDateFormat; + +/** + * Formatting class for schedulings. Can extract scheduling data from the DB, and format it into html {@link Div}s and {@link Input}s.
    + * Implements the {@link PeriodVisitor} interface, to analyze a {@link SchedulingPeriod} and show it as a html {@link Div}. + */ +@Getter +public class SchedulingFormatter implements PeriodVisitor
    { + + // Period keys + private static final String PERIOD_DAY_IN_MONTH_VALUE = SchedulingEnum.DAY_IN_MONTH_VALUE.getCriteriaName(); + private static final String PERIOD_WEEKEND = SchedulingEnum.WEEKEND.getCriteriaName(); + private static final String PERIOD_WEEKLY = SchedulingEnum.WEEKLY.getCriteriaName(); + + // Period Values + private static final String KEY_DAY_IN_MONTH_VALUE = PERIOD_DAY_IN_MONTH_VALUE; // This one is both a Periodicity value and a key + private static final String KEY_END_OF_MONTH = WeekendPeriod.END_MONTH.getStrMonthType(); + private static final String KEY_FIRST_WE = WeekendPeriod.FIRST_WEEK_END.getStrMonthType(); + private static final String KEY_SECOND_WE = WeekendPeriod.SECOND_WEEK_END.getStrMonthType(); + private static final String KEY_THIRD_WE = WeekendPeriod.THIRD_WEEK_END.getStrMonthType(); + private static final String KEY_FOURTH_WE = WeekendPeriod.FOURTH_WEEK_END.getStrMonthType(); + private static final String KEY_FIFTH_WE = WeekendPeriod.FIFTH_WEEK_END.getStrMonthType(); + + // Error message + private static final String MESSAGE_REPORT_NOT_AUTHORIZED = "Ce rapport n'est pas disponible, car il est planifié"; + + // html Positioning + protected static final String MARGIN_TOP_10PX = " margin-top: 10px; "; + private static final String MARGIN_BOTTOM_20PX = " margin-bottom: 10px; "; + private static final String P_STYLE_SUBPERIOD = "display:inline;margin-right:10px; "; + private static final String DATEPICKER_KEY = "datepicker_planification"; + + // html constants + private static final String TYPE_TEXT = "text"; + private static final String TYPE_RADIO = "radio"; + private static final String EVENT_ON_CLICK = "onclick"; + private static final String CHECKED = "checked"; + + // CSS constants + private static final String CSS_CLASS_RADIO_INPUT = "radioInput"; + + // Translation to french + private static final String TEXT_ALL_DAYS = "Tous les jours"; + private static final String TEXT_ALL_WEEK = "Toutes les semaines"; + private static final String TEXT_ALL_MONTH = "Tous les mois"; + private static final String TEXT_BY_DATE = "Date"; + + // Weekdays in french + private static final String MONDAY_FR = "Lundi"; + private static final String TUESDAY_FR = "Mardi"; + private static final String WEDNESDAY_FR = "Mercredi"; + private static final String THURSDAY_FR = "Jeudi"; + private static final String FRIDAY_FR = "Vendredi"; + + // Weekday Nums + private static final int MONDAY_NUM = 1; + private static final int TUESDAY_NUM = 2; + private static final int WEDNESDAY_NUM = 3; + private static final int THURSDAY_NUM = 4; + private static final int FRIDAY_NUM = 5; + + // Weekends in french + private static final String FR_DAY_IN_MONTH = "Jour dans le mois"; + private static final String FR_END_OF_MONTH = "Fin du mois"; + private static final String FR_FIRST_WE = "1er Week-End"; + private static final String FR_SECOND_WE = "2nd Week-End"; + private static final String FR_THIRD_WE = "3ème Week-End"; + private static final String FR_FOURTH_WE = "4ème Week-End"; + private static final String FR_FIFTH_WE = "5ème Week-End"; + + // Javascript functions + protected static final String SUB_TITLE_PLANIFICATION = "subTitle_planification"; + private static final String SUB_TITLE_PLANIFICATION_REQUIRED = "subTitle_planification_Required"; + protected static final String SUB_TITLE_SUB_PERIOD = "subTitle_sub_period"; + + /* */ + Div getPeriod(final SchedulingEnum thePeriod, final Long identifier) { + // TEXT period + P paragraph = new P(); + paragraph.setStyle("margin-left: 20px; display:inline; margin-right:30px;").setCSSClass(SUB_TITLE_PLANIFICATION_REQUIRED) + .appendText("Période* : "); + // period + Div period = makePeriod(thePeriod, identifier); + return new Div().setStyle(MARGIN_TOP_10PX).setAlign("left").appendChild(paragraph).appendChild(period); + } + + + /*Make bloc period */ + private Div makePeriod(final SchedulingEnum thePeriod, final Long identifier) { + String name = "period"; + + Div containerPeriod = new Div(); + containerPeriod.setStyle("margin-left: 80px; margin-top: 10px;display:inline;").setId("div_period"); + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + String activePeriod = identifier == null ? "" : new MngSchedulingCriteriaVal().getPeriodOfSchedulingReportById(session, identifier).getName(); + + // Construct all the Radio Buttons + boolean isDaily = thePeriod == SchedulingEnum.DAILY; + boolean isWeekly = thePeriod == SchedulingEnum.WEEKLY; + boolean isMonthly = thePeriod == SchedulingEnum.WEEKEND || thePeriod == SchedulingEnum.DAY_IN_MONTH_VALUE; + boolean isDate = thePeriod == SchedulingEnum.DATE; + + Input daily = inputRadio(name, SchedulingEnum.DAILY, isDaily, EVENT_ON_CLICK, + makeJsFunctionGetSubPeriod(SchedulingEnum.DAILY, identifier, activePeriod)); + + Input weekly = inputRadio(name, SchedulingEnum.WEEKLY, isWeekly, EVENT_ON_CLICK, + makeJsFunctionGetSubPeriod(SchedulingEnum.WEEKLY, identifier, activePeriod)); + + Input monthly = inputRadio(name, SchedulingEnum.WEEKEND, isMonthly, EVENT_ON_CLICK, + makeJsFunctionGetSubPeriod(SchedulingEnum.WEEKEND, identifier, activePeriod)).setId("div_period_monthly"); + + Input date = inputRadio(name, SchedulingEnum.DATE, isDate, EVENT_ON_CLICK, + makeJsFunctionGetSubPeriod(SchedulingEnum.DATE, identifier, activePeriod)).setId("div_period_date"); + + // Construct the Div orderly + containerPeriod.appendChild(daily).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(TEXT_ALL_DAYS)); + containerPeriod.appendChild(weekly).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(TEXT_ALL_WEEK)); + containerPeriod.appendChild(monthly).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(TEXT_ALL_MONTH)); + containerPeriod.appendChild(date).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(TEXT_BY_DATE)); + + return containerPeriod; + } + finally { + session.close(); + } + } + + /* Function for period */ + private String makeJsFunctionGetSubPeriod(final SchedulingEnum period, final Long identifier, final String activePeriod) { + return "getSubPeriod('" + period.toString() + "', '" + identifier + "', '" + period.getCriteriaName().equals(activePeriod) + "');"; + } + + Div getSchedulingName(final String theScheduligName) { + String schedulingName = "scheduling_name"; + Label labelSchedulingName = makeLabel(schedulingName, "margin-left: 20px; margin-right: 140px;", "Nom* :") + .setCSSClass(SUB_TITLE_PLANIFICATION + " " + SUB_TITLE_PLANIFICATION_REQUIRED); + Input inputSchedulingName = inputText(schedulingName, theScheduligName).setStyle("width:380px;height:20px;").setId(schedulingName); + return new Div().setId("div_scheduling_name").setAlign("left").appendChild(labelSchedulingName).appendChild(inputSchedulingName); + } + + private Label makeLabel(final String forName, final String style, final String text) { + return new Label().setFor(forName).setStyle(style).appendChild(new Text(text)); + } + + /** + * Creates an {@link Input} of type Radio Button. + */ + private static Input inputRadio(final String name, final String value, final boolean checked) { + Input radio = new Input(); + radio.setCSSClass(CSS_CLASS_RADIO_INPUT).setName(name).setType(TYPE_RADIO).setValue(value); + if (checked) { + radio.setAttribute(CHECKED, CHECKED); + } + return radio; + } + + /** + * Creates an {@link Input} of type Radio Button.
    + * Example: if checked is true and event in onclick
    + * <input class="radioInput" type="radio" name=${NAME} value=${VALUE} onclick=${FUNCTION}> + */ + private static Input inputRadio(final String name, final SchedulingEnum value, final boolean checked, final String typeEvent, + final String functionOnEvent) { + Input radio = new Input(); + radio.setCSSClass(CSS_CLASS_RADIO_INPUT).setType(TYPE_RADIO).setName(name).setValue(value.getCriteriaName()).setAttribute(typeEvent, + functionOnEvent); + if (checked) { + radio.setAttribute(CHECKED, CHECKED); + } + return radio; + } + + /** + * Creates an {@link Input} of type "text".
    + * Example:
    + * <input type="text" name=${NAME} value=${VALUE}> + * + * @param name the name of the input + * @param value the value inside the input + * @return a text {@link Input} + */ + private static Input inputText(final String name, final String value) { + return new Input().setType(TYPE_TEXT).setName(name).setValue(value); + } + + @Override + public Div visit(final DayInMonth theDayInMonth) { + // Build the 'day_in_month' radio and input. + Input dayInMonth = inputRadio(PERIOD_WEEKEND, KEY_DAY_IN_MONTH_VALUE, true); // True because this is DAY_IN_MONTH period + Input dayInMonthValue = inputText(PERIOD_DAY_IN_MONTH_VALUE, theDayInMonth.getDayInMonth().toString()).setMaxlength("2") + .setId("dayInMonthValue").setStyle("width:24px;height:20px;margin-right:10px;"); + + // Even if DayInMonth is selected, each weekend button must also be constructed (unchecked), as both are accessible via the same radio button + + Input endOfMonth = inputRadio(PERIOD_WEEKEND, KEY_END_OF_MONTH, false); // False because this is DAY_IN_MONTH PERIOD + Input firstWE = inputRadio(PERIOD_WEEKEND, KEY_FIRST_WE, false); // False because this is DAY_IN_MONTH PERIOD + Input secondWE = inputRadio(PERIOD_WEEKEND, KEY_SECOND_WE, false); // False because this is DAY_IN_MONTH PERIOD + Input thirdWE = inputRadio(PERIOD_WEEKEND, KEY_THIRD_WE, false); // False because this is DAY_IN_MONTH PERIOD + Input fourthWE = inputRadio(PERIOD_WEEKEND, KEY_FOURTH_WE, false); // False because this is DAY_IN_MONTH PERIOD + Input fifthWE = inputRadio(PERIOD_WEEKEND, KEY_FIFTH_WE, false); // False because this is DAY_IN_MONTH PERIOD + + + // Make a Div and (orderly) add the radio buttons to it + Div containerWeekEnd = new Div(); + containerWeekEnd.setStyle("margin-left: 18px; display:inline;").setId("div_weekend"); + containerWeekEnd.appendChild(dayInMonth).appendChild(new P().setStyle("display:inline; ").appendText(FR_DAY_IN_MONTH)); + containerWeekEnd.appendChild(dayInMonthValue); + containerWeekEnd.appendChild(endOfMonth).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(FR_END_OF_MONTH)); + containerWeekEnd.appendChild(firstWE).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(FR_FIRST_WE)); + containerWeekEnd.appendChild(secondWE).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(FR_SECOND_WE)); + containerWeekEnd.appendChild(thirdWE).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(FR_THIRD_WE)); + containerWeekEnd.appendChild(fourthWE).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(FR_FOURTH_WE)); + containerWeekEnd.appendChild(fifthWE).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(FR_FIFTH_WE)); + + return containerWeekEnd; + } + + @Override + public Div visit(final WeekendPeriod weekend) { + // Build the 'day_in_month' radio and input. Even if WeekEnd Period is selected, then day_of_month must also be constructed (blank), as both are accessible via the same radio button + Input dayInMonth = inputRadio(PERIOD_WEEKEND, KEY_DAY_IN_MONTH_VALUE, false); // False because this is WEEKEND PERIOD + Input dayInMonthValue = inputText(PERIOD_DAY_IN_MONTH_VALUE, StringHelper.EMPTY).setMaxlength("2").setId("dayInMonthValue") + .setStyle("width:24px;height:20px;margin-right:10px;"); // Initialize day in month to empty (this is WEEKEND PERIOD) + + // Build the 'weekend' radio buttons. Only the provided weekend will be checked. + Input endOfMonth = inputRadio(PERIOD_WEEKEND, KEY_END_OF_MONTH, weekend == WeekendPeriod.END_MONTH); + Input firstWE = inputRadio(PERIOD_WEEKEND, KEY_FIRST_WE, weekend == WeekendPeriod.FIRST_WEEK_END); + Input secondWE = inputRadio(PERIOD_WEEKEND, KEY_SECOND_WE, weekend == WeekendPeriod.SECOND_WEEK_END); + Input thirdWE = inputRadio(PERIOD_WEEKEND, KEY_THIRD_WE, weekend == WeekendPeriod.THIRD_WEEK_END); + Input fourthWE = inputRadio(PERIOD_WEEKEND, KEY_FOURTH_WE, weekend == WeekendPeriod.FOURTH_WEEK_END); + Input fifthWE = inputRadio(PERIOD_WEEKEND, KEY_FIFTH_WE, weekend == WeekendPeriod.FIFTH_WEEK_END); + + // Make a Div and (orderly) add the radio buttons to it + Div containerWeekEnd = new Div(); + containerWeekEnd.setStyle("margin-left: 18px; display:inline;").setId("div_weekend"); + containerWeekEnd.appendChild(dayInMonth).appendChild(new P().setStyle("display:inline; ").appendText(FR_DAY_IN_MONTH)); + containerWeekEnd.appendChild(dayInMonthValue); + containerWeekEnd.appendChild(endOfMonth).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(FR_END_OF_MONTH)); + containerWeekEnd.appendChild(firstWE).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(FR_FIRST_WE)); + containerWeekEnd.appendChild(secondWE).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(FR_SECOND_WE)); + containerWeekEnd.appendChild(thirdWE).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(FR_THIRD_WE)); + containerWeekEnd.appendChild(fourthWE).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(FR_FOURTH_WE)); + containerWeekEnd.appendChild(fifthWE).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(FR_FIFTH_WE)); + + return containerWeekEnd; + } + + @Override + public Div visit(final SpecificDay specificDay) { + // TEXT date + Label labelSchedulingName = makeLabel(DATEPICKER_KEY, "margin-left: 20px; margin-right: 50px; ", "Date de planification"); + String dateStr = new SimpleDateFormat(TeamcenterDateFormatter.DD_MM_YYYY).format(specificDay.getDay()); + Input inputSchedulingName = inputText(DATEPICKER_KEY, dateStr).setId(DATEPICKER_KEY).setStyle("cursor:hand;width:80px;height:20px;"); + + Div flowElement = new Div(); + flowElement.setCSSClass("flow-element").appendChild(new Div().setId("container_planification")); + return new Div().setId("div_date").setStyle(MARGIN_TOP_10PX).appendChild(labelSchedulingName).appendChild(inputSchedulingName) + .appendChild(flowElement); + } + + @Override + public Div visit(final WeeklyPeriod dayInWeek) { + Input monday = inputRadio(PERIOD_WEEKLY, String.valueOf(MONDAY_NUM), dayInWeek.getDayInWeek() == MONDAY_NUM); + Input tuesday = inputRadio(PERIOD_WEEKLY, String.valueOf(TUESDAY_NUM), dayInWeek.getDayInWeek() == TUESDAY_NUM); + Input wednesday = inputRadio(PERIOD_WEEKLY, String.valueOf(WEDNESDAY_NUM), dayInWeek.getDayInWeek() == WEDNESDAY_NUM); + Input thursday = inputRadio(PERIOD_WEEKLY, String.valueOf(THURSDAY_NUM), dayInWeek.getDayInWeek() == THURSDAY_NUM); + Input friday = inputRadio(PERIOD_WEEKLY, String.valueOf(FRIDAY_NUM), dayInWeek.getDayInWeek() == FRIDAY_NUM); + + // Put it all (orderly) in a
    container + Div containerDaily = new Div(); + containerDaily.setStyle("margin-left: 200px; display:inline;").setId("div_weekly"); + containerDaily.appendChild(monday).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(MONDAY_FR)); + containerDaily.appendChild(tuesday).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(TUESDAY_FR)); + containerDaily.appendChild(wednesday).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(WEDNESDAY_FR)); + containerDaily.appendChild(thursday).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(THURSDAY_FR)); + containerDaily.appendChild(friday).appendChild(new P().setStyle(P_STYLE_SUBPERIOD).appendText(FRIDAY_FR)); + + return containerDaily; + } + + @Override + public Div visit(final DailyPeriod uselessParam) { + // TEXT period

    + P paragraph = new P(); + paragraph.setStyle("margin-left: 210px; display:inline; margin-right:30px;").appendText("Tous les jours"); + // period

    + return new Div().setStyle(MARGIN_TOP_10PX).setAlign("left").appendChild(paragraph); + } + +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/view/SchedulingParametersReader.java b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/view/SchedulingParametersReader.java new file mode 100644 index 0000000..87c6a75 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/view/SchedulingParametersReader.java @@ -0,0 +1,56 @@ +package com.capgemini.reports.common.scheduling.view; + +import com.capgemini.reports.database.javabean.enumeration.SchedulingEnum; +import com.capgemini.reports.periodicity.*; + +/** This class can interrogate the DB and show sub-period parameters either loaded with DB data, or empty. */ +public class SchedulingParametersReader extends SchedulingFormatter { + + private static final WeeklyPeriod DEFAUT_VALUE_OF_WEEKLY = PeriodFactory.weekly(1); + private static final DayInMonth DEFAUT_VALUE_OF_WEEKEND = PeriodFactory.dayInMonth(1); + private static final DailyPeriod DEFAULT_VALUE_OF_DAILY = PeriodFactory.daily(); + + /** + * Return html code representing all the sub period data, pre-fileld or not. + * + * @param currentlySelectedSubPeriod the requested sup-period to display. (weekly / weekend...) + * @param existingUpdatePeriodFromDB optional, is present if isUpdate is true. + * @param isUpdate a boolean, true if a report scheduling is being update + * @return content sub period + */ + public String getSubPeriod(final SchedulingEnum currentlySelectedSubPeriod, final SchedulingPeriod existingUpdatePeriodFromDB, + final boolean isUpdate) { + if (isUpdate && existingUpdatePeriodFromDB.getPeriodicity() == currentlySelectedSubPeriod) { + return existingUpdatePeriodFromDB.accept(this).write(); + } else { + return getSubPeriodForNewScheduling(currentlySelectedSubPeriod); + } + } + + /** + * Return content of sub period. + * + * @param subPeriod + * @return content sub period + */ + private String getSubPeriodForNewScheduling(final SchedulingEnum subPeriod) { + final String result; + switch (subPeriod) { + case DAILY: + result = this.visit(DEFAULT_VALUE_OF_DAILY).write(); + break; + case WEEKLY: + result = this.visit(DEFAUT_VALUE_OF_WEEKLY).write(); + break; + case WEEKEND: + result = this.visit(DEFAUT_VALUE_OF_WEEKEND).write(); + break; + case DATE: + result = this.visit(PeriodFactory.today()).write(); + break; + default: + throw new UnsupportedOperationException("Unable to understand scheduling sub-period of type " + subPeriod); + } + return result; + } +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/view/UpdateSchedulingFormatter.java b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/view/UpdateSchedulingFormatter.java new file mode 100644 index 0000000..c65bc3b --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/common/scheduling/view/UpdateSchedulingFormatter.java @@ -0,0 +1,79 @@ +package com.capgemini.reports.common.scheduling.view; + +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.database.javabean.DbSchedulingCriteriaVal; +import com.capgemini.reports.database.javabean.DbSchedulingReport; +import com.capgemini.reports.database.manager.MngSchedulingCriteriaVal; +import com.capgemini.reports.database.manager.MngSchedulingReport; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.periodicity.SchedulingPeriod; +import com.hp.gagawa.java.elements.Div; +import com.hp.gagawa.java.elements.Input; + +import lombok.Getter; +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +/** + * This formatter page can display the existing scheduling data of a SchedulingReport from the DB. It is used in the 'update scheduling' page. + */ +@Getter +public class UpdateSchedulingFormatter extends SchedulingFormatter { + + private final Long reportId; + + /** + * Builds a formatter instance, that can display the 'update scheduling' page of the provided Scheduling Report ID. + * + * @param reportId the id of a {@link DbSchedulingReport} from the DB + */ + public UpdateSchedulingFormatter(final Long reportId) { + super(); + this.reportId = reportId; + } + + /** + * Builds the html content that will show the scheduling's parameters, in html. + */ + public String showReportUpdatePage() throws InvalidInputException { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + final String uncheckedSchedulingName = new MngSchedulingReport().searchById(session, reportId).getSchedulingName(); + String theSchedulingName = uncheckedSchedulingName == null ? "" : uncheckedSchedulingName; + + SchedulingPeriod thePeriodicity = new MngSchedulingCriteriaVal().getPeriod(session, reportId); + + // hidden id of scheduling report + Input hidden = new Input().setType("hidden").setName("id").setValue(String.valueOf(reportId)); + + // scheduling name + Div containerSchedulingName = getSchedulingName(theSchedulingName); + + // Period (daily / weekly / weekend / date) + Div containerPeriod = getPeriod(thePeriodicity.getPeriodicity(), reportId).setId("div_container_period").setCSSClass(SUB_TITLE_PLANIFICATION); + + // Sub period (day in week / weekend num / day in month / date + Div containerSubPeriod = new Div(); + containerSubPeriod.setId("div_container_subPeriod").setStyle(MARGIN_TOP_10PX).setCSSClass(SUB_TITLE_SUB_PERIOD); + + // Active subPeriod + Div containerAllSubPeriods = thePeriodicity.accept(this); + + containerSubPeriod.appendChild(containerAllSubPeriods); + + // Parent + Div parent = new Div(); + parent.setId("div_temporal"); + parent.appendChild(hidden); + parent.appendChild(containerSchedulingName); + parent.appendChild(containerPeriod); + parent.appendChild(containerSubPeriod); + + return parent.write(); + } + finally { + session.close(); + } + } +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/formatting/AbstractTableFormatter.java b/kurt-web/src/main/java/com/capgemini/reports/formatting/AbstractTableFormatter.java new file mode 100644 index 0000000..68d0195 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/formatting/AbstractTableFormatter.java @@ -0,0 +1,99 @@ +package com.capgemini.reports.formatting; + +import com.capgemini.framework.common.FileTemplate; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.database.HibernateUtil; +import com.capgemini.reports.exceptions.NothingToBeShownException; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.HibernateException; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.quartz.SchedulerException; + +/** + * This abstract class allows easy creation of a js table.
    + * If no data exist or if an errror occurs during the table construction, an appropriate message is shown. + */ +@Slf4j +public abstract class AbstractTableFormatter extends FileTemplate { + + private static final String TAG_TABLE_DATA = "TABLE_DATA"; + private static final String TAG_ERROR_MESSAGE = "ERROR_MESSAGE"; + + /** + * Generates a html page displaying a table.
    + * If not elements exist in the table, shows a message that says so.
    + * If the DB could not be queried, shows an error message. + * + * @return the full html page content + */ + public String makeJsContent() { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + Session session = sessionFactory.openSession(); + try { + String jsDataTable = makeTable(session); // Attempt to format all the reports into a JS table + super.setTemplateFilePath(successPageTemplateLocation()); + super.setTagValue(TAG_TABLE_DATA, jsDataTable); + this.addOptionalTags(session); + } + catch (NothingToBeShownException e) { + // This is normal behaviour: the table does not contain any matching entries. No worries + log.trace("Normal exception: nothing to show in HMI", e); + super.setTemplateFilePath(failedPageTemplateLocation()); + super.setTagValue(TAG_ERROR_MESSAGE, e.getErrorMessageForUser()); + this.addOptionalErrorTags(); + } + catch (KurtException e) { + // A Technical error occured, unable to display the screen contents + super.setTemplateFilePath(failedPageTemplateLocation()); + super.setTagValue(TAG_ERROR_MESSAGE, e.getErrorMessageForUser()); + this.addOptionalErrorTags(); + log.debug("Unable to perform user request", e); + } + catch (HibernateException e) { + super.setTemplateFilePath(failedPageTemplateLocation()); + super.setTagValue(TAG_ERROR_MESSAGE, "Impossible de communiquer avec la base de données"); + this.addOptionalErrorTags(); + log.error("A Database error occured while trying to show MyReports table", e); // This is not normal behaviour. Check query syntax, and Hibernate config + } + catch (SchedulerException e) { + super.setTemplateFilePath(failedPageTemplateLocation()); + super.setTagValue(TAG_ERROR_MESSAGE, "Impossible de communiquer avec le système de planification"); + this.addOptionalErrorTags(); + log.error("An error occurred while communicationg with Quartz", e); // This is not normal behaviour. Check Quartz setup + } + finally { + session.close(); + } + return this.generateCode(); + } + + /** + * Allows to add optional tags, if the template is a bit more complex. + */ + protected abstract void addOptionalTags(Session session); + + /** + * Allows to add optional tags, if the ERROR template is a bit more complex. + */ + protected abstract void addOptionalErrorTags(); + + /** + * Main method: builds a javascript table to be inserted into the webpage. + */ + protected abstract String makeTable(Session session) throws KurtException, SchedulerException; + + /** + * The location of the template html page, in case the data was successfully retrieved. + * + * @return the file location in src/main/resources + */ + protected abstract String successPageTemplateLocation(); + + /** + * The location of the template html page, in case the data could not be retrieved. + * + * @return the file location in src/main/resources + */ + protected abstract String failedPageTemplateLocation(); +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/formatting/AllSchedulingReports.java b/kurt-web/src/main/java/com/capgemini/reports/formatting/AllSchedulingReports.java new file mode 100644 index 0000000..8e7594a --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/formatting/AllSchedulingReports.java @@ -0,0 +1,289 @@ +package com.capgemini.reports.formatting; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.common.activedirectory.ActiveDirectory; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.common.scheduling.controller.SchedulingReaderServlet.SchedulingReportEntry; +import com.capgemini.reports.database.javabean.DbUser.UserData; +import com.capgemini.reports.database.manager.MngReportType; +import com.capgemini.reports.database.manager.MngSchedulingReport; +import com.capgemini.reports.exceptions.InvalidActiveDirectorySearchException; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.NoConnectionToActiveDirectoryException; +import com.capgemini.reports.exceptions.NothingToBeShownException; +import com.google.common.base.Optional; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringEscapeUtils; +import org.hibernate.Session; + +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +/** + * This page displays all information on report schduling. + *

    + * Top left is a filter on report codes
    + * Top right is a combobox that tells if the report selected in the filter will
    + * Below is a table listing all currently scheduled reports: + *

      + *
    1. Report Code (R01 / R20...)
    2. + *
    3. Scheduling name
    4. + *
    5. Periodicity (weekly, monthly, etc.)
    6. + *
    7. Last modification date
    8. + *
    9. Owning administrator (final a User)
    10. + *
    11. Next scheduled launch
    12. + *
    13. A button opening a popup showing the report's Functional parameters
    14. + *
    15. A button opening a page to edit the line's scheduling parameters
    16. + *
    17. A button to delete the line's schedule altogether.
    18. + *
    + */ +@Slf4j +public class AllSchedulingReports extends AbstractTableFormatter { + + + private static final boolean DEV_MODE = SettingsHelper.isDevMode(); + private static final int MAX_PAGE_SIZE = SettingsHelper.getJspPaging(); + + private static final String QUOTE_WITH_END_COMMA = "' ; "; + private static final String BUTTON_END = ""; + + private static final String TAG_SELECT_DATA = "SELECT_DATA"; + private static final String TAG_DISPLAY_BUTTONS = "DISPLAY_BUTTONS"; + private static final String TAG_ACTIF_REPORT_NAME = "ACTIF_REPORT_NAME"; + private static final String TAG_ACTIF_REPORT_VALUE = "ACTIF_REPORT_VALUE"; + private static final String TAG_ACTIF_BUTTON_VALIDATE = "ACTIF_BUTTON_VALIDATE"; + private static final String TAG_PAGING = "PAGING"; + /** + * Date Format of the form 'dd-MMMM-yyyy' which gives '08-April-2014' in US timezone. + */ + private static final String DD_MMMM_YYYY = "dd MMMM yyyy"; + private static final String SIMPLE_FORMATTER = DD_MMMM_YYYY; + + private final String theUserLogin; + + /** + * The report filter. May be null far 'all'. + */ + private final Optional reportCode; + private final String thePageParamStr; + private final Set entries; + private String paging; + + /** + * Constructs an instance of this page. Invoke {@link AllSchedulingReports#makeJsContent()} to generate it.
    + * This page displays all information on report scheduling. + *

    + * Top left is a filter on report codes
    + * Top right is a combobox that tells if the report selected in the filter will
    + * Below is a table listing all currently scheduled reports: + *

      + *
    1. Report Code (R01 / R20...)
    2. + *
    3. Scheduling name
    4. + *
    5. Periodicity (weekly, monthly, etc.)
    6. + *
    7. Last modification date
    8. + *
    9. Owning administrator (final a User)
    10. + *
    11. Next scheduled launch
    12. + *
    13. A button opening a popup showing the report's Functional parameters
    14. + *
    15. A button opening a page to edit the line's scheduling parameters
    16. + *
    17. A button to delete the line's schedule altogether.
    18. + *
    + * + * @param reportCode the {@link ReportEnum} (maybe null for ALL) + * @param thePageParamStr (optional) the page number.
    + * possible values: 1, 2, 3... + * @param theUserLogin the login of the user who requested the page + * @param entries a {@link Set} of {@link SchedulingReportEntry} obtained from the DB, that belong to the user + */ + public AllSchedulingReports(final ReportEnum reportCode, final String thePageParamStr, final String theUserLogin, + final Set entries) { + super(); + this.reportCode = Optional.fromNullable(reportCode); + this.thePageParamStr = thePageParamStr; + this.theUserLogin = theUserLogin; + this.entries = entries; + } + + private static int obtainIntegerPageParam(final String thePageParamStr) throws InvalidInputException { + if (thePageParamStr != null) { + try { + return Integer.parseInt(thePageParamStr); + } + catch (NumberFormatException e) { + throw new InvalidInputException("Numéro de page incorrect", e); + } + } + else { + return 1; + } + } + + private static long pageCount(final long schedulingReportCount) { + return (schedulingReportCount - 1) / MAX_PAGE_SIZE + 1; // Integer division + } + + @Override + protected String makeTable(Session session) throws InvalidInputException { + // Reject request if not admin nor devmode + if (!DEV_MODE) { + boolean isAdmin = false; // by default + try { + UserData userData = ActiveDirectory.obtainUserData(theUserLogin); + isAdmin = userData.isAdmin(); + } + catch (InvalidInputException e) { + log.warn("No login received, unable to authorize admin access", e); + } + catch (NoConnectionToActiveDirectoryException e) { + log.warn("Could not connect to the AD to findAll users admin report ", e); + } + catch (InvalidActiveDirectorySearchException e) { + log.warn("Could not perform a search on the AD, to findAll users admin report", e); + } + if (!isAdmin) { + String aTechnicalErrorMessage = "User \"" + theUserLogin + "\" is not an administrator but requested the scheduling page"; + String userMessage = + "L'utilisateur \"" + theUserLogin + "\" n'est pas un administrateur et ne peut accéder à la page de planification"; + throw new NothingToBeShownException(aTechnicalErrorMessage, userMessage); + } + } + + // Prepare data + MngSchedulingReport mgnSchedulingReport = new MngSchedulingReport(); + final long schedulingReportCount; + if (reportCode.isPresent()) { + schedulingReportCount = mgnSchedulingReport.countSchedulingReportsByReportCode(session, reportCode.get()); + } + else { + schedulingReportCount = mgnSchedulingReport.countAllSchedulingReport(session); + } + int thePageParam = obtainIntegerPageParam(thePageParamStr); + long pageCount = pageCount(schedulingReportCount); + + JsTableCreator reportArray = new JsTableCreator("reportArray"); + for (SchedulingReportEntry entry : entries) { + String owner = entry.getUserResponsable(); + Long schedulingId = entry.getId(); + Optional nextFireTime = entry.getNextFireTime(); + SimpleDateFormat frenchDateFormat = new SimpleDateFormat(SIMPLE_FORMATTER, Locale.FRENCH); + String nextFireTimeStr = nextFireTime.isPresent() ? frenchDateFormat.format(nextFireTime.get()) : "Jamais"; + String lastUpdate = frenchDateFormat.format(entry.getLastUpdate()); + + // Make a line in the js table + Map schedulingReportsAsMap = new HashMap<>(); + schedulingReportsAsMap.put("report_code", StringEscapeUtils.escapeJavaScript(entry.getReportCode().getReportCode())); + schedulingReportsAsMap.put("planif_name", StringEscapeUtils.escapeJavaScript(entry.getPlanificationName())); + schedulingReportsAsMap.put("period", StringEscapeUtils.escapeJavaScript(entry.getPeriod())); + schedulingReportsAsMap.put("date_maj", StringEscapeUtils.escapeJavaScript(lastUpdate)); + schedulingReportsAsMap.put("user_responsable", StringEscapeUtils.escapeJavaScript(owner)); + schedulingReportsAsMap.put("date_start", StringEscapeUtils.escapeJavaScript(nextFireTimeStr)); + schedulingReportsAsMap.put("id", StringEscapeUtils.escapeJavaScript(schedulingId.toString())); + reportArray.addLine(schedulingReportsAsMap); + } + + // Additional tags preparation + paging = makePaging(thePageParam, pageCount); + + return reportArray.toString(); + } + + /* Paging */ + private String makePaging(final int thePageParam, final long theLastPage) { + /* Manage page browsing */ + StringBuilder thePaging = new StringBuilder(); + for (int i = 1; (i <= theLastPage) && (theLastPage > 1); i++) { + if (thePaging.length() > 0) { + thePaging.append(" - "); + } + else { + thePaging.append( + "
     
    Pages: "); + } + + if (i == thePageParam) { + thePaging.append(""); + showButton.append(""); + } + else { + showButton.append(""); + } + return showButton.toString(); + } + + /** + * Return js code for an array containing 'TOUS' as well as all report types authorized for planification. + */ + private String getDatasReportType(Session session) { + MngReportType theMngReportType = new MngReportType(); + Collection theReportType = theMngReportType.getAllSchedulableReportTypes(session); + JsArrayCreator selectArray = new JsArrayCreator("selectArray"); + selectArray.addEntry("TOUS"); + selectArray.addAll(theReportType); + return selectArray.toString(); + } + + private String isSchedulingAuthorized(Session session, final ReportEnum aReportCode) { + return new MngReportType().search(session, aReportCode).getReportAuthorized(); + } + + @Override + protected void addOptionalErrorTags() { + // Nothing to do for Running Reports + } + +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/formatting/ErrorPageTemplate.java b/kurt-web/src/main/java/com/capgemini/reports/formatting/ErrorPageTemplate.java new file mode 100644 index 0000000..6370727 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/formatting/ErrorPageTemplate.java @@ -0,0 +1,38 @@ +package com.capgemini.reports.formatting; + +import lombok.extern.slf4j.Slf4j; + +import com.capgemini.framework.common.FileTemplate; +import com.capgemini.framework.common.ResourceHelper; +import com.capgemini.reports.exceptions.FileLoadingException; + +/** Template loader for HTML content in order to display an error in JSP. **/ +@Slf4j +public class ErrorPageTemplate extends FileTemplate { + + /** + * Constructor. + * + * @param anErrorTitle Title of the error + * @param anErrorMessage Content message for the current error + */ + public ErrorPageTemplate(final String anErrorTitle, final String anErrorMessage) { + + super(); + + // Select the corresponding template content + try { + String theTemplateContent = ResourceHelper.getResourceContent("/html/error_jsp_page.html"); + setTemplateContent(theTemplateContent); + } + catch (FileLoadingException e) { + log.warn("Could not load the Page template", e); + } + + // Assign the expected template + + // Set tag values + setTagValue("ERROR_TITLE", anErrorTitle); + setTagValue("ERROR_MESSAGE", anErrorMessage); + } +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/formatting/JsArrayCreator.java b/kurt-web/src/main/java/com/capgemini/reports/formatting/JsArrayCreator.java new file mode 100644 index 0000000..fe074f5 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/formatting/JsArrayCreator.java @@ -0,0 +1,55 @@ +package com.capgemini.reports.formatting; + +import java.util.Collection; + +/** + * Creates a js array easily.
    + * Example output:
    + * var tab = new Array();\n
    + * tab[0] = 'toto';\n
    + * tab[1] = 'tata';\n + */ +public class JsArrayCreator { + + private final StringBuilder content = new StringBuilder(); + private final String tableName; + private int lineCount; + + /** + * Creates a js array wit hthe provided name. + * + * @param tableName the name of the table + */ + public JsArrayCreator(final String tableName) { + this.tableName = tableName; + this.content.append("\n").append("var ").append(tableName).append(" = new Array();\n"); + this.lineCount = 0; + } + + /** + * Add an entry to the table (will add a new line to the array). + * + * @param entry the content + */ + public void addEntry(final String entry) { + content.append(tableName).append('[').append(lineCount).append("] = '").append(entry).append("';\n"); + lineCount++; + } + + /** + * Adds the provided beans' content to a line in the table. + * + * @param someObjects a {@link Collection} of JAVA objects, on which {@link Object#toString() toString} will be invoked + */ + public void addAll(final Collection someObjects) { + for (Object aBean : someObjects) { + addEntry(aBean.toString()); + } + } + + @Override + public String toString() { + return content.toString(); + } + +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/formatting/JsTableCreator.java b/kurt-web/src/main/java/com/capgemini/reports/formatting/JsTableCreator.java new file mode 100644 index 0000000..e700fa2 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/formatting/JsTableCreator.java @@ -0,0 +1,104 @@ +package com.capgemini.reports.formatting; + +import com.capgemini.framework.common.BeanHelper; + +import java.util.Collection; +import java.util.Map; +import java.util.Map.Entry; + +/** + * Creates a Javascript table declaration, along with content. The table is 2D, with line numbers [0..n] as dimension 1, and whatever you want as dimension 2.
    + * Example output with table name 'tab', and two provided maps: + *
      + *
    • map1={key1=val1, key2=val2}
    • + *
    • map2={key1=val3, key2=val4} + *
    + * Expected output: + *

    + * var tab = new Array();
    + * tab[0] = new Array();
    + * tab[0]['key1'] = val1
    + * tab[0]['key2'] = val2
    + * tab[1] = new Array();
    + * tab[1]['key1'] = val3
    + * tab[1]['key2'] = val4
    + *

    + * Note: keys may not even be coherent between lines. + */ +public class JsTableCreator { + + final StringBuilder content = new StringBuilder(); + final String tableName; + int lineCount; + + /** + * Creates a js table, with the provided name. The table is 2D, with line numbers as dimension 1, and whatever you want as dimension 2. + * + * @param tableName the table name. + */ + public JsTableCreator(final String tableName) { + this.tableName = tableName; + this.content.append("\nvar ").append(tableName).append(" = new Array();\n"); + this.lineCount = 0; + } + + /** + * Adds a line showing for each map key, the associated value. + * + * @param lineContent the {@link Map} + */ + public void addLine(final Map lineContent) { + content.append('\n'); + String thisLine = "\t" + tableName + "[" + lineCount + "]"; + content.append(thisLine).append(" = new Array();\n"); + for (Entry entry : lineContent.entrySet()) { + content.append(thisLine).append("['").append(entry.getKey()).append("'] = '").append(entry.getValue()).append("';\n"); + } + lineCount++; + } + + /** + * Adds the provided bean's content to a line in the table. + * + * @param aJavaBean JAVA bean + */ + public void addBean(final Object aJavaBean) { + Map theAttMap = BeanHelper.toStringMap(aJavaBean); + addLine(theAttMap); + } + + /** + * Adds a line formed by the bean's contents, as well as the map's content. + * + * @param map the map + * @param aJavaBean the bean + */ + public void addLineAndBean(final Map map, final Object aJavaBean) { + content.append('\n'); + String thisLine = "\t" + tableName + "[" + lineCount + "]"; + content.append(thisLine).append(" = new Array();\n"); + Map lineContent = BeanHelper.toStringMap(aJavaBean); + lineContent.putAll(map); + for (Entry entry : lineContent.entrySet()) { + content.append(thisLine).append("['").append(entry.getKey()).append("'] = '").append(entry.getValue()).append("';\n"); + } + lineCount++; + } + + /** + * Adds the provided beans' content to a line in the table. + * + * @param someJavaBeans a {@link Collection} of JAVA beans + */ + public void addAllBean(final Collection someJavaBeans) { + for (Object aBean : someJavaBeans) { + addBean(aBean); + } + } + + @Override + public String toString() { + return content.toString(); + } + +} diff --git a/kurt-web/src/main/java/com/capgemini/reports/formatting/MyReports.java b/kurt-web/src/main/java/com/capgemini/reports/formatting/MyReports.java new file mode 100644 index 0000000..f862881 --- /dev/null +++ b/kurt-web/src/main/java/com/capgemini/reports/formatting/MyReports.java @@ -0,0 +1,133 @@ +package com.capgemini.reports.formatting; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.reports.database.manager.MngReport; +import com.capgemini.reports.database.manager.MngReport.RunningReportEntry; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.NothingToBeShownException; +import org.hibernate.Session; + +import java.util.List; + +/** This class can generate an html page showing every reports currently running or waiting to be executed that are owned by the logged-in user. */ +public class MyReports extends AbstractTableFormatter { + // User input + private final String thePageParamStr; + + // Last entries: to be put in additional Tags + private String paging; + private long reportCount; + private final String theUserLogin; + + private static final String BUTTON_END = ""; + + /** + * Create the some user's 'My Reports' page, passing the page number to be shown as (String) parameter. + * + * @param thePageParamStr the page number + * @param userLogin the login of the user who wants to know the status of his reports + */ + public MyReports(final String thePageParamStr, final String userLogin) { + super(); + this.thePageParamStr = thePageParamStr; + this.theUserLogin = userLogin == null ? "Invité(e)" : userLogin; + } + + @Override + protected String makeTable(Session session) throws InvalidInputException { + // Prepare data + MngReport theMngRep = new MngReport(); + this.reportCount = theMngRep.countUserReports(session, theUserLogin); + int thePageParam = obtainIntegerPageParam(thePageParamStr); + long pageCount = pageCount(reportCount); + + StringBuilder theTableJsCode = new StringBuilder("var reportArray = new Array();\n"); + + // Access the user reports for the current page + int theLineCount = 0; + List theUserReports = theMngRep.searchUserReports(session, theUserLogin, thePageParam); + if (theUserReports.isEmpty()) { + throw new NothingToBeShownException("No previous report executions", "Aucun rapport executé"); + } + + for (RunningReportEntry currentReport : theUserReports) { + String table = "\treportArray[" + theLineCount + "]"; + theTableJsCode.append(StringHelper.toJs(table, currentReport.getReport())); + theTableJsCode.append(table).append("['requestDate'] = '").append(currentReport.getRequestDate()).append("';"); + theLineCount++; + } + + // Additional tags preparation + paging = makePaging(thePageParam, pageCount); + + return theTableJsCode.toString(); + } + + protected static int obtainIntegerPageParam(final String thePageParamStr) throws InvalidInputException { + if (thePageParamStr != null) { + try { + return Integer.parseInt(thePageParamStr); + } catch (NumberFormatException e) { + throw new InvalidInputException("Numéro de page incorrect", e); + } + } + return 1; + } + + protected static long pageCount(final long theUserReportCount) { + int theMaxPageSize = SettingsHelper.getJspPaging(); + return (theUserReportCount - 1) / theMaxPageSize + 1; // Integer division + } + + protected static String makePaging(final int thePageParam, final long theLastPage) { + /* Manage page browsing */ + StringBuilder thePaging = new StringBuilder(); + if (theLastPage > 1) { + for (int i = 1; i <= theLastPage; i++) { + if (thePaging.length() > 0) { + thePaging.append(" - "); + } else { + thePaging.append("
     
    Pages: "); + } + + if (i != thePageParam) { + thePaging + .append(" + + + + + \ No newline at end of file diff --git a/kurt-web/src/main/resources/html/myReports/my_reports_success.html b/kurt-web/src/main/resources/html/myReports/my_reports_success.html new file mode 100644 index 0000000..98bfe41 --- /dev/null +++ b/kurt-web/src/main/resources/html/myReports/my_reports_success.html @@ -0,0 +1,46 @@ + + + + Mes rapports - [[USER_LOGIN]] + + + + + + + + +

    Mes rapports - [[USER_LOGIN]] : [[USER_REPORT_COUNT]] rapport(s)

    + + + Rafraichir +

    + +
    +
    + + + + + + + + + + +
    Code du rapportDate de demandeDate de lancementDate de finInfosStatut
    + + [[PAGING]] + +

    + + +
    + + + \ No newline at end of file diff --git a/kurt-web/src/main/resources/html/queueStatus/queue_status_failed.html b/kurt-web/src/main/resources/html/queueStatus/queue_status_failed.html new file mode 100644 index 0000000..0344a0f --- /dev/null +++ b/kurt-web/src/main/resources/html/queueStatus/queue_status_failed.html @@ -0,0 +1,31 @@ + + + + + + + + + Rapports en attente + + + + + + + + Rafraichir + +

    Rapports en attente

    + +
    +
    + [[ERROR_MESSAGE]] +

    + +
    + + + \ No newline at end of file diff --git a/kurt-web/src/main/resources/html/queueStatus/queue_status_success.html b/kurt-web/src/main/resources/html/queueStatus/queue_status_success.html new file mode 100644 index 0000000..935b626 --- /dev/null +++ b/kurt-web/src/main/resources/html/queueStatus/queue_status_success.html @@ -0,0 +1,36 @@ + + + + + + + + + Rapports en attente + + + + + + + + + Rafraichir + +

    Rapports en attente

    + +
    +
    + + +

    + +
    + + + \ No newline at end of file diff --git a/kurt-web/src/main/resources/html/runningReports/running_reports_failed.html b/kurt-web/src/main/resources/html/runningReports/running_reports_failed.html new file mode 100644 index 0000000..fb8d68c --- /dev/null +++ b/kurt-web/src/main/resources/html/runningReports/running_reports_failed.html @@ -0,0 +1,40 @@ + + + + Rapports en cours + + + + + + + + +

    Rapports en cours

    + +
    Auto-refresh:
    + +
    +
    + [[ERROR_MESSAGE]] +

    + +
    + + + + + \ No newline at end of file diff --git a/kurt-web/src/main/resources/html/runningReports/running_reports_success.html b/kurt-web/src/main/resources/html/runningReports/running_reports_success.html new file mode 100644 index 0000000..8c97146 --- /dev/null +++ b/kurt-web/src/main/resources/html/runningReports/running_reports_success.html @@ -0,0 +1,54 @@ + + + + Rapports en cours + + + + + + + + + + +

    Rapports en cours

    + +
    Auto-refresh:
    + +
    +
    + + + + + + + + + + + +
    Code du rapportPrioritéUtilisateurDate de demandeDate de lancementInfosStatut
    +
    + + + + + \ No newline at end of file diff --git a/kurt-web/src/main/resources/html/schedulingReports/schedulingReports_error.html b/kurt-web/src/main/resources/html/schedulingReports/schedulingReports_error.html new file mode 100644 index 0000000..d24ff7e --- /dev/null +++ b/kurt-web/src/main/resources/html/schedulingReports/schedulingReports_error.html @@ -0,0 +1,31 @@ + + + + + Planification des rapports + + + + + + + + +
    +

    Planification des rapports

    +
    +
    + + +
    +
    + [[ERROR_MESSAGE]] +

    + + + +
    +
    + + + \ No newline at end of file diff --git a/kurt-web/src/main/resources/html/schedulingReports/schedulingReports_success.html b/kurt-web/src/main/resources/html/schedulingReports/schedulingReports_success.html new file mode 100644 index 0000000..736b814 --- /dev/null +++ b/kurt-web/src/main/resources/html/schedulingReports/schedulingReports_success.html @@ -0,0 +1,132 @@ + + + + + Planification des rapports + + + + + + + + + + + + + + + + + + + +
    +

    Planification des rapports

    +
    +
    +
    + + + + + + + + + + + + + +
    +

    Filtrer les rapports

    +
    +

    Autoriser le lancement du rapport affiché en + immediat ou différé

    +
    + + + + +
    +
    + +
    +
    +
    + + + + + +
    +

    Rapport(s) planifié(s)

    +
    +
    + + + + + + + + + + + + + + + + +
    RapportNom planificationPériodeDernière modificationAdmin. responsableDate prochain lancementInfosModifierSupprimer
    +
    +
    +[[PAGING]] + + + [[DISPLAY_BUTTONS]] + +
    + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/WEB-INF/beans.xml b/kurt-web/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 0000000..3738086 --- /dev/null +++ b/kurt-web/src/main/webapp/WEB-INF/beans.xml @@ -0,0 +1,27 @@ + + + + + + diff --git a/kurt-web/src/main/webapp/WEB-INF/ejb-jar.xml b/kurt-web/src/main/webapp/WEB-INF/ejb-jar.xml new file mode 100644 index 0000000..ebea87c --- /dev/null +++ b/kurt-web/src/main/webapp/WEB-INF/ejb-jar.xml @@ -0,0 +1,26 @@ + + + Deployment descriptor + + + + jobConsumer + com.capgemini.reports.queuing.consumer.ReportConsumer + javax.jms.MessageListener + javax.jms.Queue + + + minSession + 15 + + + maxSession + 15 + + + + + + diff --git a/kurt-web/src/main/webapp/WEB-INF/web.xml b/kurt-web/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..59926b1 --- /dev/null +++ b/kurt-web/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,58 @@ + + +Servlet 3.0 Web Application + + + + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/css/dialog.css b/kurt-web/src/main/webapp/css/dialog.css new file mode 100644 index 0000000..acc9abb --- /dev/null +++ b/kurt-web/src/main/webapp/css/dialog.css @@ -0,0 +1,66 @@ +/* DIALOG PART */ +/***************/ +#dialog { + position: absolute; + width: 600px; + left: 50%; + top: 300px; + margin-left: -300px; + padding: 0px; + z-index: 200; + background: #fff; + filter: progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=135, Color='#333355'); + box-shadow: 1px 1px 5px #555; +} + +#dialog-header { + display: block; + height: 24px; + background: #fff url(../ihm/dialog.gif) repeat-x; + padding-right: -4px; +} + +#dialog-title { + float: left; + height: 24px; + font-weight: bold; + font-family: Verdana; + font-size: 12px; + padding: 4px; + color: #fff; + border-left: 1px solid #DCEFFC; +} + +#dialog-content { + padding: 6px; + color: #15142B; + font-size: 13px; + font-family: Verdana; + text-align: center; + font-weight: bold; +} + +#dialog-mask { + position: absolute; + top: 0; + left: 0; + min-height: 100%; + width: 100%; + background: #BBBBCC; + opacity: .5; + filter: alpha(opacity=50); + z-index: 100 +} + +#diag-btclose { + float: right; + margin-left: -2px; + width: 18px; + height: 18px; + margin-top: 4px; +} + +#diag-btcloseX { + margin-left: -4px; + font-weight: bold; +} \ No newline at end of file diff --git a/kurt-web/src/main/webapp/css/kurt-style-frame.css b/kurt-web/src/main/webapp/css/kurt-style-frame.css new file mode 100644 index 0000000..c168bf3 --- /dev/null +++ b/kurt-web/src/main/webapp/css/kurt-style-frame.css @@ -0,0 +1,177 @@ +body{ + background-color:#FFFFFF; + margin:10px; + font-family:Verdana; + font-size:11px; +} + +strong{ + color:#78718F; +} + +td{ + font-family:Verdana; + font-size:11px; +} + +td.tdFieldTitle{ + width:210px; + font-weight:bold; + color:#7D8490; + font-size:12px; + padding-left:20px; + text-align:left; +} +td.tdFieldTitleScheduling{ + font-weight:bold; + color:#7D8490; + font-size:12px; + padding-left:20px; + text-align:left; +} +td.tdFieldTitle_align_right{ + width:210px; + font-weight:bold; + color:#7D8490; + font-size:12px; + padding-left:20px; + text-align:right; +} +td.delimitedPart{ + font-size:14px; + color:#787599; +} + +td.required{ + color:#CC0000; +} + +th.reportTable +{ + height:18px; + font-size:12px; + color:#3E3E5C; + background-image:url('../ihm/left-bar-action-back-hover.png'); + background-repeat:repeat-x; + border-bottom:3px double #E1E8ED; +} + +th.reportTableScheduling +{ + height:12px; + font-size:12px; + color:#3E3E5C; + background-image:url('../ihm/left-bar-action-back-hover.png'); + background-repeat:repeat-x; + border-bottom:3px double #E1E8ED; +} + +td.reportTable +{ + border-bottom:1px solid #E1E8ED; + text-align:center; +} + +input{ + width:310px; + height:21px; + color:#3E567D; + font-family:Verdana; + font-size:11px; + padding:3px; + border:1px solid #CCC7D1; + background-image:url('../ihm/input-back.png'); + background-repeat:repeat-x; + border-radius:2px; +} + +input.radioInput{ + width:16px; + height:12px; + font-size:10px; + border:none; + background:none; +} + +input.checkform{ + width:16px; + height:12px; + font-size:10px; + border:none; + background:none; +} + +label { + margin-left: 85px; +} + + +select{ + size:1; + align:center; + width:316px; + height:26px; + color:#3E567D; + font-family:Verdana; + font-size:11px; + padding:3px; + border:1px solid #CCC7D1; + background-image:url('../ihm/input-back.png'); + background-repeat:repeat-x; + border-radius:2px; +} + +select.basicSelect{ + size:1; + width:100px; + height:26px; + color:#3E567D; + font-family:Verdana; + font-size:11px; + padding:3px; + border:1px solid #CCC7D1; + background-image:none; + background-repeat:none; + border-radius:2px; +} + +textarea { + width:310px; + height:60px; + color:#3E567D; + font-family:Verdana; + font-size:11px; + padding:3px; + border:1px solid #CCC7D1; + background-image:url('../ihm/input-back.png'); + background-repeat:repeat-x; + border-radius:2px; +} + +.formButton{ + height:22px; + margin-top:3px; + width:200px; + border:2px solid #DDDDFF; + cursor:hand; + font-weight:bold; + color:#3E6571; + background-image:url('../ihm/button-back.png'); + background-repeat:repeat-x; +} + +h1{ + font-family:Verdana; + font-size:15px; + font-weight:bold; + color:#411E56; + padding-bottom:6px; + border-bottom:double 3px #E7F0FD; +} +.title_H1_with_no_bottom_border{ + font-family:Verdana; + font-size:15px; + font-weight:bold; + color:#411E56; + padding-bottom:6px; +} diff --git a/kurt-web/src/main/webapp/css/kurt-style.css b/kurt-web/src/main/webapp/css/kurt-style.css new file mode 100644 index 0000000..d7c7a4a --- /dev/null +++ b/kurt-web/src/main/webapp/css/kurt-style.css @@ -0,0 +1,114 @@ +BODY{ + background-color:#FCFFFF; + background-image:url('../ihm/left-bar_260.png'); + background-repeat:repeat-y; + margin:0; + font-family:Verdana; + font-size:12px; +} + +#body_frame{ + background-image:url('../ihm/left-bar_160.png'); + background-repeat:repeat-y; + background-color:#FCFFFF; + margin:0; + font-family:Verdana; + font-size:12px; +} + +#titleImg{ + background-image:url('../ihm/generateur-rapports-teamcenter.png'); + position:absolute; + top:0px; + left:50%; + width:280px; + height:49px; +} + +#snecmaImg{ + background-image:url('../ihm/title.png'); + position:absolute; + top:0px; + left:0px; + width:523px; + height:50px; +} + +#topBarImg{ + background-image:url('../ihm/top-bar.png'); + height:50px; +} + +#actionLeftBar{ + border:1px solid #E8E8FF; + background-color:#FFFFFF; + position:absolute; + left:8px; + top:58px; + width:240px; + padding:2px; + border-radius:3px; +} + +#actionLeftBarTitle{ + background-image:url('../ihm/left-bar-top.png'); + height:18px; + font-weight:bold; + color:#FFFFFF; + padding:4px; +} + +.actionLeftBarActionBack{ + border:1px solid #EAFEFE; + background-image:url('../ihm/left-bar-action-back.png'); + margin-top:2px; + height:21px; + display:block; + text-decoration:none; + color:#8888BB; + font-weight:bold; + font-size:13px; +} + +.actionLeftBarActionBack:hover{ + color:#00AA00; + background-image:url('../ihm/left-bar-action-back-hover.png'); + border:1px solid #E0FFF0; +} + +#subFrame{ + border:1px solid #E8E8FF; + background-color:#FFFFFF; + left:250px; + top:58px; + padding:2px; + width:90%; + height:100%; + border-radius:15px; + box-shadow:1px 1px 4px 1px #FBFAFF; + margin-left:80px; +} + +#footer{ + position:absolute; + margin-top:-20px; + left:20%; + top:100%; + color:#AAAACC; + font-size:10px; +} +.table_period{ + border-spacing: 15px; +} +.width_60{ + width: 60px; +} +.width_140{ + width: 140px; +} +.width_160{ + width: 160px; +} +.width_180{ + width: 180px; +} \ No newline at end of file diff --git a/kurt-web/src/main/webapp/css/pikaday.css b/kurt-web/src/main/webapp/css/pikaday.css new file mode 100644 index 0000000..e855673 --- /dev/null +++ b/kurt-web/src/main/webapp/css/pikaday.css @@ -0,0 +1,194 @@ +@charset "UTF-8"; + +.pika-single { + z-index: 9999; + display: block; + position: relative; + color: #333; + background: #fff; + border: 1px solid #ccc; + border-bottom-color: #bbb; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +.pika-single:before, +.pika-single:after { + content: " "; + display: table; +} +.pika-single:after { clear: both } +.pika-single { *zoom: 1 } + +.pika-single.is-hidden { + display: none; +} + +.pika-single.is-bound { + position: absolute; + box-shadow: 0 5px 15px -5px rgba(0,0,0,.5); +} + +.pika-lendar { + float: left; + width: 240px; + margin: 8px; +} + +.pika-title { + position: relative; + text-align: center; +} + +.pika-label { + display: inline-block; + *display: inline; + position: relative; + z-index: 9999; + overflow: hidden; + margin: 0; + padding: 5px 3px; + font-size: 14px; + line-height: 20px; + font-weight: bold; + background-color: #fff; +} +.pika-title select { + cursor: pointer; + position: absolute; + z-index: 9998; + margin: 0; + left: 0; + top: 5px; + filter: alpha(opacity=0); + opacity: 0; +} + +.pika-prev, +.pika-next { + display: block; + cursor: pointer; + position: relative; + outline: none; + border: 0; + padding: 0; + width: 20px; + height: 30px; + /* hide text using text-indent trick, using width value (it's enough) */ + text-indent: 20px; + white-space: nowrap; + overflow: hidden; + background-color: transparent; + background-position: center center; + background-repeat: no-repeat; + background-size: 75% 75%; + opacity: .5; + *position: absolute; + *top: 0; +} + +.pika-prev:hover, +.pika-next:hover { + opacity: 1; +} + +.pika-prev, +.is-rtl .pika-next { + float: left; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAUklEQVR42u3VMQoAIBADQf8Pgj+OD9hG2CtONJB2ymQkKe0HbwAP0xucDiQWARITIDEBEnMgMQ8S8+AqBIl6kKgHiXqQqAeJepBo/z38J/U0uAHlaBkBl9I4GwAAAABJRU5ErkJggg=='); + *left: 0; +} + +.pika-next, +.is-rtl .pika-prev { + float: right; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAU0lEQVR42u3VOwoAMAgE0dwfAnNjU26bYkBCFGwfiL9VVWoO+BJ4Gf3gtsEKKoFBNTCoCAYVwaAiGNQGMUHMkjGbgjk2mIONuXo0nC8XnCf1JXgArVIZAQh5TKYAAAAASUVORK5CYII='); + *right: 0; +} + +.pika-prev.is-disabled, +.pika-next.is-disabled { + cursor: default; + opacity: .2; +} + +.pika-select { + display: inline-block; + *display: inline; +} + +.pika-table { + width: 100%; + border-collapse: collapse; + border-spacing: 0; + border: 0; +} + +.pika-table th, +.pika-table td { + width: 14.285714285714286%; + padding: 0; +} + +.pika-table th { + color: #999; + font-size: 12px; + line-height: 25px; + font-weight: bold; + text-align: center; +} + +.pika-button { + cursor: pointer; + display: block; + box-sizing: border-box; + -moz-box-sizing: border-box; + outline: none; + border: 0; + margin: 0; + width: 100%; + padding: 5px; + color: #666; + font-size: 12px; + line-height: 15px; + text-align: right; + background: #f5f5f5; +} + +.pika-week { + font-size: 11px; + color: #999; +} + +.is-today .pika-button { + color: #33aaff; + font-weight: bold; +} + +.is-selected .pika-button { + color: #fff; + font-weight: bold; + background: #33aaff; + box-shadow: inset 0 1px 3px #178fe5; + border-radius: 3px; +} + +.is-disabled .pika-button { + pointer-events: none; + cursor: default; + color: #999; + opacity: .3; +} + +.pika-button:hover { + color: #fff !important; + background: #ff8000 !important; + box-shadow: none !important; + border-radius: 3px !important; +} + +/* styling for abbr */ +.pika-table abbr { + border-bottom: none; + cursor: help; +} + diff --git a/kurt-web/src/main/webapp/css/scheduling.css b/kurt-web/src/main/webapp/css/scheduling.css new file mode 100644 index 0000000..3670f32 --- /dev/null +++ b/kurt-web/src/main/webapp/css/scheduling.css @@ -0,0 +1,29 @@ + + +.title_planification{ + border-bottom :2px solid #9ec8de; + margin-bottom : 14px; + margin-top:40px; + width:800px; + font-weight:bold; + color:#7D8490; + font-size:12px; + padding-left:20px; + text-align:left; +} +.subTitle_planification{ + font-weight:bold; + color:#7D8490; + font-size:12px; + text-align:left; +} +.subTitle_sub_period{ + font-weight:bold; + color:#7D8490; + font-size:12px; + text-align:left; +} +.subTitle_planification_Required { + color: #CC0000; + font-weight: bold; +} \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/all_scheduling_reports.jsp b/kurt-web/src/main/webapp/frames/all_scheduling_reports.jsp new file mode 100644 index 0000000..3bad050 --- /dev/null +++ b/kurt-web/src/main/webapp/frames/all_scheduling_reports.jsp @@ -0,0 +1,57 @@ +<%@page import="com.capgemini.reports.ReportEnum"%> +<%@page import="com.capgemini.reports.common.scheduling.controller.SchedulingReaderServlet.SchedulingReportEntry"%> +<%@page import="com.capgemini.reports.formatting.AllSchedulingReports" %> +<%@page import="java.util.List" %> +<%@page import="java.util.Set" %> +<%! final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("com.capgemini.reports.all_scheduling_reports.jsp"); %> + +<% +response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1 +response.setHeader("Pragma", "no-cache"); // HTTP 1.0 +response.setDateHeader("Expires", 0); // Proxies +%> + + +<% + String reportCode = request.getParameter("reportCode"); + List allReports = ReportEnum.getListReportCode(); + ReportEnum reportEnum = allReports.contains(reportCode) ? ReportEnum.fromCode(reportCode) : null; + String pageNum = request.getParameter("page"); + String userLogin = request.getRemoteUser(); + Set entries = (Set) request.getAttribute("schedulings"); + + log.trace("reportCode = " + reportCode); + log.trace("reportEnum = " + (reportEnum==null ? "(null)" : reportEnum.toString())); + log.trace("page = " + pageNum); + log.trace("userLogin = " + userLogin); + log.trace("entries = " + entries.toString()); +%> +<%= new AllSchedulingReports(reportEnum, pageNum, userLogin, entries).makeJsContent() %> + diff --git a/kurt-web/src/main/webapp/frames/criteria.jsp b/kurt-web/src/main/webapp/frames/criteria.jsp new file mode 100644 index 0000000..c93ec4f --- /dev/null +++ b/kurt-web/src/main/webapp/frames/criteria.jsp @@ -0,0 +1,65 @@ +<%@page import="com.capgemini.framework.common.StringHelper" %> +<%@page import="com.capgemini.reports.database.HibernateUtil"%> +<%@page import="com.capgemini.reports.database.manager.MngCriteriaVal"%> +<%@page import="com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue" %> +<%@page import="java.util.List"%> +<%! final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("com.capgemini.criteria.jsp"); %> +<% + /* This part requests in the DB all the criteria relative to a report, whose uid is pass as URL parameter. */ + String theJsCriteriaArray = StringHelper.EMPTY; + String theErrorMessage = StringHelper.EMPTY; + String theReportUid = request.getParameter("reportUid"); + + try { + StringBuilder theJsCode = new StringBuilder(); + int theLineCount = 0; + List theReportCriteriaList = new MngCriteriaVal().searchCriteriasByReportUID(theReportUid); + for (CriteriaValue currentCriteria: theReportCriteriaList) { + if (currentCriteria != null){ + String theName = StringHelper.toHtml(currentCriteria.getName()); + String theValue = StringHelper.toHtml(currentCriteria.getValue()); + theJsCode.append("\tcriteriaArray[").append(theLineCount).append("] = new Array();\n"); + theJsCode.append("\tcriteriaArray[").append(theLineCount).append("]['name'] = '").append(theName).append("';\n"); + theJsCode.append("\tcriteriaArray[").append(theLineCount).append("]['value'] = '").append(theValue == null || theValue.isEmpty() || "null".equals(theValue) ? "-" : theValue).append("';\n"); + theLineCount++; + } + } + theJsCriteriaArray = theJsCode.toString(); + } + catch (Exception e) { + log.error("Impossible d'afficher les crit�res: " + e.getMessage()); + } +%> + + + + + + + + + Critères du rapport + + + + + +
    +
    + + + + + + +
    NomValeur
    + <%= theErrorMessage %> +
    +
    + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/mem_monitoring.jsp b/kurt-web/src/main/webapp/frames/mem_monitoring.jsp new file mode 100644 index 0000000..3248169 --- /dev/null +++ b/kurt-web/src/main/webapp/frames/mem_monitoring.jsp @@ -0,0 +1,79 @@ +<% + +response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1 +response.setHeader("Pragma", "no-cache"); // HTTP 1.0 +response.setDateHeader("Expires", 0); // Proxies +%> +<%@page import="com.capgemini.framework.common.MemoryHelper" %> +<%@page import="com.capgemini.framework.common.SettingsHelper" %> +<%@page import="com.capgemini.reports.database.javabean.DbMemMonitor"%> +<%@page import="com.capgemini.reports.database.manager.MngMemMonitor"%> +<%@page import="java.util.List" %> +<% + + /* Retreive parameter */ + String theMonitoring = MemoryHelper.monitorMemory(); + Integer theMsFrequency = SettingsHelper.getInteger("MngMemMonitor.frequency") * 1000; + + /* Browse last memory traces */ + Double theMaxMemory = 0D; + int theIndexCount = 0; + StringBuilder theJsArray = new StringBuilder(); + MngMemMonitor theMemMonitor = new MngMemMonitor(); + List theMonitorList = theMemMonitor.searchMemMonitor(); + for (DbMemMonitor currentMonitor : theMonitorList){ + + /* Store max memory estimation */ + if (currentMonitor.getMaxMemory() > theMaxMemory){ + theMaxMemory = currentMonitor.getMaxMemory(); + } + + theJsArray.append("\t\tmemArray[").append(theIndexCount).append("] = new Array();\n"); + theJsArray.append("\t\tmemArray[").append(theIndexCount).append("]['freeMem'] = ").append(currentMonitor.getUsedMemory()).append(";\n"); + theJsArray.append("\t\tmemArray[").append(theIndexCount).append("]['monitorDate'] = '").append(currentMonitor.getMonitorDate()).append("';\n"); + theIndexCount ++; + } + +%> + + + Suivi mémoire + + + + + +

    Suivi mémoire

    + +
    +
    + +
    px;border-bottom:2px solid #DDDDFF;border-left:1px solid #EEEEFF;"> + +
    + +
    + <%= theMonitoring %> +
    + +
    + + + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/my_reports.jsp b/kurt-web/src/main/webapp/frames/my_reports.jsp new file mode 100644 index 0000000..96ce462 --- /dev/null +++ b/kurt-web/src/main/webapp/frames/my_reports.jsp @@ -0,0 +1,9 @@ +<%@page import="com.capgemini.reports.formatting.MyReports" %> + +<% + response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1 + response.setHeader("Pragma", "no-cache"); // HTTP 1.0 + response.setDateHeader("Expires", 0); // Proxies +%> + +<%= new MyReports(request.getParameter("page"), request.getRemoteUser()).makeJsContent() %> \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/queue.jsp b/kurt-web/src/main/webapp/frames/queue.jsp new file mode 100644 index 0000000..49fc12c --- /dev/null +++ b/kurt-web/src/main/webapp/frames/queue.jsp @@ -0,0 +1,26 @@ +<%@page import="com.capgemini.reports.database.manager.MngReport.RunningReportEntry"%> +<%@page import="com.capgemini.reports.quartz.SchedulerServer.JobExecution"%> +<%@page import="com.capgemini.reports.formatting.QueueStatus"%> +<%@page import="java.util.List"%> + +<% +response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1 +response.setHeader("Pragma", "no-cache"); // HTTP 1.0 +response.setDateHeader("Expires", 0); // Proxies +%> + + + +<% + List theWaitingReports = (List) request.getAttribute("waitingReports"); + List tonightJobs = (List) request.getAttribute("quartzJobList"); +%> +<%= new QueueStatus(theWaitingReports, tonightJobs).makeJsContent() %> \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/report_not_authorized_message.jsp b/kurt-web/src/main/webapp/frames/report_not_authorized_message.jsp new file mode 100644 index 0000000..638b03a --- /dev/null +++ b/kurt-web/src/main/webapp/frames/report_not_authorized_message.jsp @@ -0,0 +1 @@ +

    Ce rapport n'est pas disponible, car il est planifié...

    \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/running_reports.jsp b/kurt-web/src/main/webapp/frames/running_reports.jsp new file mode 100644 index 0000000..85edac5 --- /dev/null +++ b/kurt-web/src/main/webapp/frames/running_reports.jsp @@ -0,0 +1,9 @@ +<%@page import="com.capgemini.reports.formatting.RunningReports"%> + +<% +response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1 +response.setHeader("Pragma", "no-cache"); // HTTP 1.0 +response.setDateHeader("Expires", 0); // Proxies +%> + +<%= new RunningReports().makeJsContent() %> \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/scheduling_criteria.jsp b/kurt-web/src/main/webapp/frames/scheduling_criteria.jsp new file mode 100644 index 0000000..3b0e2a9 --- /dev/null +++ b/kurt-web/src/main/webapp/frames/scheduling_criteria.jsp @@ -0,0 +1,67 @@ +<%@page import="com.capgemini.framework.common.StringHelper" %> +<%@page import="com.capgemini.reports.database.HibernateUtil" %> +<%@page import="com.capgemini.reports.database.manager.MngSchedulingCriteriaVal" %> +<%@page import="java.util.List" %> +<%! final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("com.capgemini.scheduling_criteria.jsp"); %> +<% + /* This part requests in the DB all the criteria relative to a report, whose uid is pass as URL parameter. */ + String theJsCriteriaArray = StringHelper.EMPTY; + String theErrorMessage = StringHelper.EMPTY; + String theReportId = request.getParameter("reportId"); + + try { + StringBuilder theJsCode = new StringBuilder(); + int theLineCount = 0; + List theReportCriteriaList = new MngSchedulingCriteriaVal().searchFunctional(Long.valueOf(theReportId)); + + for (MngSchedulingCriteriaVal.SchedulingCriteriaValue currentCriteria : theReportCriteriaList) { + if (currentCriteria != null) { + String theName = StringHelper.toHtml(currentCriteria.getName()); + String theValue = StringHelper.toHtml(currentCriteria.getValue()); + theJsCode.append("\tcriteriaArray[").append(theLineCount).append("] = new Array();\n"); + theJsCode.append("\tcriteriaArray[").append(theLineCount).append("]['name'] = '").append(theName).append("';\n"); + theJsCode.append("\tcriteriaArray[").append(theLineCount).append("]['value'] = '").append(theValue == null || theValue.isEmpty() || "null".equals(theValue) ? "-" : theValue).append("';\n"); + theLineCount++; + } + } + + theJsCriteriaArray = theJsCode.toString(); + } + catch (Exception e) { + log.error("Impossible d'afficher les crit�res: " + e.getMessage()); + } +%> + + + + + + + + + Critères du rapport et de la planification + + + + + + +
    +
    + + + + + + +
    NomValeur
    + <%= theErrorMessage %> +
    +
    + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/scheduling_delete.jsp b/kurt-web/src/main/webapp/frames/scheduling_delete.jsp new file mode 100644 index 0000000..2d6983d --- /dev/null +++ b/kurt-web/src/main/webapp/frames/scheduling_delete.jsp @@ -0,0 +1,68 @@ +<%@page import="com.capgemini.reports.database.manager.MngSchedulingReport"%> +<%@page import="com.capgemini.reports.database.manager.MngSchedulingCriteriaVal"%> +<%@page import="com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue"%> +<%@page import="com.capgemini.reports.database.HibernateUtil"%> +<%@page import="com.capgemini.reports.database.javabean.DbCriteriaVal"%> +<%@page import="com.capgemini.reports.database.manager.MngCriteriaVal"%> +<%@page import="com.capgemini.framework.common.StringHelper"%> +<%@page import="com.capgemini.framework.common.SettingsHelper"%> +<%@page import="com.capgemini.framework.common.BeanHelper"%> +<%@page import="com.capgemini.framework.common.StringHelper"%> +<%@page import="com.capgemini.reports.database.manager.MngReport"%> +<%@page import="java.util.List"%> +<%! org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("com.capgemini.report.scheduling_delete.jsp"); %> +<% + // This is a pop-up content to check if the user REALLY wants to destroy a scheduling + /* This part requests in the DB all the criteria relative to a report, whose uid is pass as URL parameter. */ + String theJsCriteriaArray = StringHelper.EMPTY; + String theErrorMessage = StringHelper.EMPTY; + String theReportId = request.getParameter("reportId"); + String curReportNumber = request.getParameter("activeReportCode"); + String planifName = request.getParameter("planif_name"); + +%> + + + + + + + + + + + + Suppression + + + + + + + + +
    +
    + + +
    + Confirmez vous la suppression de la planification [ <%=planifName%> ] ? +
    + +
    + + + + + +
    + +
    +
    + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/scheduling_new.jsp b/kurt-web/src/main/webapp/frames/scheduling_new.jsp new file mode 100644 index 0000000..270ce12 --- /dev/null +++ b/kurt-web/src/main/webapp/frames/scheduling_new.jsp @@ -0,0 +1,122 @@ +<%@page import="com.capgemini.reports.ReportEnum"%> +<%@page import="java.util.Arrays"%> +<%@page import="java.util.Collections"%> +<%@page import="java.util.ArrayList"%> +<%@page import="java.util.List"%> +<%@page import="java.util.Map"%> +<%@page import="java.util.HashMap"%> +<%@page import="com.capgemini.framework.common.StringHelper"%> +<%@page import="com.capgemini.framework.common.SettingsHelper"%> +<%@page import="com.capgemini.reports.database.manager.MngSchedulingReport"%> +<%@page import="com.capgemini.reports.database.javabean.enumeration.SchedulingEnum"%> +<%@page import="com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum"%> +<%@page import="com.capgemini.reports.database.manager.MngSchedulingCriteriaVal"%> +<%@page import="com.capgemini.reports.common.scheduling.view.NewSchedulingFormatter"%> +<%@page import="com.capgemini.reports.common.scheduling.view.UpdateSchedulingFormatter"%> + +<% + response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1 + response.setHeader("Pragma", "no-cache"); // HTTP 1.0 + response.setDateHeader("Expires", 0); // Proxies + + + boolean isDevMode = SettingsHelper.isDevMode(); + + String selectedFilter = request.getParameter("activeSchedulingList"); + String curReportNumber = selectedFilter.equals("TOUS") ? selectedFilter : "R" + selectedFilter; + + ReportEnum reportEntryEnum = ReportEnum.fromCode(curReportNumber); + String reportTitleCanonicalName = curReportNumber.concat(" - ").concat( reportEntryEnum.getReportTitle() ); + + String jspURL = "template_r" + selectedFilter + ".jsp"; + String reportCode = "R" + selectedFilter ; +%> + + + + Planification - + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Planification <%=reportTitleCanonicalName%> (Création)

    + +
    +
    + +
    +
    +
    +

    Définition du Rapport

    +
    +
    + + <%-- --%> + + + + + + + + +
    +
    +
    + +
    +
    + + +
    +

    Critères de Planification du Rapport

    +
    + +
    + + <%=new NewSchedulingFormatter().showNewReportSchedulingPage()%> + + +
    +
    + + +
    + + +
    + + +
    +
    + + diff --git a/kurt-web/src/main/webapp/frames/scheduling_update.jsp b/kurt-web/src/main/webapp/frames/scheduling_update.jsp new file mode 100644 index 0000000..186c3a8 --- /dev/null +++ b/kurt-web/src/main/webapp/frames/scheduling_update.jsp @@ -0,0 +1,127 @@ +<%@page import="com.capgemini.framework.common.SettingsHelper" %> +<%@page import="com.capgemini.reports.ReportEnum"%> +<%@page import="com.capgemini.reports.common.scheduling.view.UpdateSchedulingFormatter"%> +<%! final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("com.capgemini.report.scheduling_update.jsp"); %> +<% + //// + response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1 + response.setHeader("Pragma", "no-cache"); // HTTP 1.0 + response.setDateHeader("Expires", 0); // Proxies + + + boolean isDevMode = SettingsHelper.isDevMode(); + // Useless? + String tempCurrentReportNumber = request.getParameter("activeSchedulingList"); + + String idStr = request.getParameter("id"); + Long idLong = Long.valueOf(idStr); + String curReportCode = request.getParameter("reportCode"); + String curReportNumber = curReportCode.replace("R", ""); + + ReportEnum reportEntryEnum = ReportEnum.fromCode(curReportCode); + String reportTitleCanonicalName = curReportCode.concat(" - ").concat( reportEntryEnum.getReportTitle() ); + + String jspReportToCall = "template_r" + curReportNumber + ".jsp"; + + log.trace("devMode = " + isDevMode); + log.trace("tempRepNumber = " + tempCurrentReportNumber); + log.trace("idStr = " + idStr); + log.trace("curReportCode = " + curReportCode); + log.trace("curReportNumber = " + curReportNumber); + log.trace("jspReportToCall = " + jspReportToCall); + log.trace("idLong = " + idLong); + + String theSchedulingName = ""; + String thePeriod = ""; + String theDaily = ""; + String theWeekly = ""; + String theMonthly = ""; + String theWeekEnd = ""; + String theDate = ""; + String theMonthlyValue = ""; +%> + + + + +Planification - + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Planification <%=reportTitleCanonicalName%> (Modification)

    + +
    +
    + +
    +
    + +
    +

    Définition du Rapport

    +
    + +
    +
    + + + + + + +
    +
    +
    + +
    + + +
    + <%--

    Planification du Rapport R<%=curReportCode%>

    --%> +

    Critères de la planification

    +
    + +
    + + <%=new UpdateSchedulingFormatter(idLong).showReportUpdatePage()%> + +
    +
    + +
    + + +
    + + +
    +
    + + diff --git a/kurt-web/src/main/webapp/frames/statistics_per_report.jsp b/kurt-web/src/main/webapp/frames/statistics_per_report.jsp new file mode 100644 index 0000000..043a8ce --- /dev/null +++ b/kurt-web/src/main/webapp/frames/statistics_per_report.jsp @@ -0,0 +1,104 @@ +<%@page import="com.capgemini.framework.common.DateHelper" %> +<%@page import="com.capgemini.reports.ReportEnum" %> +<%@page import="com.capgemini.reports.database.stats.GenJspStats" %> +<% + /* Retreive parameter */ + String theStartPeriod = DateHelper.getDate(); + String theEndPeriod = DateHelper.getDate(); + if ((request.getParameter("startPeriod") != null) && (request.getParameter("endPeriod") != null)) { + theStartPeriod = String.valueOf(request.getParameter("startPeriod")); + theEndPeriod = String.valueOf(request.getParameter("endPeriod")); + } + String theJsStatArray1 = GenJspStats.generateTimingsTableAsJS(theStartPeriod, theEndPeriod); + int nbReports = ReportEnum.values().length; +%> + + + + + + + + + Statistiques par rapport + + + + + + + + + + + + +
    +

    Statistiques par rapport

    + +
    +
    + + + + + + + + + +
    +
    +
    +
    +
    +
    / + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    + + + + + + + + + + + +
    Code du rapportNombre d'ex�cutionsErreurs de saisieErreurs techniquesDur�e minimaleDur�e moyenneDur�e maximale
    + +

    + + +

    + + +
    +
    + + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/statistics_per_user.jsp b/kurt-web/src/main/webapp/frames/statistics_per_user.jsp new file mode 100644 index 0000000..1c9a9e8 --- /dev/null +++ b/kurt-web/src/main/webapp/frames/statistics_per_user.jsp @@ -0,0 +1,100 @@ +<%@page import="com.capgemini.framework.common.DateHelper" %> +<%@page import="com.capgemini.reports.ReportEnum" %> +<%@page import="com.capgemini.reports.database.stats.GenJspStats" %> +<% + /* Retreive parameter */ + String theStartPeriod = DateHelper.getDate(); + String theEndPeriod = DateHelper.getDate(); + if ((request.getParameter("startPeriod") != null) && (request.getParameter("endPeriod") != null)) { + theStartPeriod = String.valueOf(request.getParameter("startPeriod")); + theEndPeriod = String.valueOf(request.getParameter("endPeriod")); + } + String theJsStatArray2 = GenJspStats.generateLaunchCountTableAsJS(theStartPeriod, theEndPeriod); + int nbReports = ReportEnum.values().length; +%> + + + + + + + + + Statistiques par utilisateur + + + + + + + + + + + + +
    +

    Statistiques par utilisateur

    + +
    +
    + + + + + + + + + +
    +
    +
    +
    +
    +
    / + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    + + + + <% for (ReportEnum value : ReportEnum.values()) { %> + + <% } %> + + + + +
    Utilisateur<%=value.getReportCode() %> + Global
    +



    + + +
    +
    + + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/submitNewReport.jsp b/kurt-web/src/main/webapp/frames/submitNewReport.jsp new file mode 100644 index 0000000..cb9105d --- /dev/null +++ b/kurt-web/src/main/webapp/frames/submitNewReport.jsp @@ -0,0 +1,101 @@ +<%@page import="com.capgemini.framework.common.SettingsHelper" %> +<%@page import="com.capgemini.reports.ReportEnum" %> +<%@page import="com.capgemini.reports.database.manager.MngReportType" %> +<%@ page import="org.hibernate.SessionFactory" %> +<%@ page import="com.capgemini.reports.database.HibernateUtil" %> +<%@ page import="org.hibernate.Session" %> +<%! final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("com.capgemini.reports.submitNewReport.jsp"); %> +<% + + response.setHeader("Pragma", "no-cache"); + response.setHeader("Cache-Control", "no-cache"); + response.setDateHeader("Expires", 0); + + String reportNameRaw = request.getParameter("rd_id"); // May contain comments appended by '_' like : 'REPORT_R19_Document' + if (reportNameRaw == null) { + reportNameRaw = "REPORT_R01"; + } + String reportCode = reportNameRaw.split("_")[1]; // Report Code like 'R19' + ReportEnum reportEnum = ReportEnum.fromCode(reportCode); + String theReportTitle = reportEnum.getReportTitle(); + boolean authorized = new MngReportType().isAuthorized(reportEnum); + boolean isDevMode = SettingsHelper.isDevMode(); + + String targetTemplate = "template_" + reportCode.toLowerCase() + ".jsp"; + + log.trace("reportCode : " + reportCode); + log.trace("reportEnum : " + reportEnum.toString()); + log.trace("TargetTemplate: " + targetTemplate); + log.trace("isDevMode: " + isDevMode); +%> + + + + + + + + + + + + + + <%if (isDevMode) {%> + + <%}%> + + <%= theReportTitle %> + + + + + + + + + + + + +

    <%=reportCode%> - <%= theReportTitle %> +

    +
    +
    +
    +
    + +<%if (!authorized) {%> +
    +

    Ce rapport n'est pas autorisé

    +
    +<% } %> + +
    +
    +
    + <%-- Imports the report's template JSP in a form --%> + <%-- Activates content fields in the report template IF it is authorized for immediate execution --%> + + + + +
    +
    +
    +
    +
    + <% if (authorized) { %> + + <% } %> + +
    +
    +
    +
    + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/template_r01.jsp b/kurt-web/src/main/webapp/frames/template_r01.jsp new file mode 100644 index 0000000..9e7d782 --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r01.jsp @@ -0,0 +1,164 @@ +<%@page import="com.capgemini.framework.common.SettingsHelper"%> +<%@page import="com.capgemini.framework.common.StringHelper" %> +<%@page import="com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum"%> +<%@page import="com.capgemini.reports.database.manager.MngSchedulingCriteriaVal"%> +<%@page import="java.util.Map"%> +<%! final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("com.capgemini.report.template_r01.jsp"); %> +<% + /* + * Available request parameters: + * "isUpdateReport" (boolean) Is this a submission of a NEW report or an UPDATE? + * "idReport" (long) Report Id in case of an UPDATE request + */ + boolean isDevMode = SettingsHelper.isDevMode(); + boolean isUpdate = Boolean.valueOf(request.getParameter("isUpdateReport")); + Long reportID = isUpdate ? Long.valueOf(request.getParameter("idReport")) : new Long(-1); + + log.info("**********************"); + log.info("isDevMode = " + isDevMode); + log.info("isUpdate = " + isUpdate); + log.info("reportID = " + reportID); + + // Default values in each field. May contain nothing / existing values / development values + String theDefaultGen = ""; + String theDefaultGenMont = ""; + String theDefaultProduct = ""; + String theDefaultUnit = ""; + String theDefaultDate = ""; + String theMonoMulti = "MONO" ; + String isSuperModelBOM = Boolean.FALSE.toString(); + + if (isDevMode){ // Devmode default values + theDefaultGen = ""; + theDefaultGenMont = "24E"; + theDefaultProduct = "30E0"; + theDefaultUnit = "20"; + theDefaultDate = "01-01-2015"; + } + + if( isUpdate){ // Existing values to reload from DB + Map theFunctionalCriteriaValues = new MngSchedulingCriteriaVal().getFunctionalMap(reportID); + + theDefaultGen = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.GENERIC) ); + theDefaultGenMont = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.GENERIC_ASSEMB) ); + theDefaultProduct = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.PRODUCT) ); + theDefaultUnit = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.UNIT) ); + theDefaultDate = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.EFFECTIVITY_DATE) ); + theMonoMulti = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.MONO_MULTI) ); + isSuperModelBOM = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.SUPERMODEL) ); + log.info("theDefaultGen = " + theDefaultGen); + log.info("theDefaultGenMont = " + theDefaultGenMont); + log.info("theDefaultProduct = " + theDefaultProduct); + log.info("theDefaultUnit = " + theDefaultUnit); + log.info("theDefaultDate = " + theDefaultDate); + log.info("theMonoMulti = " + theMonoMulti); + } +%> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Niveau : +
    + /> Mono + /> Multi + + /> +
    +
    +
    +
    Générique "Vue Technique" : + +
    Générique "Vue montage" : + +
    Produit* : + +
    Unit* : + +
    Date d'effectivité : + + +
    +
    +
    +
    +
    +
    + +
    + + + diff --git a/kurt-web/src/main/webapp/frames/template_r03.jsp b/kurt-web/src/main/webapp/frames/template_r03.jsp new file mode 100644 index 0000000..900462b --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r03.jsp @@ -0,0 +1,82 @@ +<%@page import="com.capgemini.framework.common.SettingsHelper"%> + + + + + + + + + + + + + + + + + + +
    N° d'article* :
    Révision* : + + +
    +
    + +
    + + + + + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/template_r07.jsp b/kurt-web/src/main/webapp/frames/template_r07.jsp new file mode 100644 index 0000000..5485b64 --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r07.jsp @@ -0,0 +1,172 @@ +<%@page import="com.capgemini.framework.common.SettingsHelper"%> +<%@page import="com.capgemini.framework.common.StringHelper" %> +<%@page import="com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum" %> +<%@page import="com.capgemini.reports.database.manager.MngSchedulingCriteriaVal"%> +<%@page import="java.util.Map"%> +<% + /* + * Available request parameters: + * "isUpdateReport" (boolean) Is this a submission of a NEW report or an UPDATE? + * "idReport" (long) Report Id in case of an UPDATE request + */ + boolean isDevMode = SettingsHelper.isDevMode(); + boolean isUpdate = Boolean.valueOf(request.getParameter("isUpdateReport")); + Long reportID = isUpdate ? Long.valueOf(request.getParameter("idReport")) : new Long(-1); + + /* Conf 1*/ + String theDefaultGen1 = ""; + String theDefaultGenMont1 = ""; + String theDefaultProduct1 = ""; + String theDefaultUnit1 = ""; + + /* Conf 2*/ + String theDefaultGen2 = ""; + String theDefaultGenMont2 = ""; + String theDefaultProduct2 = ""; + String theDefaultUnit2 = ""; + + if (isDevMode){ // Default values for development environment only + theDefaultGen1 = ""; + theDefaultGenMont1 = ""; + theDefaultProduct1 = "ZZ07"; + theDefaultUnit1 = "10"; + theDefaultGen2 = ""; + theDefaultGenMont2 = ""; + theDefaultProduct2 = "ZZ07"; + theDefaultUnit2 = "20"; + } + + if( isUpdate ){ // Recall existing data from DB + Map theFunctionalCriteriaValues = new MngSchedulingCriteriaVal().getFunctionalMap(reportID); + + theDefaultGen1 = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.GENERIC)); + theDefaultGenMont1 = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.GENERIC_ASSEMB)); + theDefaultProduct1 = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.PRODUCT)); + theDefaultUnit1 = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.UNIT_CONFIGURATION_1)); + theDefaultUnit2 = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.UNIT_CONFIGURATION_2)); + theDefaultGen2 = theDefaultGen1; // Same both conf + theDefaultGenMont2 = theDefaultGenMont1; // Same both conf + theDefaultProduct2 = theDefaultProduct1; // Same both conf + } +%> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Informations de la configuration 1 :Informations de la configuration 2 :
    +
    +
    Générique "Vue Technique" 1 :Générique "Vue Technique" 2 (non modifiable) :
    Générique "Vue Montage" 1 :Générique "Vue Montage" 2 (non modifiable) :
    Produit 1* :Produit 2 (non modifiable) :
    Unit 1* :Unit 2* :
    +
    +
    +
    +
    + +
    + + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/template_r10.jsp b/kurt-web/src/main/webapp/frames/template_r10.jsp new file mode 100644 index 0000000..8604cb2 --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r10.jsp @@ -0,0 +1,136 @@ +<%@page import="com.capgemini.framework.common.SettingsHelper"%> +<%@page import="com.capgemini.framework.common.StringHelper" %> +<%@page import="com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum"%> +<%@page import="com.capgemini.reports.database.manager.MngSchedulingCriteriaVal" %> +<%@page import="java.util.Map"%> +<% + /* + * Available request parameters: + * "isUpdateReport" (boolean) Is this a submission of a NEW report or an UPDATE? + * "idReport" (long) Report Id in case of an UPDATE request + */ + boolean isDevMode = SettingsHelper.isDevMode(); + boolean isUpdate = Boolean.valueOf(request.getParameter("isUpdateReport")); + Long reportID = isUpdate ? Long.valueOf(request.getParameter("idReport")) : new Long(-1); + + /* Default values for development environment only */ + String theDefaultGen = ""; + String theDefaultGenMont = ""; + String theDefaultProduct = ""; + String theDefaultUnit = ""; + String theDefaultDate = ""; + String theMonoMulti = "MONO"; + + if( isDevMode ){ + theDefaultGen = "A10"; + theDefaultProduct = "ZZ01"; + theDefaultUnit = "1"; + theDefaultDate = "14-07-2014"; + } + + if( isUpdate){ // Existing values to reload from DB + Map theFunctionalCriteriaValues = new MngSchedulingCriteriaVal().getFunctionalMap(reportID); + + theDefaultGen = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.GENERIC)); + theDefaultGenMont = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.GENERIC_ASSEMB)); + theDefaultProduct = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.PRODUCT)); + theDefaultUnit = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.UNIT)); + theDefaultDate = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.EFFECTIVITY_DATE)); + theMonoMulti = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.MONO_MULTI)); + } +%> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Niveau : +
    + /> Mono + /> Multi +
    +
    +
    +
    Générique "Vue Technique" : + +
    Générique "Vue montage" : + +
    Produit* : + +
    Unit* : + +
    Date d'effectivité : + + +
    +
    +
    +
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/template_r11.jsp b/kurt-web/src/main/webapp/frames/template_r11.jsp new file mode 100644 index 0000000..022c989 --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r11.jsp @@ -0,0 +1,118 @@ +<%@page import="com.capgemini.framework.common.DateHelper" %> +<%@page import="com.capgemini.framework.common.SettingsHelper" %> +<%@page import="com.capgemini.framework.common.StringHelper"%> +<%@page import="com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum" + import="com.capgemini.reports.database.manager.MngSchedulingCriteriaVal" %> +<%@page import="java.util.Map"%> +<% + /* + * Available request parameters: + * "isUpdateReport" (boolean) Is this a submission of a NEW report or an UPDATE? + * "idReport" (long) Report Id in case of an UPDATE request + */ + boolean isDevMode = SettingsHelper.isDevMode(); + boolean isUpdate = Boolean.valueOf(request.getParameter("isUpdateReport")); + Long reportID = isUpdate ? Long.valueOf(request.getParameter("idReport")) : new Long(-1); + + // Default values in each field. May contain nothing / existing values / development values + String theDefaultGen = ""; + String theDefaultProduct = ""; + String theDefaultUnit = ""; + String theDefaultDate = ""; + String theMonoMulti = "MONO" ; + + if (isDevMode){ // Devmode default values + theDefaultGen = "C25"; + theDefaultProduct = "29R0"; + theDefaultUnit = "245"; + theDefaultDate = DateHelper.getDate(); // Today + } + if( isUpdate){ // Existing values to reload from DB + Map theFunctionalCriteriaValues = new MngSchedulingCriteriaVal().getFunctionalMap(reportID); + + theDefaultGen = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.GENERIC_ASSEMB)); + theDefaultProduct = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.PRODUCT)); + theDefaultUnit = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.UNIT)); + theDefaultDate = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.EFFECTIVITY_DATE)); + theMonoMulti = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.MONO_MULTI)); + } +%> + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Niveau : +
    + /> Mono + /> Multi +
    +
    +
    +
    Générique "Vue Technique" : + +
    Produit* : + +
    Unit* : + +
    Date d'effectivité* : + + +
    +
    +
    +
    + +

    + +
    + + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/template_r13.jsp b/kurt-web/src/main/webapp/frames/template_r13.jsp new file mode 100644 index 0000000..abdf297 --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r13.jsp @@ -0,0 +1,140 @@ +<%@page import="com.capgemini.framework.common.SettingsHelper"%> +<%@page import="com.capgemini.framework.common.StringHelper" %> +<%@page import="com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum"%> +<%@page import="com.capgemini.reports.database.manager.MngSchedulingCriteriaVal"%> +<%@page import="java.util.Map"%> +<% + /* + * Available request parameters: + * "isUpdateReport" (boolean) Is this a submission of a NEW report or an UPDATE? + * "idReport" (long) Report Id in case of an UPDATE request + */ + boolean isDevMode = SettingsHelper.isDevMode(); + boolean isUpdate = Boolean.valueOf(request.getParameter("isUpdateReport")); + Long reportID = isUpdate ? Long.valueOf(request.getParameter("idReport")) : new Long(-1); + + // Default values in each field. May contain nothing / existing values / development values + String theDefaultDateDebut = ""; + String theDefaultDateFin = ""; + String theTypeOject = ""; + + if (isDevMode){ // Devmode default values + theDefaultDateDebut = ""; + theDefaultDateFin = ""; + } + + if( isUpdate){ // Existing values to reload from DB + Map theFunctionalCriteriaValues = new MngSchedulingCriteriaVal().getFunctionalMap(reportID); + + theDefaultDateDebut = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.DATE_DEBUT)); + theDefaultDateFin = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.DATE_FIN)); + theTypeOject = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.TYPE_OBJET)); + } +%> + + +<%! private String isCRorFPP(final String theTypeOject) { + String selectedCR = ""; + String selectedFPP = ""; + StringBuilder buildSelect = new StringBuilder(); + if("CR".equals(theTypeOject)){ + selectedCR ="selected=\"selected\""; + }else{ + selectedFPP ="selected=\"selected\""; + } + buildSelect.append(""); + buildSelect.append(""); + return buildSelect.toString(); + } +%> + + + + + + + + + + + + + + + + + + +
    Date début : + + +
    +
    +
    +
    + +
    Date fin : + + +
    +
    +
    +
    + +
    Type objet* : + +

    + +
    + + + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/template_r15.jsp b/kurt-web/src/main/webapp/frames/template_r15.jsp new file mode 100644 index 0000000..60f7dad --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r15.jsp @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + +
    N° d'article* : + +
    Révision* : + +
    Langue* : + + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/template_r16.jsp b/kurt-web/src/main/webapp/frames/template_r16.jsp new file mode 100644 index 0000000..66766c7 --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r16.jsp @@ -0,0 +1,148 @@ +<%@page import="com.capgemini.framework.common.SettingsHelper"%> +<%@page import="com.capgemini.framework.common.StringHelper" %> +<%@page import="com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum"%> +<%@page import="com.capgemini.reports.database.manager.MngSchedulingCriteriaVal"%> +<%@page import="java.util.Map"%> +<% + /* + * Available request parameters: + * "isUpdateReport" (boolean) Is this a submission of a NEW report or an UPDATE? + * "idReport" (long) Report Id in case of an UPDATE request + */ + boolean isDevMode = SettingsHelper.isDevMode(); + boolean isUpdate = Boolean.valueOf(request.getParameter("isUpdateReport")); + Long reportID = isUpdate ? Long.valueOf(request.getParameter("idReport")) : new Long(-1); + + // Default values in each field. May contain nothing / existing values / development values + String theDefaultGen = ""; + String theDefaultProduct = ""; + String theDefaultUnit = ""; + String theDefaultLanguage= ""; + String theDefaultPrinterType= ""; + + if (isDevMode){ // Devmode default values + theDefaultGen = "C25"; + theDefaultProduct = "29R0"; + theDefaultUnit = "245"; + } + + if( isUpdate ){ // Existing values to reload from DB + Map theFunctionalCriteriaValues = new MngSchedulingCriteriaVal().getFunctionalMap(reportID); + + theDefaultGen = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.GENERIC_ASSEMB)); + theDefaultProduct = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.PRODUCT)); + theDefaultUnit = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.UNIT)); + theDefaultLanguage = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.LANGUAGE)); + theDefaultPrinterType = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.TYPE_IMPRESSION)); + } +%> + +<%! private String getSelectedLanguage(final String language){ + String selectedFR = ""; + String selectedEN = ""; + StringBuilder buildSelect = new StringBuilder(); + if("Francais".equals(language)){ + selectedFR ="selected=\"selected\""; + }else{ + selectedEN ="selected=\"selected\""; + } + buildSelect.append(""); + buildSelect.append(""); + return buildSelect.toString(); + } + + private String getPrinterType(final String printerType){ + String selectedDefCertifie = ""; + String selectedDefRealisation = ""; + StringBuilder buildSelect = new StringBuilder(); + if("Def_certifiee".equals(printerType)){ + selectedDefCertifie ="selected=\"selected\""; + }else{ + selectedDefRealisation ="selected=\"selected\""; + } + buildSelect.append(""); + buildSelect.append(""); + return buildSelect.toString(); + } +%> + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Générique* : + +
    Produit* : + +
    Unit* : + +
    Type d'impression : + +
    Langue : + +
    +
    + +
    + + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/template_r17.jsp b/kurt-web/src/main/webapp/frames/template_r17.jsp new file mode 100644 index 0000000..adc41af --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r17.jsp @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + +
    N° d'article* : + +
    Révision* : + +
    Langue* : + + +
    +
    + +
    + + + + + diff --git a/kurt-web/src/main/webapp/frames/template_r19.jsp b/kurt-web/src/main/webapp/frames/template_r19.jsp new file mode 100644 index 0000000..f4c2101 --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r19.jsp @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + +
    N° Document* : + +
    Révision* : + +

    + +
    + + + + + + + diff --git a/kurt-web/src/main/webapp/frames/template_r20.jsp b/kurt-web/src/main/webapp/frames/template_r20.jsp new file mode 100644 index 0000000..bbeead5 --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r20.jsp @@ -0,0 +1,375 @@ +<%@page import="com.capgemini.framework.common.SettingsHelper"%> +<%@page import="com.capgemini.framework.common.StringHelper" %> +<%@page import="com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum"%> +<%@page import="com.capgemini.reports.database.manager.MngSchedulingCriteriaVal"%> +<%@page import="java.util.Map"%> +<% + /* + * Available request parameters: + * "isUpdateReport" (boolean) Is this a submission of a NEW report or an UPDATE? + * "idReport" (long) Report Id in case of an UPDATE request + */ + boolean isDevMode = SettingsHelper.isDevMode(); + boolean isUpdate = Boolean.valueOf(request.getParameter("isUpdateReport")); + Long reportID = isUpdate ? Long.valueOf(request.getParameter("idReport")) : new Long(-1); + + /* Default values for development environment only */ + String theDefaultProductBefore = ""; + String theDefaultProductAfter = ""; + String theDefaultUnitAfter=""; + String theDefaultUnitBefore=""; + String theDefaultMatricule=""; + String theDefaultLMR="-"; + String theDefaultClasse =""; + String theDefaultMajorMinor=""; + String theDefaultUniqueConjoint =""; + + if (isDevMode){ // Devmode default values + theDefaultProductAfter = "97R0"; + theDefaultUnitAfter = "550"; + theDefaultUnitBefore = "520"; + theDefaultMatricule = "GE90 M10 MOTEUR ASSEMBLE"; + theDefaultLMR = "-"; + } + + if( isUpdate){ // Existing values to reload from DB + Map theFunctionalCriteriaValues = new MngSchedulingCriteriaVal().getFunctionalMap(reportID); + + // Product + theDefaultProductBefore = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.PRODUCT_BEFORE)); + theDefaultProductAfter = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.PRODUCT_AFTER)); + theDefaultMatricule = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.MATRICULE)); + //Unit + theDefaultUnitAfter = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.UNIT_AFTER)); + theDefaultUnitBefore = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.UNIT_BEFORE)); + // Overall + theDefaultClasse = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.CLASSE)); + theDefaultMajorMinor = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.MAJOR_MINOR)); + theDefaultUniqueConjoint = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.CONJOINT_UNIQUE)); + // LMR + theDefaultLMR = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.LMR)); + } +%> + + +<%! private String getSelectedClasse(final String theClasse){ + String selectedClasseOne = ""; + String selectedClasseTwo = ""; + StringBuilder buildSelect = new StringBuilder(); + if("1".equals(theClasse)){ + selectedClasseOne ="selected=\"selected\""; + }else{ + selectedClasseTwo ="selected=\"selected\""; + } + buildSelect.append(""); + buildSelect.append(""); + + return buildSelect.toString(); + } + + private String getSelectedMajorMinor(final String theMajorMinor){ + String selectedMajor = ""; + String selectedMinor = ""; + StringBuilder buildSelect = new StringBuilder(); + if("Majeur".equals(theMajorMinor)){ + selectedMajor ="selected=\"selected\""; + }else{ + selectedMinor ="selected=\"selected\""; + } + buildSelect.append(""); + buildSelect.append(""); + + return buildSelect.toString(); + } + + private String getSelectedUniqueConjoint(final String theUniqueConjoint){ + String selectedUnique = ""; + String selectedConjoint = ""; + StringBuilder buildSelect = new StringBuilder(); + if("Conjoint".equals(theUniqueConjoint)){ + selectedConjoint = "selected=\"selected\""; + }else{ + selectedUnique = "selected=\"selected\""; + } + buildSelect.append(""); + buildSelect.append(""); + + return buildSelect.toString(); + } + + /* generate js Array*/ + private String generateArrayLMRs(final String theLMRsList){ + String[] lmrList = StringHelper.splitWithoutDelim(";", theLMRsList); + StringBuilder theTableCode = new StringBuilder("var LMRsArray = new Array();\n"); + int i = 0; + for(String curLMR : lmrList ){ + theTableCode.append("LMRsArray[").append(i).append("]='").append(curLMR).append("';"); + i++; + } + return theTableCode.toString(); + } +%> + + + +<% if( isUpdate && !theDefaultLMR.contains("-")){ %> + +<% } %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Informations de la configuration "Après" :Informations de la configuration "Avant" :
    Produit* : + + Produit (non modifiable) : + +
    Unit* : + + Unit de référence* : + +
    +
    +
    +
    Informations supplémentaires :
    +
    Matricule : + +
    Classe* : + +
    Majeur ou Mineur* : + +
    Unique ou Conjoint* : + +
    Modifications Retirées : +
    +
    + <% if( isUpdate && !theDefaultLMR.contains("-") ){ %> + + <% }else{ %> +
    + +
    + <% } %> +
    +
    + +
    + + + + +<% if( !isUpdate ){ %> + +<% } %> \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/template_r21.jsp b/kurt-web/src/main/webapp/frames/template_r21.jsp new file mode 100644 index 0000000..85d7b2c --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r21.jsp @@ -0,0 +1,116 @@ +<%@page import="com.capgemini.framework.common.SettingsHelper"%> +<%@page import="com.capgemini.framework.common.StringHelper" %> +<%@page import="com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum"%> +<%@page import="com.capgemini.reports.database.manager.MngSchedulingCriteriaVal"%> +<%@page import="java.util.Map"%> + +<% + /* + * Available request parameters: + * "isUpdateReport" (boolean) Is this a submission of a NEW report or an UPDATE? + * "idReport" (long) Report Id in case of an UPDATE request + */ + boolean isDevMode = SettingsHelper.isDevMode(); + boolean isUpdate = Boolean.valueOf(request.getParameter("isUpdateReport")); + Long reportID = isUpdate ? Long.valueOf(request.getParameter("idReport")) : new Long(-1); + + // Default values in each field. May contain nothing / existing values / development values + String theDefaultGen = ""; + String theDefaultGenMont = ""; + String theDefaultProduct = ""; + String theDefaultUnit = ""; + String theDefaultDate = ""; + + if (isDevMode){ // Devmode default values + theDefaultGen = "E24"; + theDefaultGenMont = "24E"; + theDefaultProduct = "30E0"; + theDefaultUnit = "20"; + theDefaultDate = "01-01-2015"; + } + + if( isUpdate){ // Existing values to reload from DB + Map theFunctionalCriteriaValues = new MngSchedulingCriteriaVal().getFunctionalMap(reportID); + + theDefaultGen = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.GENERIC)); + theDefaultGenMont = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.GENERIC_ASSEMB)); + theDefaultProduct = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.PRODUCT)); + theDefaultUnit = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.UNIT)); + theDefaultDate = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.EFFECTIVITY_DATE)); + + } +%> + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Générique "Vue Technique"* : + +
    Générique "Vue montage"* : + +
    Produit* : + +
    Unit* : + +
    Date d'effectivité : + +
    +
    +
    +
    +

    + +
    + + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/template_r22.jsp b/kurt-web/src/main/webapp/frames/template_r22.jsp new file mode 100644 index 0000000..ac833de --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r22.jsp @@ -0,0 +1,85 @@ +<%@page import="com.capgemini.framework.common.SettingsHelper"%> +<%@page import="com.capgemini.framework.common.StringHelper"%> + + + + + + + + + + + + + + + + + + +
    N° d'article* : + +
    Révision* : + + +
    +
    + +
    + + + + + + diff --git a/kurt-web/src/main/webapp/frames/template_r23.jsp b/kurt-web/src/main/webapp/frames/template_r23.jsp new file mode 100644 index 0000000..93cd178 --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r23.jsp @@ -0,0 +1,231 @@ +<%@page import="com.capgemini.framework.common.SettingsHelper" %> +<%@page import="com.capgemini.framework.common.StringHelper" %> +<%@page import="com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum" %> +<%@page import="com.capgemini.reports.database.manager.MngSchedulingCriteriaVal" %> +<%@page import="java.util.Map" %> +<%@page import="com.capgemini.framework.common.DateHelper" %> +<%! final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("com.capgemini.report.template_r23.jsp"); %> +<% + /* + * Available request parameters: + * "isUpdateReport" (boolean) Is this a submission of a NEW report or an UPDATE? + * "idReport" (long) Report Id in case of an UPDATE request + */ + boolean isDevMode = SettingsHelper.isDevMode(); + boolean isUpdate = Boolean.valueOf(request.getParameter("isUpdateReport")); + Long reportID = isUpdate ? Long.valueOf(request.getParameter("idReport")) : new Long(-1); + + log.info("**********************"); + log.info("isDevMode = " + isDevMode); + log.info("isUpdate = " + isUpdate); + log.info("reportID = " + reportID); + + // Default values in each field. May contain nothing / existing values / development values + String theDefaultGen = ""; + String theDefaultGenMont = ""; + String theDefaultProduct = ""; + String theDefaultDate = DateHelper.getDate(); + String theMonoMulti = "MONO"; + String isSuperModelBOM = Boolean.FALSE.toString(); + String isWithFrozenUnit = Boolean.FALSE.toString(); + String theDefaultUnit = ""; + String theDefaultFromUnit = ""; + String theDefaultFrozenSinceLessThan = ""; + + if (isDevMode) { // Devmode default values + theDefaultGen = ""; + theDefaultGenMont = "24E"; + theDefaultProduct = "30E0"; + theDefaultDate = "01-01-2015"; + } + + if (isUpdate) { // Existing values to reload from DB + Map theFunctionalCriteriaValues = new MngSchedulingCriteriaVal().getFunctionalMap(reportID); + + theDefaultGen = StringHelper.replaceNullByEmpty(theFunctionalCriteriaValues.get(ReportCriteriaEnum.GENERIC)); + theDefaultGenMont = StringHelper.replaceNullByEmpty(theFunctionalCriteriaValues.get(ReportCriteriaEnum.GENERIC_ASSEMB)); + theDefaultProduct = StringHelper.replaceNullByEmpty(theFunctionalCriteriaValues.get(ReportCriteriaEnum.PRODUCT)); + theDefaultDate = StringHelper.replaceNullByEmpty(theFunctionalCriteriaValues.get(ReportCriteriaEnum.EFFECTIVITY_DATE)); + theMonoMulti = StringHelper.replaceNullByEmpty(theFunctionalCriteriaValues.get(ReportCriteriaEnum.MONO_MULTI)); + isSuperModelBOM = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.SUPERMODEL) ); + isWithFrozenUnit = StringHelper.replaceNullByEmpty(theFunctionalCriteriaValues.get(ReportCriteriaEnum.WITH_FROZEN_UNIT)); + theDefaultUnit = StringHelper.replaceNullByEmpty(theFunctionalCriteriaValues.get(ReportCriteriaEnum.UNIT)); + theDefaultFromUnit = StringHelper.replaceNullByEmpty(theFunctionalCriteriaValues.get(ReportCriteriaEnum.FROM_UNIT)); + theDefaultFrozenSinceLessThan = StringHelper.replaceNullByEmpty(theFunctionalCriteriaValues.get(ReportCriteriaEnum.UNITS_FROZEN_SINCE_LESS_THAN)); + + log.info("theDefaultGen = " + theDefaultGen); + log.info("theDefaultGenMont = " + theDefaultGenMont); + log.info("theDefaultProduct = " + theDefaultProduct); + log.info("theDefaultDate = " + theDefaultDate); + log.info("theMonoMulti = " + theMonoMulti); + log.info("isWithFrozenUnit = " + isWithFrozenUnit); + log.info("theDefaultUnit = " + theDefaultUnit); + log.info("theDefaultFromUnit = " + theDefaultFromUnit); + log.info("theDefaultFrozenSinceLessThan = " + theDefaultFrozenSinceLessThan); + } +%> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Niveau : +
    + /> Mono + /> Multi + + /> + + /> +
    +
    +
    +
    Générique "Vue Technique" : + +
    Générique "Vue montage" : + +
    Produit* : + +
    Unit : + +
    A partir du Unit : + +
    Units gelés il y a moins de : + +
    Date d'effectivité : + + +
    +
    +
    +
    +
    +
    + +
    + + + diff --git a/kurt-web/src/main/webapp/frames/template_r24.jsp b/kurt-web/src/main/webapp/frames/template_r24.jsp new file mode 100644 index 0000000..15d7298 --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r24.jsp @@ -0,0 +1,137 @@ +<%@page import="com.capgemini.framework.common.StringHelper"%> +<%@page import="com.capgemini.framework.common.SettingsHelper"%> +<%@page import="com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum"%> +<%@page import="com.capgemini.reports.database.manager.MngSchedulingCriteriaVal"%> +<%@page import="java.util.Map"%> +<% + /* + * Available request parameters: + * "isUpdateReport" (boolean) Is this a submission of a NEW report or an UPDATE? + * "idReport" (long) Report Id in case of an UPDATE request + */ + boolean isDevMode = SettingsHelper.isDevMode(); + boolean isUpdate = Boolean.valueOf(request.getParameter("isUpdateReport")); + Long reportID = isUpdate ? Long.valueOf(request.getParameter("idReport")) : new Long(-1); + + // Default values in each field. May contain nothing / existing values / development values + String theDefaultProduct = ""; + String theDefaultUnit = ""; + String theDefaultLanguage= ""; + String theDefaultPrinterType= ""; + + if (isDevMode){ // Devmode default values + theDefaultProduct = "29R0"; + theDefaultUnit = "245"; + } + + if( isUpdate ){ // Existing values to reload from DB + Map theFunctionalCriteriaValues = new MngSchedulingCriteriaVal().getFunctionalMap(reportID); + + theDefaultProduct = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.PRODUCT)); + theDefaultUnit = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.UNIT)); + theDefaultLanguage = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.LANGUAGE)); + theDefaultPrinterType = StringHelper.replaceNullByEmpty( theFunctionalCriteriaValues.get(ReportCriteriaEnum.TYPE_IMPRESSION)); + } +%> + +<%! private String getSelectedLanguage(final String language){ + String selectedFR = ""; + String selectedEN = ""; + StringBuilder buildSelect = new StringBuilder(); + if("Francais".equals(language)){ + selectedFR ="selected=\"selected\""; + }else{ + selectedEN ="selected=\"selected\""; + } + buildSelect.append(""); + buildSelect.append(""); + return buildSelect.toString(); +} + + private String getPrinterType(final String printerType){ + String selectedDefCertifie = ""; + String selectedDefRealisation = ""; + StringBuilder buildSelect = new StringBuilder(); + if("Def_certifiee".equals(printerType)){ + selectedDefCertifie ="selected=\"selected\""; + }else{ + selectedDefRealisation ="selected=\"selected\""; + } + buildSelect.append(""); + buildSelect.append(""); + return buildSelect.toString(); + } +%> + + + + + + + + + + + + + + + + + + + + + + +
    Produit* : + +
    Unit* : + +
    Type d'impression : + +
    Langue : + +
    +
    + +
    + + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/template_r25.jsp b/kurt-web/src/main/webapp/frames/template_r25.jsp new file mode 100644 index 0000000..9e2218d --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r25.jsp @@ -0,0 +1,140 @@ +<%@page import="com.capgemini.framework.common.SettingsHelper" %> +<%@page import="com.capgemini.framework.common.StringHelper" %> +<%@page import="com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum" %> +<%@page import="com.capgemini.reports.database.manager.MngSchedulingCriteriaVal" %> +<%@page import="java.util.Map" %> +<% + /* + * Available request parameters: + * "isUpdateReport" (boolean) Is this a submission of a NEW report or an UPDATE? + * "idReport" (long) Report Id in case of an UPDATE request + */ + boolean isDevMode = SettingsHelper.isDevMode(); + boolean isUpdate = Boolean.valueOf(request.getParameter("isUpdateReport")); + Long reportID = isUpdate ? Long.valueOf(request.getParameter("idReport")) : new Long(-1); + + // Default values in each field. May contain nothing / existing values / development values + String theDefaultProduct = ""; + String theDefaultUnit = ""; + String theDefaultLanguage = ""; + String theDefaultPrinterType = ""; + + if (isDevMode) { // Devmode default values + theDefaultProduct = "29R0"; + theDefaultUnit = "245"; + } + + if (isUpdate) { // Existing values to reload from DB + Map theFunctionalCriteriaValues = new MngSchedulingCriteriaVal().getFunctionalMap(reportID); + + theDefaultProduct = StringHelper.replaceNullByEmpty(theFunctionalCriteriaValues.get(ReportCriteriaEnum.PRODUCT)); + theDefaultUnit = StringHelper.replaceNullByEmpty(theFunctionalCriteriaValues.get(ReportCriteriaEnum.UNIT)); + theDefaultLanguage = StringHelper.replaceNullByEmpty(theFunctionalCriteriaValues.get(ReportCriteriaEnum.LANGUAGE)); + theDefaultPrinterType = StringHelper.replaceNullByEmpty(theFunctionalCriteriaValues.get(ReportCriteriaEnum.TYPE_IMPRESSION)); + } +%> + +<%! private String getSelectedLanguage(final String language) { + String selectedFR = ""; + String selectedEN = ""; + StringBuilder buildSelect = new StringBuilder(); + if ("Francais".equals(language)) { + selectedFR = "selected=\"selected\""; + } + else { + selectedEN = "selected=\"selected\""; + } + buildSelect.append(""); + buildSelect.append(""); + return buildSelect.toString(); +} + + private String getPrinterType(final String printerType) { + String selectedDefCertifie = ""; + String selectedDefRealisation = ""; + StringBuilder buildSelect = new StringBuilder(); + if ("Def_certifiee".equals(printerType)) { + selectedDefCertifie = "selected=\"selected\""; + } + else { + selectedDefRealisation = "selected=\"selected\""; + } + buildSelect.append(""); + buildSelect.append(""); + return buildSelect.toString(); + } +%> + + + + + + + + + + + + + + + + + + + + + + +
    Produit* : + +
    Unit : + +
    Type d'impression : + +
    Langue : + +
    +
    + +
    + + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/template_r26.jsp b/kurt-web/src/main/webapp/frames/template_r26.jsp new file mode 100644 index 0000000..02ae75e --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r26.jsp @@ -0,0 +1,94 @@ + + +<%@ page import="com.capgemini.framework.common.SettingsHelper" %> +<%@ page import="java.util.Date" %> +<%@ page import="java.util.Calendar" %> +<%@ page import="java.text.SimpleDateFormat" %> + +<% + Date startDate = Calendar.getInstance().getTime(); + SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy"); + + String revisionRule = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R26", SettingsHelper.getDefaultRevisionRule()); + String date = sdf.format(startDate); +%> + + + + + + + + + + + + + + + + + + + + +
    Composant* : + +
    Règle de révision : + +
    Date d'effectivité : + +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/frames/template_r27.jsp b/kurt-web/src/main/webapp/frames/template_r27.jsp new file mode 100644 index 0000000..f8ec07e --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r27.jsp @@ -0,0 +1,45 @@ +<%@page import="com.capgemini.framework.common.SettingsHelper"%> +<%@page import="com.capgemini.framework.common.StringHelper" %> +<%@page import="com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum"%> +<%@page import="com.capgemini.reports.database.manager.MngSchedulingCriteriaVal"%> +<%@page import="java.util.Map"%> +<%! final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("com.capgemini.report.template_r27.jsp"); %> +<% + /* + * Available request parameters: + * "isUpdateReport" (boolean) Is this a submission of a NEW report or an UPDATE? + * "idReport" (long) Report Id in case of an UPDATE request + */ + boolean isDevMode = SettingsHelper.isDevMode(); + boolean isUpdate = Boolean.valueOf(request.getParameter("isUpdateReport")); + Long reportID = isUpdate ? Long.valueOf(request.getParameter("idReport")) : new Long(-1); + + log.info("**********************"); + log.info("isDevMode = " + isDevMode); + log.info("isUpdate = " + isUpdate); + log.info("reportID = " + reportID); + +%> + + + + + + +
    +
    + +
    + + + diff --git a/kurt-web/src/main/webapp/frames/template_r28.jsp b/kurt-web/src/main/webapp/frames/template_r28.jsp new file mode 100644 index 0000000..70e2def --- /dev/null +++ b/kurt-web/src/main/webapp/frames/template_r28.jsp @@ -0,0 +1,45 @@ +<%@page import="com.capgemini.framework.common.SettingsHelper"%> +<%@page import="com.capgemini.framework.common.StringHelper" %> +<%@page import="com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum"%> +<%@page import="com.capgemini.reports.database.manager.MngSchedulingCriteriaVal"%> +<%@page import="java.util.Map"%> +<%! final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("com.capgemini.report.template_r28.jsp"); %> +<% + /* + * Available request parameters: + * "isUpdateReport" (boolean) Is this a submission of a NEW report or an UPDATE? + * "idReport" (long) Report Id in case of an UPDATE request + */ + boolean isDevMode = SettingsHelper.isDevMode(); + boolean isUpdate = Boolean.valueOf(request.getParameter("isUpdateReport")); + Long reportID = isUpdate ? Long.valueOf(request.getParameter("idReport")) : new Long(-1); + + log.info("**********************"); + log.info("isDevMode = " + isDevMode); + log.info("isUpdate = " + isUpdate); + log.info("reportID = " + reportID); + +%> + + + + + + +
    +
    + +
    + + + diff --git a/kurt-web/src/main/webapp/ihm/bt-error-functional.png b/kurt-web/src/main/webapp/ihm/bt-error-functional.png new file mode 100644 index 0000000..dbfda22 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/bt-error-functional.png differ diff --git a/kurt-web/src/main/webapp/ihm/bt-error-technical.png b/kurt-web/src/main/webapp/ihm/bt-error-technical.png new file mode 100644 index 0000000..34abb64 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/bt-error-technical.png differ diff --git a/kurt-web/src/main/webapp/ihm/bt-refresh.png b/kurt-web/src/main/webapp/ihm/bt-refresh.png new file mode 100644 index 0000000..5f84138 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/bt-refresh.png differ diff --git a/kurt-web/src/main/webapp/ihm/bt-save.png b/kurt-web/src/main/webapp/ihm/bt-save.png new file mode 100644 index 0000000..99d532e Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/bt-save.png differ diff --git a/kurt-web/src/main/webapp/ihm/bt-search.png b/kurt-web/src/main/webapp/ihm/bt-search.png new file mode 100644 index 0000000..c7095f2 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/bt-search.png differ diff --git a/kurt-web/src/main/webapp/ihm/button-back.png b/kurt-web/src/main/webapp/ihm/button-back.png new file mode 100644 index 0000000..9a2fc35 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/button-back.png differ diff --git a/kurt-web/src/main/webapp/ihm/calendar_planification.png b/kurt-web/src/main/webapp/ihm/calendar_planification.png new file mode 100644 index 0000000..f8a88b9 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/calendar_planification.png differ diff --git a/kurt-web/src/main/webapp/ihm/delete.png b/kurt-web/src/main/webapp/ihm/delete.png new file mode 100644 index 0000000..47c464a Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/delete.png differ diff --git a/kurt-web/src/main/webapp/ihm/dialog.gif b/kurt-web/src/main/webapp/ihm/dialog.gif new file mode 100644 index 0000000..09f64d5 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/dialog.gif differ diff --git a/kurt-web/src/main/webapp/ihm/generateur-rapports-teamcenter.png b/kurt-web/src/main/webapp/ihm/generateur-rapports-teamcenter.png new file mode 100644 index 0000000..1d6d4a3 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/generateur-rapports-teamcenter.png differ diff --git a/kurt-web/src/main/webapp/ihm/ico-admin.png b/kurt-web/src/main/webapp/ihm/ico-admin.png new file mode 100644 index 0000000..5fc02e2 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/ico-admin.png differ diff --git a/kurt-web/src/main/webapp/ihm/ico-email.png b/kurt-web/src/main/webapp/ihm/ico-email.png new file mode 100644 index 0000000..8ac6662 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/ico-email.png differ diff --git a/kurt-web/src/main/webapp/ihm/ico-jboss.png b/kurt-web/src/main/webapp/ihm/ico-jboss.png new file mode 100644 index 0000000..bc98bc0 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/ico-jboss.png differ diff --git a/kurt-web/src/main/webapp/ihm/ico-progress.png b/kurt-web/src/main/webapp/ihm/ico-progress.png new file mode 100644 index 0000000..10f7655 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/ico-progress.png differ diff --git a/kurt-web/src/main/webapp/ihm/ico-queue.png b/kurt-web/src/main/webapp/ihm/ico-queue.png new file mode 100644 index 0000000..6de1521 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/ico-queue.png differ diff --git a/kurt-web/src/main/webapp/ihm/ico-queued.png b/kurt-web/src/main/webapp/ihm/ico-queued.png new file mode 100644 index 0000000..3553e84 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/ico-queued.png differ diff --git a/kurt-web/src/main/webapp/ihm/ico-report-stats.png b/kurt-web/src/main/webapp/ihm/ico-report-stats.png new file mode 100644 index 0000000..25a676e Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/ico-report-stats.png differ diff --git a/kurt-web/src/main/webapp/ihm/ico-report.png b/kurt-web/src/main/webapp/ihm/ico-report.png new file mode 100644 index 0000000..9ec394c Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/ico-report.png differ diff --git a/kurt-web/src/main/webapp/ihm/ico-scheduled.png b/kurt-web/src/main/webapp/ihm/ico-scheduled.png new file mode 100644 index 0000000..d981231 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/ico-scheduled.png differ diff --git a/kurt-web/src/main/webapp/ihm/ico-stats.png b/kurt-web/src/main/webapp/ihm/ico-stats.png new file mode 100644 index 0000000..05a498f Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/ico-stats.png differ diff --git a/kurt-web/src/main/webapp/ihm/ico-user.png b/kurt-web/src/main/webapp/ihm/ico-user.png new file mode 100644 index 0000000..e24ed7a Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/ico-user.png differ diff --git a/kurt-web/src/main/webapp/ihm/icone-moins.png b/kurt-web/src/main/webapp/ihm/icone-moins.png new file mode 100644 index 0000000..7a6b790 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/icone-moins.png differ diff --git a/kurt-web/src/main/webapp/ihm/icone-plus.png b/kurt-web/src/main/webapp/ihm/icone-plus.png new file mode 100644 index 0000000..0908e24 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/icone-plus.png differ diff --git a/kurt-web/src/main/webapp/ihm/input-back.png b/kurt-web/src/main/webapp/ihm/input-back.png new file mode 100644 index 0000000..cee1526 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/input-back.png differ diff --git a/kurt-web/src/main/webapp/ihm/left-bar-action-back-hover.png b/kurt-web/src/main/webapp/ihm/left-bar-action-back-hover.png new file mode 100644 index 0000000..15eb12a Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/left-bar-action-back-hover.png differ diff --git a/kurt-web/src/main/webapp/ihm/left-bar-action-back.png b/kurt-web/src/main/webapp/ihm/left-bar-action-back.png new file mode 100644 index 0000000..e92aab4 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/left-bar-action-back.png differ diff --git a/kurt-web/src/main/webapp/ihm/left-bar-top.png b/kurt-web/src/main/webapp/ihm/left-bar-top.png new file mode 100644 index 0000000..391f824 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/left-bar-top.png differ diff --git a/kurt-web/src/main/webapp/ihm/left-bar.png b/kurt-web/src/main/webapp/ihm/left-bar.png new file mode 100644 index 0000000..4b94886 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/left-bar.png differ diff --git a/kurt-web/src/main/webapp/ihm/left-bar_160.png b/kurt-web/src/main/webapp/ihm/left-bar_160.png new file mode 100644 index 0000000..c38259c Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/left-bar_160.png differ diff --git a/kurt-web/src/main/webapp/ihm/left-bar_260.png b/kurt-web/src/main/webapp/ihm/left-bar_260.png new file mode 100644 index 0000000..7527a2d Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/left-bar_260.png differ diff --git a/kurt-web/src/main/webapp/ihm/progress.gif b/kurt-web/src/main/webapp/ihm/progress.gif new file mode 100644 index 0000000..ed3ad84 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/progress.gif differ diff --git a/kurt-web/src/main/webapp/ihm/report.png b/kurt-web/src/main/webapp/ihm/report.png new file mode 100644 index 0000000..3b58df4 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/report.png differ diff --git a/kurt-web/src/main/webapp/ihm/state_executing.png b/kurt-web/src/main/webapp/ihm/state_executing.png new file mode 100644 index 0000000..4859e0c Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/state_executing.png differ diff --git a/kurt-web/src/main/webapp/ihm/state_failed.png b/kurt-web/src/main/webapp/ihm/state_failed.png new file mode 100644 index 0000000..51aa7a1 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/state_failed.png differ diff --git a/kurt-web/src/main/webapp/ihm/state_finished.png b/kurt-web/src/main/webapp/ihm/state_finished.png new file mode 100644 index 0000000..4e8240c Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/state_finished.png differ diff --git a/kurt-web/src/main/webapp/ihm/state_ready.png b/kurt-web/src/main/webapp/ihm/state_ready.png new file mode 100644 index 0000000..3df8605 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/state_ready.png differ diff --git a/kurt-web/src/main/webapp/ihm/state_unknown.png b/kurt-web/src/main/webapp/ihm/state_unknown.png new file mode 100644 index 0000000..6d26f9b Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/state_unknown.png differ diff --git a/kurt-web/src/main/webapp/ihm/state_wait.png b/kurt-web/src/main/webapp/ihm/state_wait.png new file mode 100644 index 0000000..c87fb8b Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/state_wait.png differ diff --git a/kurt-web/src/main/webapp/ihm/title.png b/kurt-web/src/main/webapp/ihm/title.png new file mode 100644 index 0000000..267e77c Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/title.png differ diff --git a/kurt-web/src/main/webapp/ihm/top-bar.png b/kurt-web/src/main/webapp/ihm/top-bar.png new file mode 100644 index 0000000..f293450 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/top-bar.png differ diff --git a/kurt-web/src/main/webapp/ihm/update.png b/kurt-web/src/main/webapp/ihm/update.png new file mode 100644 index 0000000..9c7f773 Binary files /dev/null and b/kurt-web/src/main/webapp/ihm/update.png differ diff --git a/kurt-web/src/main/webapp/index.jsp b/kurt-web/src/main/webapp/index.jsp new file mode 100644 index 0000000..3fca861 --- /dev/null +++ b/kurt-web/src/main/webapp/index.jsp @@ -0,0 +1,225 @@ +<%@page import="com.capgemini.framework.common.SettingsHelper" %> +<%@page import="com.capgemini.framework.common.activedirectory.ActiveDirectory" %> +<%@page import="com.capgemini.framework.teamcenter.exceptions.KurtException" %> +<%@page import="com.capgemini.reports.database.javabean.DbUser.UserData" %> +<%@page import="java.net.InetAddress" %> +<%! final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("com.capgemini.index.jsp"); %> +<% + response.setHeader("Pragma", "no-cache"); + response.setHeader("Cache-Control", "no-cache"); + response.setDateHeader("Expires", 0); + + String rawUserLogin = request.getRemoteUser(); + + // Useful for debug: + log.trace("Request: =" + request.toString()); + log.trace("Request: Auth Type =" + request.getAuthType()); + log.trace("Request: HeaderNames=" + request.getHeaderNames().toString()); + log.trace("Request: isSecure =" + request.isSecure()); + log.trace("Raw userName =" + rawUserLogin); + + + // Obtain user data (if the header's login is valid) + UserData userData; + try { + userData = ActiveDirectory.obtainUserData(rawUserLogin); + } catch (KurtException e) { + // Failed to authenticate the user, defaulting to Guest + log.debug("Could not authenticate the user: " + (rawUserLogin == null ? "null" : rawUserLogin), e); + userData = ActiveDirectory.getGuestUser(); + } + + // Tag for developer mode + String theDevModeInfo = ""; + boolean isDevMode = SettingsHelper.isDevMode(); + boolean isValMode = SettingsHelper.isValMode(); + if (isDevMode) { + theDevModeInfo = " - Mode DEV actif"; + } + if (isValMode) { + theDevModeInfo = theDevModeInfo + " - Mode VAL actif"; + } + + // Tag for URL to the current teamcenter target server + String theTeamcenterURL; + if (isValMode || isDevMode) { + theTeamcenterURL = " - " + SettingsHelper.getPropertyWithDefaultValue("teamcenter.url", "Unknown"); + } else { + theTeamcenterURL = ""; + } +%> + + + + + + + + + + + + + + Générateur de rapports Teamcenter + + + + + + + + + + + + + +
    +
    +
    + +
    +
    Utilisateur :
    + + <%=userData.getLogin()%> + + + <% if (isDevMode){ %> + + + <%=userData.getFirstName()%> <%=userData.getSurname()%> + + + <% } %> + + <% if(userData.isAdmin()){%> + Admin + <% } %> + +
    Actions :
    + <% if (isDevMode){ %> + + Rapport 01 + Rapport 03 + Rapport 07 + Rapport 10 + Rapport 11 + Rapport 13 + Rapport 15 + Rapport 16 + Rapport 17 + Rapport 19 + Rapport 20 + Rapport 21 + Rapport 22 + Rapport 23 + Rapport 24 + Rapport 25 + Rapport 26 + Rapport 27 + Rapport 28 + <% } %> + Mes rapports + <% if (isDevMode){ %> + + Suivi mémoire + <% } %> + + <% if(userData.isAdmin() || isDevMode){ %> + +
    Administration :
    + <% if (isDevMode) { %> + Interface JBoss + <% } %> + Rapports en + cours + Etat des queues + Statistiques par + rapport + Statistiques par + utilisateur + Planification + des rapports + <% } %> + +
    + + + + + + + + + + +
       
    + +
    + + + + + \ No newline at end of file diff --git a/kurt-web/src/main/webapp/js/criteria.js b/kurt-web/src/main/webapp/js/criteria.js new file mode 100644 index 0000000..5871a95 --- /dev/null +++ b/kurt-web/src/main/webapp/js/criteria.js @@ -0,0 +1,17 @@ +function DisplayTable() { + + var tableContent = ''; + + /* Browse each criteria */ + var criteriaCount = criteriaArray.length; + for (var i = 0; i < criteriaCount; i++) { + + /* Display columns of the current criteria */ + tableContent += ''; + tableContent += '' + criteriaArray[i]['name'] + ''; + tableContent += '' + criteriaArray[i]['value'] + ''; + tableContent += ''; + } + + document.write(tableContent); +} diff --git a/kurt-web/src/main/webapp/js/dialog_box.js b/kurt-web/src/main/webapp/js/dialog_box.js new file mode 100644 index 0000000..4a984fc --- /dev/null +++ b/kurt-web/src/main/webapp/js/dialog_box.js @@ -0,0 +1,71 @@ +/* Variable globale */ +var dialogRefresh = false; + +function GetById(id) { + return document.getElementById(id); +} + +String.prototype.startsWith = function(s) { + return (this.match("^" + s) == s); +}; + +/* calculate the current window height */ +function pageHeight() { + return window.innerHeight != null ? window.innerHeight : document.documentElement + && document.documentElement.clientHeight ? document.documentElement.clientHeight + : document.body != null ? document.body.clientHeight : null; +} + +/* calculate the current window vertical offset */ +function topPosition() { + return pageHeight() / 2 - 50; +} + +/* build-show the dialog box, populate the data and call the fadeDialog function */ +/* var t = title */ +/* var m = message */ +function Dialog(t, m) { + + /* Icone du message */ + var i = ''; + + var dialog = GetById('dialog'); + if (!dialog) { + dialog = document.createElement('DIV'); + dialog.id = 'dialog'; + dialog.innerHTML = '
     
     
    '; + dialog.style.top = topPosition(); + document.getElementsByTagName('body')[0].appendChild(dialog); + var mask = document.createElement('div'); + mask.id = 'dialog-mask'; + mask.style.height = Math.max(document.body.scrollHeight, document.body.offsetHeight) + 'px'; + document.getElementsByTagName('body')[0].appendChild(mask); + } else { + dialog.style.top = topPosition(); + dialog.style.display = ''; + GetById('dialog-mask').style.display = ''; + } + + GetById('dialog-title').innerHTML = t; + GetById('dialog-content').innerHTML = m; + GetById('dialog-table').style.backgroundImage = i; + + if (m.startsWith("\')" title="Afficher les critères" style="cursor:pointer;width:16px;height:16px;"/>\n'; + tableContent += currentError + ' ' + currentDownload + ' \n'; + tableContent += ' ' + currentStatus + '\n'; + tableContent += ''; + } + document.write(tableContent); +} + +/* Redirect to page */ +function GoPage(i) { + document.location.href = '/kurt-web/frames/my_reports.jsp?page=' + i; +} diff --git a/kurt-web/src/main/webapp/js/obtain_data.js b/kurt-web/src/main/webapp/js/obtain_data.js new file mode 100644 index 0000000..da63e1e --- /dev/null +++ b/kurt-web/src/main/webapp/js/obtain_data.js @@ -0,0 +1,27 @@ +/** + * Tool for sending an AJAX request with GET parameters for retrieving data. + */ + +/* Dedicated HttpRequest object (as global) */ +var objGetRequest = null; + +/* Main method for retrieving data in the ServerResponseForObtainData callback method */ +function ObtainData(url) { + /* Detect client browser for getting the expected HttpRequest object */ + if (window.XMLHttpRequest) + objGetRequest = new XMLHttpRequest(); + else if (window.ActiveXObject) + objGetRequest = new ActiveXObject("Microsoft.XMLHTTP"); + + /* Send AJAX form and get response */ + objGetRequest.open('post', url, true); + objGetRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + objGetRequest.onreadystatechange = ServerResponseForObtainData; + + /* Display loading bar and hide buttons */ + document.getElementById("loading").style.display = ''; + document.getElementById("btZone").style.display = 'none'; + + /* Send request and wait for response */ + objGetRequest.send(); +} diff --git a/kurt-web/src/main/webapp/js/pikaday.js b/kurt-web/src/main/webapp/js/pikaday.js new file mode 100644 index 0000000..258a000 --- /dev/null +++ b/kurt-web/src/main/webapp/js/pikaday.js @@ -0,0 +1,915 @@ +(function (root, factory) { + 'use strict'; + + var moment; + if (typeof exports === 'object') { + // CommonJS module + // Load moment.js as an optional dependency + try { + moment = require('moment'); + } catch (e) { + } + module.exports = factory(moment); + } else if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(function (req) { + // Load moment.js as an optional dependency + var id = 'moment'; + try { + moment = req(id); + } catch (e) { + } + return factory(moment); + }); + } else { + root.Pikaday = factory(root.moment); + } +}(this, function (moment) { + 'use strict'; + + /** + * feature detection and helper functions + */ + var hasMoment = typeof moment === 'function', + + hasEventListeners = !!window.addEventListener, + + document = window.document, + + sto = window.setTimeout, + + addEvent = function (el, e, callback, capture) { + if (hasEventListeners) { + el.addEventListener(e, callback, !!capture); + } else { + el.attachEvent('on' + e, callback); + } + }, + + removeEvent = function (el, e, callback, capture) { + if (hasEventListeners) { + el.removeEventListener(e, callback, !!capture); + } else { + el.detachEvent('on' + e, callback); + } + }, + + fireEvent = function (el, eventName, data) { + var ev; + + if (document.createEvent) { + ev = document.createEvent('HTMLEvents'); + ev.initEvent(eventName, true, false); + ev = extend(ev, data); + el.dispatchEvent(ev); + } else if (document.createEventObject) { + ev = document.createEventObject(); + ev = extend(ev, data); + el.fireEvent('on' + eventName, ev); + } + }, + + trim = function (str) { + return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, ''); + }, + + hasClass = function (el, cn) { + return (' ' + el.className + ' ').indexOf(' ' + cn + ' ') !== -1; + }, + + addClass = function (el, cn) { + if (!hasClass(el, cn)) { + el.className = (el.className === '') ? cn : el.className + ' ' + cn; + } + }, + + removeClass = function (el, cn) { + el.className = trim((' ' + el.className + ' ').replace(' ' + cn + ' ', ' ')); + }, + + isArray = function (obj) { + return (/Array/).test(Object.prototype.toString.call(obj)); + }, + + isDate = function (obj) { + return (/Date/).test(Object.prototype.toString.call(obj)) && !isNaN(obj.getTime()); + }, + + isLeapYear = function (year) { + // solution by Matti Virkkunen: http://stackoverflow.com/a/4881951 + return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0; + }, + + getDaysInMonth = function (year, month) { + return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; + }, + + setToStartOfDay = function (date) { + if (isDate(date)) date.setHours(0, 0, 0, 0); + }, + + compareDates = function (a, b) { + // weak date comparison (use setToStartOfDay(date) to ensure correct result) + return a.getTime() === b.getTime(); + }, + + extend = function (to, from, overwrite) { + var prop, hasProp; + for (prop in from) { + hasProp = to[prop] !== undefined; + if (hasProp && typeof from[prop] === 'object' && from[prop] !== null && from[prop].nodeName === undefined) { + if (isDate(from[prop])) { + if (overwrite) { + to[prop] = new Date(from[prop].getTime()); + } + } + else if (isArray(from[prop])) { + if (overwrite) { + to[prop] = from[prop].slice(0); + } + } else { + to[prop] = extend({}, from[prop], overwrite); + } + } else if (overwrite || !hasProp) { + to[prop] = from[prop]; + } + } + return to; + }, + + adjustCalendar = function (calendar) { + if (calendar.month < 0) { + calendar.year -= Math.ceil(Math.abs(calendar.month) / 12); + calendar.month += 12; + } + if (calendar.month > 11) { + calendar.year += Math.floor(Math.abs(calendar.month) / 12); + calendar.month -= 12; + } + return calendar; + }, + + /** + * defaults and localisation + */ + defaults = { + + // bind the picker to a form field + field: null, + + // automatically show/hide the picker on `field` focus (default `true` if `field` is set) + bound: undefined, + + // position of the datepicker, relative to the field (default to bottom & left) + // ('bottom' & 'left' keywords are not used, 'top' & 'right' are modifier on the bottom/left position) + position: 'bottom left', + + // automatically fit in the viewport even if it means repositioning from the position option + reposition: true, + + // the default output format for `.toString()` and `field` value + format: 'DD-MM-YYYY', + + // the initial date to view when first opened + defaultDate: null, + + // make the `defaultDate` the initial selected value + setDefaultDate: false, + + // first day of week (0: Sunday, 1: Monday etc) + firstDay: 0, + + // the minimum/earliest date that can be selected + minDate: null, + // the maximum/latest date that can be selected + maxDate: null, + + // number of years either side, or array of upper/lower range + yearRange: 10, + + // show week numbers at head of row + showWeekNumber: false, + + // used internally (don't config outside) + minYear: 0, + maxYear: 9999, + minMonth: undefined, + maxMonth: undefined, + + isRTL: false, + + // Additional text to append to the year in the calendar title + yearSuffix: '', + + // Render the month after year in the calendar title + showMonthAfterYear: false, + + // how many months are visible + numberOfMonths: 1, + + // when numberOfMonths is used, this will help you to choose where the main calendar will be (default `left`, can be set to `right`) + // only used for the first display or when a selected date is not visible + mainCalendar: 'left', + + // Specify a DOM element to render the calendar in + container: undefined, + + // internationalization + i18n: { + previousMonth: 'Mois précédent', + nextMonth: 'Mois suivant', + months: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'], + weekdays: ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'], + weekdaysShort: ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'] + }, + + // callback function + onSelect: null, + onOpen: null, + onClose: null, + onDraw: null + }, + + + /* Templating functions to abstract HTML rendering */ + renderDayName = function (opts, day, abbr) { + day += opts.firstDay; + while (day >= 7) { + day -= 7; + } + return abbr ? opts.i18n.weekdaysShort[day] : opts.i18n.weekdays[day]; + }, + + renderDay = function (d, m, y, isSelected, isToday, isDisabled, isEmpty) { + if (isEmpty) { + return ''; + } + var arr = []; + if (isDisabled) { + arr.push('is-disabled'); + } + if (isToday) { + arr.push('is-today'); + } + if (isSelected) { + arr.push('is-selected'); + } + return '' + + '' + + ''; + }, + + renderWeek = function (d, m, y) { + var onejan = new Date(y, 0, 1), + weekNum = Math.ceil((((new Date(y, m, d) - onejan) / 86400000) + onejan.getDay() + 1) / 7); + return '' + weekNum + ''; + }, + + renderRow = function (days, isRTL) { + return '' + (isRTL ? days.reverse() : days).join('') + ''; + }, + + renderBody = function (rows) { + return '' + rows.join('') + ''; + }, + + renderHead = function (opts) { + var i, arr = []; + if (opts.showWeekNumber) { + arr.push(''); + } + for (i = 0; i < 7; i++) { + arr.push('' + renderDayName(opts, i, true) + ''); + } + return '' + (opts.isRTL ? arr.reverse() : arr).join('') + ''; + }, + + renderTitle = function (instance, c, year, month, refYear) { + var i, j, arr, + opts = instance._o, + isMinYear = year === opts.minYear, + isMaxYear = year === opts.maxYear, + html = '
    ', + monthHtml, + yearHtml, + prev = true, + next = true; + + for (arr = [], i = 0; i < 12; i++) { + arr.push(''); + } + monthHtml = '
    ' + opts.i18n.months[month] + '
    '; + + if (isArray(opts.yearRange)) { + i = opts.yearRange[0]; + j = opts.yearRange[1] + 1; + } else { + i = year - opts.yearRange; + j = 1 + year + opts.yearRange; + } + + for (arr = []; i < j && i <= opts.maxYear; i++) { + if (i >= opts.minYear) { + arr.push(''); + } + } + yearHtml = '
    ' + year + opts.yearSuffix + '
    '; + + if (opts.showMonthAfterYear) { + html += yearHtml + monthHtml; + } else { + html += monthHtml + yearHtml; + } + + if (isMinYear && (month === 0 || opts.minMonth >= month)) { + prev = false; + } + + if (isMaxYear && (month === 11 || opts.maxMonth <= month)) { + next = false; + } + + if (c === 0) { + html += ''; + } + if (c === (instance._o.numberOfMonths - 1)) { + html += ''; + } + + return html += '
    '; + }, + + renderTable = function (opts, data) { + return '' + renderHead(opts) + renderBody(data) + '
    '; + }, + + + /* Pikaday constructor */ + Pikaday = function (options) { + var self = this, + opts = self.config(options); + + self._onMouseDown = function (e) { + if (!self._v) { + return; + } + e = e || window.event; + var target = e.target || e.srcElement; + if (!target) { + return; + } + + if (!hasClass(target, 'is-disabled')) { + if (hasClass(target, 'pika-button') && !hasClass(target, 'is-empty')) { + self.setDate(new Date(target.getAttribute('data-pika-year'), target.getAttribute('data-pika-month'), target.getAttribute('data-pika-day'))); + if (opts.bound) { + sto(function () { + self.hide(); + if (opts.field) { + opts.field.blur(); + } + }, 100); + } + return; + } + else if (hasClass(target, 'pika-prev')) { + self.prevMonth(); + } + else if (hasClass(target, 'pika-next')) { + self.nextMonth(); + } + } + if (!hasClass(target, 'pika-select')) { + if (e.preventDefault) { + e.preventDefault(); + } else { + e.returnValue = false; + return false; + } + } else { + self._c = true; + } + }; + + self._onChange = function (e) { + e = e || window.event; + var target = e.target || e.srcElement; + if (!target) { + return; + } + if (hasClass(target, 'pika-select-month')) { + self.gotoMonth(target.value); + } + else if (hasClass(target, 'pika-select-year')) { + self.gotoYear(target.value); + } + }; + + self._onInputChange = function (e) { + var date; + + if (e.firedBy === self) { + return; + } + if (hasMoment) { + date = moment(opts.field.value, opts.format); + date = (date && date.isValid()) ? date.toDate() : null; + } + else { + date = new Date(Date.parse(opts.field.value)); + } + self.setDate(isDate(date) ? date : null); + if (!self._v) { + self.show(); + } + }; + + self._onInputFocus = function () { + self.show(); + }; + + self._onInputClick = function () { + self.show(); + }; + + self._onInputBlur = function () { + if (!self._c) { + self._b = sto(function () { + self.hide(); + }, 50); + } + self._c = false; + }; + + self._onClick = function (e) { + e = e || window.event; + var target = e.target || e.srcElement, + pEl = target; + if (!target) { + return; + } + if (!hasEventListeners && hasClass(target, 'pika-select')) { + if (!target.onchange) { + target.setAttribute('onchange', 'return;'); + addEvent(target, 'change', self._onChange); + } + } + do { + if (pEl === opts.trigger) { + return; + } + } + while ((pEl = pEl.parentNode)); + if (self._v && pEl !== opts.trigger) { + //self.hide(); + } + }; + + self.el = document.createElement('div'); + self.el.className = 'pika-single' + (opts.isRTL ? ' is-rtl' : ''); + + addEvent(self.el, 'mousedown', self._onMouseDown, true); + addEvent(self.el, 'change', self._onChange); + + if (opts.field) { + if (opts.container) { + opts.container.appendChild(self.el); + } else if (opts.bound) { + document.body.appendChild(self.el); + } else { + opts.field.parentNode.insertBefore(self.el, opts.field.nextSibling); + } + addEvent(opts.field, 'change', self._onInputChange); + + if (!opts.defaultDate) { + if (hasMoment && opts.field.value) { + opts.defaultDate = moment(opts.field.value, opts.format).toDate(); + } else { + opts.defaultDate = new Date(Date.parse(opts.field.value)); + } + opts.setDefaultDate = true; + } + } + + var defDate = opts.defaultDate; + + if (isDate(defDate)) { + if (opts.setDefaultDate) { + self.setDate(defDate, true); + } else { + self.gotoDate(defDate); + } + } else { + self.gotoDate(new Date()); + } + + if (opts.bound) { + this.hide(); + self.el.className += ' is-bound'; + addEvent(opts.trigger, 'click', self._onInputClick); + addEvent(opts.trigger, 'focus', self._onInputFocus); + addEvent(opts.trigger, 'blur', self._onInputBlur); + } else { + this.show(); + } + }; + + Pikaday.prototype = { + + + /* Configure functionality */ + config: function (options) { + if (!this._o) { + this._o = extend({}, defaults, true); + } + + var opts = extend(this._o, options, true); + + opts.isRTL = !!opts.isRTL; + + opts.field = (opts.field && opts.field.nodeName) ? opts.field : null; + + opts.bound = !!(opts.bound !== undefined ? opts.field && opts.bound : opts.field); + + opts.trigger = (opts.trigger && opts.trigger.nodeName) ? opts.trigger : opts.field; + + var nom = parseInt(opts.numberOfMonths, 10) || 1; + opts.numberOfMonths = nom > 4 ? 4 : nom; + + if (!isDate(opts.minDate)) { + opts.minDate = false; + } + if (!isDate(opts.maxDate)) { + opts.maxDate = false; + } + if ((opts.minDate && opts.maxDate) && opts.maxDate < opts.minDate) { + opts.maxDate = opts.minDate = false; + } + if (opts.minDate) { + setToStartOfDay(opts.minDate); + opts.minYear = opts.minDate.getFullYear(); + opts.minMonth = opts.minDate.getMonth(); + } + if (opts.maxDate) { + setToStartOfDay(opts.maxDate); + opts.maxYear = opts.maxDate.getFullYear(); + opts.maxMonth = opts.maxDate.getMonth(); + } + + if (isArray(opts.yearRange)) { + var fallback = new Date().getFullYear() - 10; + opts.yearRange[0] = parseInt(opts.yearRange[0], 10) || fallback; + opts.yearRange[1] = parseInt(opts.yearRange[1], 10) || fallback; + } else { + opts.yearRange = Math.abs(parseInt(opts.yearRange, 10)) || defaults.yearRange; + if (opts.yearRange > 100) { + opts.yearRange = 100; + } + } + + return opts; + }, + + /* Return a formatted string of the current selection (using Moment.js if available) */ + toString: function (format) { + return !isDate(this._d) ? '' : hasMoment ? moment(this._d).format(format || this._o.format) : this._d.toDateString(); + }, + + /* Return a Moment.js object of the current selection (if available) */ + getMoment: function () { + return hasMoment ? moment(this._d) : null; + }, + + /* Set the current selection from a Moment.js object (if available) */ + setMoment: function (date, preventOnSelect) { + if (hasMoment && moment.isMoment(date)) { + this.setDate(date.toDate(), preventOnSelect); + } + }, + + /* Return a Date object of the current selection */ + getDate: function () { + return isDate(this._d) ? new Date(this._d.getTime()) : null; + }, + + /* Set the current selection */ + setDate: function (date, preventOnSelect) { + if (!date) { + this._d = null; + + if (this._o.field) { + this._o.field.value = ''; + fireEvent(this._o.field, 'change', {firedBy: this}); + } + + return this.draw(); + } + if (typeof date === 'string') { + date = new Date(Date.parse(date)); + } + if (!isDate(date)) { + return; + } + + var min = this._o.minDate, + max = this._o.maxDate; + + if (isDate(min) && date < min) { + date = min; + } else if (isDate(max) && date > max) { + date = max; + } + + this._d = new Date(date.getTime()); + setToStartOfDay(this._d); + this.gotoDate(this._d); + + if (this._o.field) { + this._o.field.value = this.toString(); + fireEvent(this._o.field, 'change', {firedBy: this}); + } + if (!preventOnSelect && typeof this._o.onSelect === 'function') { + this._o.onSelect.call(this, this.getDate()); + } + }, + + /* Change view to a specific date */ + gotoDate: function (date) { + var newCalendar = true; + + if (!isDate(date)) { + return; + } + + if (this.calendars) { + var firstVisibleDate = new Date(this.calendars[0].year, this.calendars[0].month, 1), + lastVisibleDate = new Date(this.calendars[this.calendars.length - 1].year, this.calendars[this.calendars.length - 1].month, 1), + visibleDate = date.getTime(); + // get the end of the month + lastVisibleDate.setMonth(lastVisibleDate.getMonth() + 1); + lastVisibleDate.setDate(lastVisibleDate.getDate() - 1); + newCalendar = (visibleDate < firstVisibleDate.getTime() || lastVisibleDate.getTime() < visibleDate); + } + + if (newCalendar) { + this.calendars = [{ + month: date.getMonth(), + year: date.getFullYear() + }]; + if (this._o.mainCalendar === 'right') { + this.calendars[0].month += 1 - this._o.numberOfMonths; + } + } + + this.adjustCalendars(); + }, + + adjustCalendars: function () { + this.calendars[0] = adjustCalendar(this.calendars[0]); + for (var c = 1; c < this._o.numberOfMonths; c++) { + this.calendars[c] = adjustCalendar({ + month: this.calendars[0].month + c, + year: this.calendars[0].year + }); + } + this.draw(); + }, + + gotoToday: function () { + this.gotoDate(new Date()); + }, + + /* Change view to a specific month (zero-index, e.g. 0: January) */ + gotoMonth: function (month) { + if (!isNaN(month)) { + this.calendars[0].month = parseInt(month, 10); + this.adjustCalendars(); + } + }, + + nextMonth: function () { + this.calendars[0].month++; + this.adjustCalendars(); + }, + + prevMonth: function () { + this.calendars[0].month--; + this.adjustCalendars(); + }, + + /* Change view to a specific full year (e.g. "2012") */ + gotoYear: function (year) { + if (!isNaN(year)) { + this.calendars[0].year = parseInt(year, 10); + this.adjustCalendars(); + } + }, + + /* Change the minDate */ + setMinDate: function (value) { + this._o.minDate = value; + }, + + /* Change the maxDate */ + setMaxDate: function (value) { + this._o.maxDate = value; + }, + + /* Refresh the HTML */ + draw: function (force) { + if (!this._v && !force) { + return; + } + var opts = this._o, + minYear = opts.minYear, + maxYear = opts.maxYear, + minMonth = opts.minMonth, + maxMonth = opts.maxMonth, + html = ''; + + if (this._y <= minYear) { + this._y = minYear; + if (!isNaN(minMonth) && this._m < minMonth) { + this._m = minMonth; + } + } + if (this._y >= maxYear) { + this._y = maxYear; + if (!isNaN(maxMonth) && this._m > maxMonth) { + this._m = maxMonth; + } + } + + for (var c = 0; c < opts.numberOfMonths; c++) { + html += '
    ' + renderTitle(this, c, this.calendars[c].year, this.calendars[c].month, this.calendars[0].year) + this.render(this.calendars[c].year, this.calendars[c].month) + '
    '; + } + + this.el.innerHTML = html; + + if (opts.bound) { + if (opts.field.type !== 'hidden') { + sto(function () { + opts.trigger.focus(); + }, 1); + } + } + + if (typeof this._o.onDraw === 'function') { + var self = this; + sto(function () { + self._o.onDraw.call(self); + }, 0); + } + }, + + adjustPosition: function () { + if (this._o.container) return; + var field = this._o.trigger, pEl = field, + width = this.el.offsetWidth, height = this.el.offsetHeight, + viewportWidth = window.innerWidth || document.documentElement.clientWidth, + viewportHeight = window.innerHeight || document.documentElement.clientHeight, + scrollTop = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop, + left, top, clientRect; + + if (typeof field.getBoundingClientRect === 'function') { + clientRect = field.getBoundingClientRect(); + left = clientRect.left + window.pageXOffset; + top = clientRect.bottom + window.pageYOffset; + } else { + left = pEl.offsetLeft; + top = pEl.offsetTop + pEl.offsetHeight; + while ((pEl = pEl.offsetParent)) { + left += pEl.offsetLeft; + top += pEl.offsetTop; + } + } + + /* Default position is bottom & left */ + if ((this._o.reposition && left + width > viewportWidth) || + ( + this._o.position.indexOf('right') > -1 && + left - width + field.offsetWidth > 0 + ) + ) { + left = left - width + field.offsetWidth; + } + if ((this._o.reposition && top + height > viewportHeight + scrollTop) || + ( + this._o.position.indexOf('top') > -1 && + top - height - field.offsetHeight > 0 + ) + ) { + top = top - height - field.offsetHeight; + } + + this.el.style.cssText = [ + 'position: absolute', + 'left: ' + left + 'px', + 'top: ' + top + 'px' + ].join(';'); + }, + + /* Render HTML for a particular month */ + render: function (year, month) { + var opts = this._o, + now = new Date(), + days = getDaysInMonth(year, month), + before = new Date(year, month, 1).getDay(), + data = [], + row = []; + setToStartOfDay(now); + if (opts.firstDay > 0) { + before -= opts.firstDay; + if (before < 0) { + before += 7; + } + } + var cells = days + before, + after = cells; + while (after > 7) { + after -= 7; + } + cells += 7 - after; + for (var i = 0, r = 0; i < cells; i++) { + var day = new Date(year, month, 1 + (i - before)), + isDisabled = (opts.minDate && day < opts.minDate) || (opts.maxDate && day > opts.maxDate), + isSelected = isDate(this._d) ? compareDates(day, this._d) : false, + isToday = compareDates(day, now), + isEmpty = i < before || i >= (days + before); + + row.push(renderDay(1 + (i - before), month, year, isSelected, isToday, isDisabled, isEmpty)); + + if (++r === 7) { + if (opts.showWeekNumber) { + row.unshift(renderWeek(i - before, month, year)); + } + data.push(renderRow(row, opts.isRTL)); + row = []; + r = 0; + } + } + return renderTable(opts, data); + }, + + isVisible: function () { + return this._v; + }, + + show: function () { + if (!this._v) { + removeClass(this.el, 'is-hidden'); + this._v = true; + this.draw(); + if (this._o.bound) { + addEvent(document, 'click', this._onClick); + this.adjustPosition(); + } + if (typeof this._o.onOpen === 'function') { + this._o.onOpen.call(this); + } + } + }, + + hide: function () { + var v = this._v; + if (v !== false) { + if (this._o.bound) { + removeEvent(document, 'click', this._onClick); + } + this.el.style.cssText = ''; + addClass(this.el, 'is-hidden'); + this._v = false; + if (v !== undefined && typeof this._o.onClose === 'function') { + this._o.onClose.call(this); + } + } + }, + + destroy: function () { + this.hide(); + removeEvent(this.el, 'mousedown', this._onMouseDown, true); + removeEvent(this.el, 'change', this._onChange); + if (this._o.field) { + removeEvent(this._o.field, 'change', this._onInputChange); + if (this._o.bound) { + removeEvent(this._o.trigger, 'click', this._onInputClick); + removeEvent(this._o.trigger, 'focus', this._onInputFocus); + removeEvent(this._o.trigger, 'blur', this._onInputBlur); + } + } + if (this.el.parentNode) { + this.el.parentNode.removeChild(this.el); + } + } + + }; + + return Pikaday; + +})); diff --git a/kurt-web/src/main/webapp/js/post_form.js b/kurt-web/src/main/webapp/js/post_form.js new file mode 100644 index 0000000..8bf9214 --- /dev/null +++ b/kurt-web/src/main/webapp/js/post_form.js @@ -0,0 +1,60 @@ +/** + * Tool for sending an AJAX request with a POST form. Be careful: the callback function called + * "ServerResponseForPostForm" should be defined in your page. + */ + +/* Declaration de l'objet HttpRequest global */ +var objPostRequest = null; + +/* Retourne la liste des éléments HTML composant un formulaire */ +function getFormData(id) { + var formEl = ''; + var LMR = ''; + var obF = document.getElementById(id); + var elements = obF.elements; + for (var i = 0; i < obF.length; i++) { + /* LMR is for R20 report */ + if (elements[i].name === 'LMR') { + if (elements[i].value == "") + continue; + if (LMR == '') { + LMR += elements[i].name + '=' + escape(elements[i].value); + } else { + LMR += ";" + escape(elements[i].value); + } + } else if (elements[i].name + "" != "") { + /* For check-boxes and radio button only take into account of checked values */ + if ((elements[i].type === 'radio') || (elements[i].type === 'checkbox')) { + if (!elements[i].checked) { + continue; + } + } + if (formEl != '') { + formEl += "&"; + } + formEl += elements[i].name + '=' + escape(elements[i].value); + } + } + if (LMR != '') { + formEl += "&" + LMR; + } + return formEl; +} + +/* Méthode d'envoi via POST d'un formulaire */ +function PostForm(url, form) { + /* Lecture des données du formulaire */ + var data = getFormData(form); + /* Détection du navigateur pour la création de l'objet XMLHttpRequest */ + if (window.XMLHttpRequest) + objPostRequest = new XMLHttpRequest(); + else if (window.ActiveXObject) + objPostRequest = new ActiveXObject("Microsoft.XMLHTTP"); + + /* Envoi du formulaire en AJAX */ + objPostRequest.open('post', url, true); + objPostRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + objPostRequest.setRequestHeader("Content-length", data.length); + objPostRequest.onreadystatechange = ServerResponseForPostForm; + objPostRequest.send(data); +} diff --git a/kurt-web/src/main/webapp/js/queue.js b/kurt-web/src/main/webapp/js/queue.js new file mode 100644 index 0000000..d6ed80e --- /dev/null +++ b/kurt-web/src/main/webapp/js/queue.js @@ -0,0 +1,83 @@ +/* Main table for all priorities */ +function DisplayTable() { + + var tableContent = ''; + + tableContent += '
    '; + tableContent += DisplayTableByPriority("Priorité haute", 1); + tableContent += ''; + + tableContent += DisplayTableByPriority("Priorité moyenne", 2); + tableContent += ''; + + tableContent += DisplayTableByPriority("Priorité basse", 3); + tableContent += ''; + + tableContent += DisplayTableByPriority("Différé", 0); + + tableContent += ''; + + tableContent += DisplayTableRunningReport("Planifié"); + tableContent += '
    '; + + document.write(tableContent); +} + +/* Sub table for each scheduling report */ +function DisplayTableRunningReport(name) { + var tableContent = getSubTableHeaderScheduling(name); + + /* Browse each report */ + var reportCount = schedulingReportArray.length; + for (var i = 0; i < reportCount; i++) { + var currentReport = schedulingReportArray[i]; + /* Display columns of the current report */ + tableContent += ''; + tableContent += '' + currentReport['reportCode'] + ''; + tableContent += '' + currentReport['name'] + ''; + tableContent += ''; + } + tableContent += ''; + return tableContent; +} + +function getSubTableHeaderScheduling(aPriorityName) { + var content = '
    ' + + aPriorityName + '
    '; + content += ''; + return content; +} + +/* Sub table for each priority */ +function DisplayTableByPriority(aPriorityName, aPriority) { + var tableContent = getSubTableHeader(aPriorityName); + + // Browse each report + var reportCount = reportArray.length; + for (var i = 0; i < reportCount; i++) { + var currentReport = reportArray[i]; + if (aPriority == '0') { + // Special case of deferred + if (currentReport['state'] != 'WAIT') { + continue; + } + } else if (currentReport['priority'] != aPriority) { + // Check priority value compliance + continue; + } + // Display columns of the current report + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + } + tableContent += '
    RapportNom planification
    ' + currentReport['reportCode'] + '' + currentReport['login'] + '
    '; + return tableContent; +} + +function getSubTableHeader(aPriorityName) { + var content = '
    ' + + aPriorityName + '
    '; + content += ''; + return content; +} \ No newline at end of file diff --git a/kurt-web/src/main/webapp/js/running_reports.js b/kurt-web/src/main/webapp/js/running_reports.js new file mode 100644 index 0000000..1cb00ba --- /dev/null +++ b/kurt-web/src/main/webapp/js/running_reports.js @@ -0,0 +1,49 @@ +function DisplayTable() { + var tableContent = ''; + // Browse each report + var reportCount = reportArray.length; + for (var i = 0; i < reportCount; i++) { + var currentReport = reportArray[i]; + + // Prepare error column content + var currentError = currentReport['errorMessage']; + if (currentError != '') { + currentError = ''; + } + + // Prepare status column content + var currentStatus = currentReport['state']; + if (currentStatus != '') { + currentStatus = ''; + } + + // Report priority + var priority = "Inconnue"; + if (currentReport['priority'] === '1') { + priority = "Haute"; + } else if (currentReport['priority'] === '2') { + priority = "Moyenne"; + } else if (currentReport['priority'] === '3') { + priority = "Basse"; + } + + /* Display columns of the current report */ + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + } + + document.write(tableContent); +} diff --git a/kurt-web/src/main/webapp/js/schedulingReport.js b/kurt-web/src/main/webapp/js/schedulingReport.js new file mode 100644 index 0000000..37176f4 --- /dev/null +++ b/kurt-web/src/main/webapp/js/schedulingReport.js @@ -0,0 +1,412 @@ +function DisplayTable() { + var tableContent = ''; + // Browse each report + var reportCount = reportArray.length; + + for (var i = 0; i < reportCount; i++) { + var currentReport = reportArray[i]; + + // Display columns of the current report + tableContent += '\n'; + tableContent += ' \n'; + tableContent += ' \n'; + tableContent += ' \n'; + tableContent += ' \n'; + tableContent += ' \n'; + tableContent += ' \n'; + // begin columns containing the buttons + // ->infos (magnifying glass) + tableContent += ' \n'; + + // ->update planification page + tableContent += ' \n'; + + // ->delete current planification + tableContent += ' \n'; + + tableContent += ''; + } + + document.write(tableContent); +} + +/* Redirect to page */ +function GoSchedulingPage(i, j) { + document.location.href = '/kurt-web/schedulingReader?page=' + i + "&reportCode=" + j; +} + +/* build select active or not active report */ +function displaySelectActivateDesactivateReport() { + if ('TOUS' === activeReportCode) { + document.getElementById('authorizedLabel').style.visibility = "hidden"; + document.getElementById('authorizedTd').style.visibility = "hidden"; + } else { + document.getElementById('authorizedLabel').style.visibility = "visible"; + document.getElementById('authorizedTd').style.visibility = "visible"; + var selectContentIsActiveReport = ''; + document.write(selectContentIsActiveReport); + } +} + +/* Redirect to page 1 */ +function getReport(i) { + document.location.href = '/kurt-web/schedulingReader?reportCode=' + i; +} + +/* get current value on select */ +function getSelectedValue(idElem) { + var e = document.getElementById(idElem); + var strUser = e.options[e.selectedIndex].value; + return strUser; +} + +/* persistence on select activate or enabled scheduling report */ +function saveAction() { + var curReportCode = "reportCode=" + activeReportCode; + var valueOfSelect = "reportAuthorized=" + getSelectedValue("selectEnableDisable"); + var data = curReportCode + "&" + valueOfSelect; + + // Detection du navigateur pour la creation de l'objet XMLHttpRequest + if (window.XMLHttpRequest) { + objPostRequest = new XMLHttpRequest(); + } else if (window.ActiveXObject) { + objPostRequest = new ActiveXObject("Microsoft.XMLHTTP"); + } + + // Envoi du formulaire en AJAX + objPostRequest.open('post', "/kurt-web/activateDeactivate", true); + objPostRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + objPostRequest.send(data); + objPostRequest.onreadystatechange = ServerResponseForSaveActionConfirmation; +} + +/* Popup after click button save to enabled or disabled report */ +function ServerResponseForSaveActionConfirmation() { + if (objPostRequest.readyState === 4) { + if (objPostRequest.status === 200) { + var queryResponse = JSON.parse(objPostRequest.responseText); + if (queryResponse.status === "success") { + parent.Dialog("Confirmation", queryResponse.success); + } else { + parent.Dialog("Erreur", queryResponse.error); + } + } + } +} + +/* */ +function refreshSchedulingPage(i) { + parent.hideDialog(); + top.frames['subFrame'].location.href = '/kurt-web/schedulingReader?reportCode=' + i; +} + +/* Hidden or show button new when user select value "TOUS" */ +function showHideButtonNewPlanification() { + var selectBox = document.getElementById("selectReportType"); + var selectedValue = selectBox.options[selectBox.selectedIndex].value; + getReport(selectedValue); +} + +function updateSchedulingReport(id, reportCode) { + return callSchedulingReport("update", id, reportCode); +} + +function newSchedulingReport() { + return callSchedulingReport("create", "", ""); +} + +function callSchedulingReport(status, id, reportCode) { + + var reportCodeActive = ""; + // reportCode = reportCode.replace("R", ""); + reportCodeActive = activeReportCode.replace("R", ""); + if (status === "create") { + var theReportCode = activeReportCode; + document.location.href = '/kurt-web/frames/scheduling_new.jsp?activeSchedulingList=' + reportCodeActive + + '&reportCode=' + theReportCode; + } else { + document.location.href = '/kurt-web/frames/scheduling_update.jsp?activeSchedulingList=' + reportCodeActive + + '&id=' + id + '&reportCode=' + reportCode; + } +} + +function getSubPeriod(name, id, isActive) { + // Detection du navigateur pour la creation de l'objet XMLHttpRequest + if (window.XMLHttpRequest) { + objPostRequest = new XMLHttpRequest(); + } else if (window.ActiveXObject) { + objPostRequest = new ActiveXObject("Microsoft.XMLHTTP"); + } + var concat = "&"; + var subPeriodData = 'subPeriod=' + encodeURIComponent(name); + var isUpdate = 'isUpdate=' + encodeURIComponent(isActive); + var idData = 'id=' + encodeURIComponent(id); + + // Envoi du formulaire en AJAX + objPostRequest.open('post', "/kurt-web/getScheduling", true); + objPostRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + objPostRequest.send(subPeriodData + concat + isUpdate + concat + idData); + objPostRequest.onreadystatechange = ServerResponseForGetSubPeriod; +} + +function createDiv(content) { + + var container = document.createElement('div'); + container.id = "div_temp"; + container.innerHTML = content; + + return container; +} + +// div_container_sub_period +function ServerResponseForGetSubPeriod() { + if (objPostRequest.readyState == 4) { + if (objPostRequest.status == 200) { + var queryResponse = JSON.parse(objPostRequest.responseText); + + var containerSubPeriod = document.getElementById("div_container_subPeriod"); + containerSubPeriod.innerHTML = ""; + + if (queryResponse.status == "success") { + containerSubPeriod.innerHTML = queryResponse.content; + initPicker('datepicker_planification', 'container_planification'); + } else { + containerSubPeriod.innerHTML = "Oh oh ......"; // FIXME + } + } else if (objPostRequest.status === 500) { + document.getElementById("div_container_subPeriod").innerHTML = "Erreur interne du serveur détectée. "; + + } else { + document.getElementById("div_container_subPeriod").innerHTML = "La connexion avec le site semble interrompue."; + + } + + } +} + +// Methode d'envoi via POST d'un formulaire +function deleteCommand(schedulingReportId) { + // active progress bar + showProgressBarOnDelete(); + // Detection du navigateur pour la creation de l'objet XMLHttpRequest + if (window.XMLHttpRequest) + objPostRequest = new XMLHttpRequest(); + else if (window.ActiveXObject) + objPostRequest = new ActiveXObject("Microsoft.XMLHTTP"); + var data = 'scheduling_report_id=' + encodeURIComponent(schedulingReportId); + // Envoi du formulaire en AJAX + objPostRequest.open('post', "/kurt-web/scheduling/delete", true); + objPostRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + objPostRequest.send(data); + objPostRequest.onreadystatechange = ServerResponseForDeleteCommand; +} + +/* Callback on delete */ +function ServerResponseForDeleteCommand() { + if (objPostRequest.readyState == 4) { + if (objPostRequest.status == 200) { + var queryResponse = JSON.parse(objPostRequest.responseText); + document.getElementById("div_message").innerHTML = ""; + if (queryResponse.status == "success") { + document.getElementById("div_message").innerHTML = queryResponse.success; + } else { + document.getElementById("div_message").innerHTML = queryResponse.failed; + } + // add button to close popup + document.getElementById("div_buttons").innerHTML = ""; + document.getElementById("div_buttons").innerHTML = addButtonClose(); + } else { + document.getElementById("div_message").innerHTML = "Erreur interne du serveur détectée. "; + document.getElementById("div_buttons").innerHTML = ""; + document.getElementById("div_buttons").innerHTML = addButtonClose(); + } + } +} + +/* Use on delete */ +function showProgressBarOnDelete() { + document.getElementById("div_message").innerHTML = progressBar(); + document.getElementById("div_buttons").innerHTML = ""; +} + +/* Build a progress bar */ +function progressBar() { + return "Traitement en cours..." + "
    " + + ""; +} + +/* build a close button */ +function addButtonClose() { + return ""; +} + +/* */ +function sendSchedulingReport(targetUrl, optionalParameters) { + /* call check of current report and call check of scheduling */ + + var isFormOK = checkForm(); + var isSchedulingOK = checkParamScheduling(); + if (isFormOK && isSchedulingOK) { + // PostForm(targetUrl,"reportSchedulingForm"); + /* Display loading bar and hide buttons */ + document.getElementById("loading").style.display = ''; + document.getElementById("div_buttons").style.display = 'none'; + postScheduling(targetUrl, "reportSchedulingForm", optionalParameters); + } + +} + +function postScheduling(url, form, optionalParameters) { + /* Lecure des donnees du formulaire */ + var data = getFormData(form); + data += optionalParameters; + /* Detection du navigateur pour la creation de l'objet XMLHttpRequest */ + if (window.XMLHttpRequest) { + objPostRequest = new XMLHttpRequest(); + } else if (window.ActiveXObject) { + objPostRequest = new ActiveXObject("Microsoft.XMLHTTP"); + } + + /* Envoi du formulaire en AJAX */ + objPostRequest.open('post', url, true); + objPostRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + // objPostRequest.setRequestHeader("Content-length", data.length); // Unsafe! + objPostRequest.onreadystatechange = serverResponseForPostScheduling; + objPostRequest.send(data); +} + +function serverResponseForPostScheduling() { + if (objPostRequest.readyState == 4) { + if (objPostRequest.status == 200) { + var queryResponse = JSON.parse(objPostRequest.responseText); + if (queryResponse.status == "success") { + parent.Dialog("Confirmation", queryResponse.success); + } else { + parent.Dialog("Erreur", queryResponse.error); + } + } else if (objPostRequest.status == 500) { + parent.Dialog("Erreur", "Erreur interne du serveur détectée."); + } else { + parent.Dialog("Erreur", "La connexion avec le site semble interrompue."); + } + // Display buttons and hide loading bar + document.getElementById("loading").style.display = 'none'; + document.getElementById("div_buttons").style.display = ''; + } +} + +/* check input button text of radio_all_month_day */ +function checkIsValidDay() { + return isValidDay("dayInMonthValue"); +} + +/* check input in field day in month */ +function isValidDay(inputText) { + var element = document.getElementById(inputText); + var isGood = true; + if (isNaN(element.value) || element.value == "" || element.value < 1 || element.value > 31) { + isGood = false; + } + return isGood; +} + +/* Check fields of planification */ +function checkParamScheduling() { + var maxCharacter = 40; + if (!checkMaxLenghtOnInputText("scheduling_name", maxCharacter)) { + parent.Dialog("Erreur", "Le champ Nom ne peut pas contenir plus de " + maxCharacter + " caractères."); + return false; + } + if (!checkInputAlphanumeric("scheduling_name")) { + parent.Dialog("Erreur", "Le champ Nom ne peut contenir que des caractères alphanumériques."); + return false; + } + /* Filed may not be empty */ + if (isEmptyFieldMaybeMandatory("scheduling_name", false)) { + document.getElementById("scheduling_name").focus(); + parent.Dialog("Erreur", "Saisir un nom pour la planification."); + return false; + } + if (!checkInputRadioDayOfMonth()) { + document.getElementById("scheduling_name").focus(); + parent + .Dialog("Erreur", + "Vous avez choisi une planification par mois, le champ ne doit pas etre vide ou comporter un jour entre 1 et 31."); + return false; + } + if (!checkInputRadioByDate()) { + document.getElementById("scheduling_name").focus(); + parent.Dialog("Erreur", "Vous avez choisi une planification par date, le champ ne doit pas etre vide."); + return false; + } + return true; +} + +/* Check by month */ +function checkInputRadioDayOfMonth() { + var returnValue = true; + if ((document.getElementById('div_period_monthly').checked) && (document.getElementById('dayInMonthValue').checked)) { // A + // day + // in + // month + // is + // selected + // --> field day in month may not be empty and between 1-31 day of month + returnValue = checkIsValidDay(); + } + return returnValue; +} + +/* Check by date */ +function checkInputRadioByDate() { + var returnValue = true; + // radio date + if (document.getElementById('div_period_date').checked) { + if (document.getElementById('datepicker_planification').value === "") { + returnValue = false; + } + } + return returnValue; +} + +/* Check max length on input text */ +function checkMaxLenghtOnInputText(idOfInput, max) { + var element = document.getElementById(idOfInput); + var returnValue = true; + if (element.value.length > max) { + returnValue = false; + } + return returnValue; +} + +/* Regex Authorized -> alaphanumeric[a-zA-Z0-9_], -, éèçà, whitespace and start min:0 to max:40 car */ +function checkInputAlphanumeric(idOfInput) { + var text = document.getElementById(idOfInput).value; + // var check = new RegExp("^([a-zA-Z0-9_-\\s]{0,40})$", "g"); + var check = /^([\w- éèçà]{0,40})$/; + return check.test(text); +} diff --git a/kurt-web/src/main/webapp/js/schedulingReportsCreaUpd.js b/kurt-web/src/main/webapp/js/schedulingReportsCreaUpd.js new file mode 100644 index 0000000..32fe7c9 --- /dev/null +++ b/kurt-web/src/main/webapp/js/schedulingReportsCreaUpd.js @@ -0,0 +1,42 @@ +/////////////----------SCRIPT NEW/UPDATE PLANIFICATION REPORT + +/* cleaning input text day in month */ +function cleaningFieldDayInMonth(isCleaning) { + if (isCleaning == "true") { + document.getElementById("dayInMonthValue").value = ""; + } +} + +/* use if when define period */ +function showSubPeriod(valueOfPeriod) { + showElements(valueOfPeriod); +} + +/* Active or not boc depend value */ +function showElements(myValue) { + + if (myValue === "daily") { + // on fait rien + document.getElementById("bloc_weekly").style.display = "none"; + document.getElementById("bloc_monthly").style.display = "none"; + document.getElementById("bloc_by_date").style.display = "none"; + } else if (myValue === "weekly") { + // active div bloc_weekly + document.getElementById("bloc_weekly").style.display = ""; + document.getElementById("bloc_monthly").style.display = "none"; + document.getElementById("bloc_by_date").style.display = "none"; + + } else if (myValue === "monthly") { + // active bloc_monthly + document.getElementById("bloc_monthly").style.display = ""; + document.getElementById("bloc_weekly").style.display = "none"; + document.getElementById("bloc_by_date").style.display = "none"; + + } else if (myValue === "date") { + // active bloc_by_date + document.getElementById("bloc_by_date").style.display = ""; + /* document.getElementById("bloc_by_date").style.visibility="visible"; */ + document.getElementById("bloc_weekly").style.display = "none"; + document.getElementById("bloc_monthly").style.display = "none"; + } +} diff --git a/kurt-web/src/main/webapp/js/statistics.js b/kurt-web/src/main/webapp/js/statistics.js new file mode 100644 index 0000000..3c8b2ce --- /dev/null +++ b/kurt-web/src/main/webapp/js/statistics.js @@ -0,0 +1,109 @@ +/* First table displaying statistics per report */ +function DisplayTablePerReport() { + var tableContent = ''; + // Browse each report + var reportCount = reportStatArray.length; + for (var i = 0; i < reportCount; i++) { // Display columns of the current report + var currentReport = reportStatArray[i]; + // Color first line for a new month + if (isColorLine(i)) { + tableContent += ''; + } else { + tableContent += ''; + } + + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + } + document.write(tableContent); +} + +// Every [nbReports] line, return true/ Warning, [nbReports] must exist as a global js variable +function isColorLine(i) { + if (i == 0) { + return false; + } else { + return i % nbReports === 0 + } +} + +/* Second table displaying statistics per user */ +function DisplayTablePerUser() { + var tableContent = ''; + // Browse each report + var reportUserCount = userStatArray.length; + for (var i = 0; i < reportUserCount; i++) { + var stat = userStatArray[i]; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + tableContent += ''; + } + document.write(tableContent); +} + +function downloadTable(tableNum) { + var startPeriod = document.getElementById("startPeriod").value; + var endPeriod = document.getElementById("endPeriod").value; + var url = "/kurt-web/downloadStats" + tableNum + "?startPeriod=" + startPeriod + "&endPeriod=" + endPeriod; + window.open(url); +} + +/* Callback method after AJAX request */ +function ServerResponseForPostForm() { + if (objPostRequest.readyState === 4) { + if (objPostRequest.status === 200) { + parent.Dialog("Success", "Fichier généré"); + } else if (objPostRequest.status === 500) { + parent.Dialog("Erreur", "Erreur interne du serveur détectée."); + } else { + parent.Dialog("Erreur", "La connexion avec le site semble interrompue."); + } + } +} + +/* Extract the value of a GET parameter set in the URL */ +function parseURL(val, defaultVal) { + var result = defaultVal; + var urlParam = window.location.search; + if (urlParam != '') { + paramArray = urlParam.substr(1).split("&"); + for (var i = 0; i < paramArray.length; i++) { + var tmpArray = paramArray[i].split("="); + if ((tmpArray.length === 2) && (tmpArray[0] === val)) { + result = decodeURIComponent(tmpArray[1]); + break; + } + } + } + return result; +} \ No newline at end of file diff --git a/kurt-web/src/test/java/com/capgemini/reports/common/AbstractKurtServletTest.java b/kurt-web/src/test/java/com/capgemini/reports/common/AbstractKurtServletTest.java new file mode 100644 index 0000000..2c29652 --- /dev/null +++ b/kurt-web/src/test/java/com/capgemini/reports/common/AbstractKurtServletTest.java @@ -0,0 +1,178 @@ +package com.capgemini.reports.common; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import lombok.extern.slf4j.Slf4j; +import org.json.JSONObject; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +import javax.jms.JMSException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +/** JUnit test. **/ +@Slf4j +public class AbstractKurtServletTest { + + private static final String STATUS_TOKEN = "status"; + private static final String STATUS_SUCCESS = "success"; + private static final String STATUS_FAILED = "failed"; + + private static final String SUCCESS_TOKEN = "success"; + private static final String SUCCESS_MESSAGE = "Success message"; + + private static final String FAILURE_TOKEN = "error"; + private static final String FAILURE_MESSAGE = "Expected Generic Failure message"; + + private static final UserInputErrorEnum EXPECTED_BAD_SERVLET_ERROR = UserInputErrorEnum.INCORRECT_PRODUCT; + + /** JUnit test. **/ + @Test + public void testSuccessMessage() { + JSONObject json = ServletMessageHelper.successMessage(SUCCESS_MESSAGE); + Assert.assertEquals(STATUS_SUCCESS, json.get(STATUS_TOKEN)); + Assert.assertEquals(SUCCESS_MESSAGE, json.getString(SUCCESS_TOKEN)); + } + + /** JUnit test. **/ + @Test + public void testErrorMessage1() { + JSONObject json = ServletMessageHelper.errorMessage(FAILURE_MESSAGE); + Assert.assertEquals(STATUS_FAILED, json.get(STATUS_TOKEN)); + Assert.assertEquals(FAILURE_MESSAGE, json.getString(FAILURE_TOKEN)); + } + + /** JUnit test. **/ + @Test + public void testErrorMessage2() { + JSONObject json = ServletMessageHelper.errorMessage(new KurtException(FAILURE_MESSAGE)); + Assert.assertEquals(STATUS_FAILED, json.get(STATUS_TOKEN)); + Assert.assertEquals(FAILURE_MESSAGE, json.getString(FAILURE_TOKEN)); + } + + /** JUnit test. **/ + @Test + public void testErrorMessage3() { + UserInputErrorEnum expectedError = UserInputErrorEnum.PRODUCT_DOES_NOT_EXIST_NO_DATA_TO_PRINT; + JSONObject json = ServletMessageHelper.errorMessage(new InvalidUserInputException(expectedError)); + Assert.assertEquals(STATUS_FAILED, json.get(STATUS_TOKEN)); + Assert.assertEquals(expectedError.getMsgFr(), json.getString(FAILURE_TOKEN)); + } + + /** + * JUnit test. + * + * @throws ServletException should not happen + * @throws IOException should not happen + **/ + @Test + public void testDoPostSuccess() throws ServletException, IOException { + // Test the servlet + JSONObject responseJson = testSomeServlet(new SomeGoodServlet()); + + // Parse the contents + String resultStr = responseJson.getString(ServletMessageHelper.TOKEN_STATUS); + log.info("Json object received with status = \"" + resultStr + "\""); + Assert.assertEquals(ServletMessageHelper.STATUS_SUCCESS, resultStr); + Assert.assertEquals(SUCCESS_MESSAGE, responseJson.get(ServletMessageHelper.STATUS_SUCCESS)); + } + + /** + * JUnit test. + * + * @throws ServletException should not happen + * @throws IOException should not happen + **/ + @Test + public void testDoPostKurtFailure() throws ServletException, IOException { + // Test the servlet + JSONObject responseJson = testSomeServlet(new SomeBadServletWithBadJMScommunication()); + + // Parse the contents + String resultStr = responseJson.getString(ServletMessageHelper.TOKEN_STATUS); + log.info("Json object received with status = \"" + resultStr + "\""); + Assert.assertEquals(ServletMessageHelper.STATUS_FAILED, resultStr); + Assert.assertEquals(ServletMessageHelper.POSTING_ERROR_MESSAGE_FR, responseJson.get(ServletMessageHelper.TOKEN_ERROR)); + } + + /** + * JUnit test. + * + * @throws ServletException should not happen + * @throws IOException should not happen + **/ + @Test + public void testDoPostServletFailure() throws ServletException, IOException { + // Test the servlet + JSONObject responseJson = testSomeServlet(new SomeBadServletWithNiceExeption()); + + // Parse the contents + String resultStr = responseJson.getString(ServletMessageHelper.TOKEN_STATUS); + log.info("Json object received with status = \"" + resultStr + "\""); + Assert.assertEquals(ServletMessageHelper.STATUS_FAILED, resultStr); + Assert.assertEquals(EXPECTED_BAD_SERVLET_ERROR.getMsgFr(), responseJson.get(ServletMessageHelper.TOKEN_ERROR)); + } + + /** + * JUnit test. + * + * @param testerServlet should not happen + * @return JSON object should not happen + * @throws ServletException should not happen + * @throws IOException should not happen + **/ + public JSONObject testSomeServlet(final AbstractKurtServlet testerServlet) throws ServletException, IOException { + + // Setup request and responses + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + log.info("Request and Response ready"); + + // Create Servlet instance and test it + testerServlet.doPost(request, response); + log.info("doPost() Done"); + + // Obtain response content + String responseStr = response.getContentAsString(); + log.info("Raw response = \"" + responseStr + "\""); + + // Obtain response status + return new JSONObject(responseStr); + } + + /** Servlet sample for test purpose. **/ + public class SomeGoodServlet extends AbstractKurtServlet { + private static final long serialVersionUID = 8779144588360308332L; + + @Override + protected JSONObject perform(final HttpServletRequest request, final TcSession session) { + return ServletMessageHelper.successMessage(SUCCESS_MESSAGE); + } + } + + /** Servlet sample for test purpose. **/ + private class SomeBadServletWithBadJMScommunication extends AbstractKurtServlet { + private static final long serialVersionUID = 7423523975629997878L; + + @Override + protected JSONObject perform(final HttpServletRequest request, final TcSession session) throws JMSException { + throw new JMSException(FAILURE_MESSAGE); + } + } + + private class SomeBadServletWithNiceExeption extends AbstractKurtServlet { + private static final long serialVersionUID = 7423523975629997878L; + + @Override + protected JSONObject perform(final HttpServletRequest request, final TcSession session) throws InvalidUserInputException { + throw new InvalidUserInputException(UserInputErrorEnum.INCORRECT_PRODUCT); + } + } + +} diff --git a/kurt-web/src/test/java/com/capgemini/reports/common/AbstractSubmitServletTest.java b/kurt-web/src/test/java/com/capgemini/reports/common/AbstractSubmitServletTest.java new file mode 100644 index 0000000..0c1b680 --- /dev/null +++ b/kurt-web/src/test/java/com/capgemini/reports/common/AbstractSubmitServletTest.java @@ -0,0 +1,368 @@ +package com.capgemini.reports.common; + +import com.capgemini.framework.common.MailHelper; +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.ReportEnum; +import com.capgemini.reports.ReportLaunchTypeEnum; +import com.capgemini.reports.builder.ReportBuilder; +import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum; +import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.execution.IDataReportPreparator; +import com.capgemini.reports.execution.mapconstructor.AbstractStaticTemplateMapConstructor; +import com.capgemini.reports.execution.mapconstructor.IMapConstructor; +import com.capgemini.reports.execution.strategies.IExecutionStrategy; +import com.capgemini.reports.printing.PrintParameters; +import com.capgemini.reports.printing.Printer.PrintFormat; +import com.capgemini.reports.queuing.ReportPriority; +import com.capgemini.reports.reports.parameters.IChecker; +import com.teamcenter.schemas.soa._2006_03.exceptions.ServiceException; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.lingala.zip4j.exception.ZipException; +import org.json.JSONObject; +import org.junit.Assert; +import org.junit.Test; +import org.quartz.SchedulerException; +import org.springframework.mock.web.MockHttpServletRequest; + +import javax.jms.JMSException; +import javax.naming.NamingException; +import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.regex.Pattern; + +/** JUnit test. **/ +@Slf4j +public class AbstractSubmitServletTest { + + private static final String FAKE_REPORT = "FAKE_REPORT"; + private static final ReportPriority EXPECTED_REPORT_PRIORITY = ReportPriority.HIGH_PRIORITY; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/test_policy.xml"); + /** A non-space string of chars, followed by '@', followed by a non-space string of chars, followed by a dot ('.'), followed by a non-space string of chars. */ + private static final Pattern EMAIL_ADDRESS_REGEX = Pattern.compile("\\S+@\\S+\\.\\S+"); + + /** + * JUnit test. All tests must pass, the report should be submitted and an email sent to the user. + * + * @throws InvalidInputException Should not happen + * @throws JMSException Should not happen + * @throws ServiceException Should not happen + * @throws NamingException Should not happen + * @throws SchedulerException Should not happen + **/ + @Test + public void testPerformSuccess() throws InvalidInputException, JMSException, ServiceException, NamingException, SchedulerException, NoTeamcenterConnectionException { + // Create Servlet instance + log.info("Create Servlet instance"); + SomeGoodParameter quickCheck = new SomeGoodParameter(); + SomeGoodParameter longCheck = new SomeGoodParameter(); + SomeExecutionReport goodReport = new SomeExecutionReport(quickCheck, longCheck, new SomeDataPreparator(), new SomeMapConstructor()); + SomeSubmitServlet testerServlet = new SomeSubmitServlet(goodReport); + + // Execute servlet POST operation + log.info("Execute Good servlet POST operation"); + JSONObject json = testPerform(testerServlet); + + // Verify Report TcReleaseStatus : posted, start email sent, but not executed + log.info("Verify Report TcReleaseStatus : params checked, report posted, start email sent, but not executed"); + Assert.assertTrue(quickCheck.isChecked); + // TODO (Long Checks not yet activated) Assert.assertTrue(longCheck.isChecked); + Assert.assertNotNull(testerServlet.theReport); + Assert.assertFalse(testerServlet.theReport.isParametersCheckFailureEmailDone); + Assert.assertTrue(testerServlet.theReport.isStartEmailDone); + Assert.assertFalse(testerServlet.theReport.isPrepareDataDone()); + Assert.assertFalse(testerServlet.theReport.isEndEmailDone); + Assert.assertFalse(testerServlet.theReport.isErrorEmailDone); + Assert.assertEquals(EXPECTED_REPORT_PRIORITY, goodReport.getPriorityCode()); + + // Verify JSON (should be success) + log.info("Verify HttpServletResponse to the server (should be success)"); + log.info("raw JSON : " + json); + Assert.assertEquals(ServletMessageHelper.STATUS_SUCCESS, json.get(ServletMessageHelper.TOKEN_STATUS)); + log.info(json.get(ServletMessageHelper.STATUS_SUCCESS).toString()); + } + + /** + * JUnit test. Report check must fail. Report should not be submitted, an explanation should be sent to the user. + * + * @throws JMSException Should not happen + * @throws ServiceException Should not happen + * @throws NamingException Should not happen + * @throws SchedulerException Should not happen + **/ + @Test + public void testPerformServletEarlyFail() throws JMSException, ServiceException, NamingException, SchedulerException, NoTeamcenterConnectionException { + // Create Servlet instance + log.info("Create Servlet instance"); + SomeFailingParameter quickCheck = new SomeFailingParameter(); + SomeGoodParameter longCheck = new SomeGoodParameter(); + SomeExecutionReport badReport = new SomeExecutionReport(quickCheck, longCheck, new SomeDataPreparator(), new SomeMapConstructor()); + SomeSubmitServlet testerServlet = new SomeSubmitServlet(badReport); + + // Execute servlet POST operation + log.info("Execute Bad servlet POST operation"); + try { + testPerform(testerServlet); + } catch (InvalidInputException e) { + // Verify Report TcReleaseStatus : NOT posted, no eMail sent, report not executed + log.info("Verify Report TcReleaseStatus : NOT posted, no eMail sent, report not executed"); + Assert.assertNotNull(testerServlet.theReport); + Assert.assertFalse(testerServlet.theReport.isParametersCheckFailureEmailDone); + Assert.assertFalse(testerServlet.theReport.isStartEmailDone); + Assert.assertFalse(testerServlet.theReport.isPrepareDataDone()); + Assert.assertFalse(testerServlet.theReport.isEndEmailDone); + log.info("Test successful", e); + return; + } + log.info("Test failed!"); + Assert.fail(); + } + + /** + * JUnit test. Report check must fail. Report should not be submitted, an explanation should be sent to the user. + * + * @throws JMSException Should not happen + * @throws InvalidInputException Should not happen + **/ + @Test + public void testPerformServletLateFail() throws JMSException, InvalidInputException { + /* + // Create Servlet instance + log.info("Create Servlet instance"); + SomeGoodParameter quickCheck = new SomeGoodParameter(); + SomeFailingParameter longCheck = new SomeFailingParameter(); + SomeExecutionReport badReport = new SomeExecutionReport(quickCheck, longCheck); + SomeSubmitServlet testerServlet = new SomeSubmitServlet(badReport); + SomeMessagingServer messagingServer = new SomeMessagingServer(); + + // Execute servlet POST operation + log.info("Execute Good servlet POST operation"); + JSONObject json = testPerform(testerServlet, messagingServer); + + // Verify Report TcReleaseStatus : NOT posted, error eMail sent, report not executed + log.info("Verify Report TcReleaseStatus : NOT posted, Error eMail sent, report not executed"); + Assert.assertFalse(messagingServer.reportPosted); + Assert.assertNotNull(testerServlet.theReport); + Assert.assertTrue(quickCheck.isChecked); + Assert.assertTrue(testerServlet.theReport.isParametersCheckFailureEmailDone); + Assert.assertFalse(testerServlet.theReport.isStartEmailDone); + Assert.assertFalse(testerServlet.theReport.isPrepareDataDone); + Assert.assertFalse(testerServlet.theReport.isConstructDataMapsDone); + Assert.assertFalse(testerServlet.theReport.isEndEmailDone); + + // Verify HttpServletResponse (should be failed) + log.info("Verify HttpServletResponse to the server (should be failed, internal error)"); + Assert.assertEquals(AbstractSubmitServlet.SUCCESS, json.findAll(AbstractSubmitServlet.STATUS)); + Assert.assertEquals("BOM assemblage PU successfully posted in the queues", json.findAll(AbstractSubmitServlet.SUCCESS)); + log.info("Test successful");*/ + } + + private JSONObject testPerform(final AbstractSubmitServlet servlet) + throws InvalidInputException, JMSException, ServiceException, NamingException, SchedulerException, NoTeamcenterConnectionException { + // Setup request and responses + log.info("testPerform(): Setup request and responses"); + HttpServletRequest request = new MockHttpServletRequest(); + + // Execute servlet POST operation + log.info("Execute Good servlet POST operation"); + try (final TcSession session = new FakeTcSession()) { + // Return the servlet response for further checks + return servlet.perform(request, session); + } + } + + + @Test + public void getDefaultEmailDestinatorsTest() { + log.info("Input: '" + SettingsHelper.getDefaultDestinatorEmail()); + List defaults = MailHelper.DEFAULT_DESTINATORS; + Assert.assertFalse(defaults.isEmpty()); + for (String user : defaults) { + log.info("'" + user + "'"); + Assert.assertTrue(EMAIL_ADDRESS_REGEX.matcher(user).matches()); + } + } + + /** A placeholder implementation of SubmitServlet for testing. */ + @Getter + private class SomeSubmitServlet extends AbstractSubmitServlet { + private static final long serialVersionUID = 8030290777260376309L; + private final SomeExecutionReport theReport; + + public SomeSubmitServlet(final SomeExecutionReport report) { + this.theReport = report; + } + + @Override + public SomeExecutionReport prepareReport(final HttpServletRequest request) { + return theReport; + } + } + + @Getter + private class SomeDataPreparator implements IDataReportPreparator { + private static final long serialVersionUID = 4832031208271989060L; + private boolean done; + + @Override + public String print(TcSession session, SomeExecutionReport execution, IExecutionStrategy executionStrategy) throws KurtException, ZipException { + done = true; + return null; + } + } + + /** + * Fake {@link TcSession} that does nothing. + */ + private class FakeTcSession extends TcSession { + + public FakeTcSession() { + super(); + } + + @Override + public void close() { + // Do not logout! + } + + } + + @Getter + private class SomeMapConstructor extends AbstractStaticTemplateMapConstructor { + private static final long serialVersionUID = -6387054969518914371L; + private boolean done; + + @Override + public void constructDataMaps(TcSession session, final PrintParameters printParameters, final Void report) throws KurtException { + done = true; + } + + } + + /** A placeholder implementation of an ExecutionReport. */ + @Getter + private class SomeExecutionReport extends AbstractExecutionReport { + + private static final long serialVersionUID = 3104147701132381151L; + + private boolean isStartEmailDone; + private boolean isEndEmailDone; + private boolean isErrorEmailDone; + private boolean isParametersCheckFailureEmailDone; + + final List quickChecks; + final List longChecks; + + public SomeExecutionReport(final IChecker quickCheck, final IChecker longCheck, + final IDataReportPreparator prepaData, final IMapConstructor constructMap) { + super(EXPECTED_REPORT_PRIORITY.getPriorityValue(), "someRule", ReportLaunchTypeEnum.IMMEDIATE);// the highest priority code, launch type is immediate + quickChecks = new ArrayList<>(); + quickChecks.add(quickCheck); + longChecks = new ArrayList<>(); + longChecks.add(longCheck); + } + + public boolean isPrepareDataDone() { + return ((SomeDataPreparator) this.getDataPreparator()).isDone(); + } + + @Override + public ReportPriority getReportPriority() { + isStartEmailDone = true; + return EXPECTED_REPORT_PRIORITY; + } + + + @Override + public String getSpecifiedFileName() { + return FAKE_REPORT; + } + + @Override + public PrintFormat getPrintingFormat() { + return PrintFormat.XLSX; + } + + @Override + public List getQuickChecks() { + return quickChecks; + } + + @Override + public List getLongChecks() { + return longChecks; + } + + @Override + public ReportEnum getReportIdentifier() { + return ReportEnum.REPORT_R01; + } + + @Override + public PolicyLocation getPropertyPolicyForLongChecks() { + return XML_POLICY; + } + + @Override + public PolicyLocation getFullPolicy() { + return XML_POLICY; + } + + @Override + public String getTemplateLocation() { + return "somewhere"; + } + + @Override + public List getLaunchData() { + List crits = new ArrayList<>(); + crits.add(new CriteriaValue(ReportCriteriaEnum.PRODUCT, UUID.randomUUID().toString())); + return crits; // Random Data to avoid duplicates + } + + @Override + public IDataReportPreparator getDataPreparator() { + return new SomeDataPreparator(); + } + + @Override + public AbstractExecutionReport cloneTemplateToExecution() { + SomeFailingParameter quickCheck = new SomeFailingParameter(); + SomeGoodParameter longCheck = new SomeGoodParameter(); + return new SomeExecutionReport(quickCheck, longCheck, new SomeDataPreparator(), new SomeMapConstructor()); + } + + @Override + public Class getReportBuilderClass() { + return null; + } + + } + + private class SomeGoodParameter implements IChecker { + boolean isChecked; + + @Override + public void check(final TcSession session) throws InvalidUserInputException { + isChecked = true; + } + } + + private class SomeFailingParameter implements IChecker { + + @Override + public void check(final TcSession session) throws InvalidUserInputException { + throw new InvalidUserInputException(UserInputErrorEnum.INTERNAL_ERROR); + } + } +} diff --git a/kurt-web/src/test/java/com/capgemini/reports/common/scheduling/SchedulingServletTest.java b/kurt-web/src/test/java/com/capgemini/reports/common/scheduling/SchedulingServletTest.java new file mode 100644 index 0000000..f0e1a49 --- /dev/null +++ b/kurt-web/src/test/java/com/capgemini/reports/common/scheduling/SchedulingServletTest.java @@ -0,0 +1,87 @@ +package com.capgemini.reports.common.scheduling; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.NotSupportedException; +import com.capgemini.reports.execution.AbstractExecutionReport; +import com.capgemini.reports.quartz.TriggerPreparator; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.junit.Test; +import org.quartz.CronTrigger; +import org.quartz.JobKey; +import org.quartz.Trigger; +import org.quartz.TriggerKey; +import org.springframework.mock.web.MockHttpServletRequest; + + +@Slf4j +public class SchedulingServletTest { + + private final String LAUNCH_DATE_STR = SettingsHelper.getDelayedLaunchHour(); + + /** + * JUnit test. + * + * @throws NotSupportedException Should not happen + */ + @Test + public void testGetExecutionReportImpl() throws NotSupportedException { + // Get a mock HttpRequest to test the methods of the servlet + MockHttpServletRequest mockRequest = getMockHttpServletRequest(); + + SubmitServletScheduling servlet = new SubmitServletScheduling(); + AbstractExecutionReport reportTest = servlet.getExecutionReportImpl(mockRequest); + + // Check + Assert.assertNotNull(reportTest); + log.info(reportTest.toString()); + } + + /** + * JUnit test. + * + * @throws InvalidInputException Should not happen + */ + @Test + public void testGetSchedulingTrigger() throws InvalidInputException { + // Initialize the variables + Long uid = (long) 123456789; + int priority = 1; + + // Separate hours and minutes (format hour:minute) + String[] tableStrLaunchTime = LAUNCH_DATE_STR.split(":"); + int launchHour = Integer.parseInt(tableStrLaunchTime[0]); + int launchMinute = Integer.parseInt(tableStrLaunchTime[1]); + + // Get a mock HttpRequest to test the methods of the servlet + MockHttpServletRequest mockRequest = getMockHttpServletRequest(); + String schedulingName = mockRequest.getParameter("scheduling_name"); + + SubmitServletScheduling servlet = new SubmitServletScheduling(); + + Trigger triggerTest = TriggerPreparator.prepareScheduledTrigger(uid, priority, schedulingName, servlet.getSchedulingData(mockRequest)); + + // Check + Assert.assertNotNull(triggerTest); + CronTrigger cronTrigger = (CronTrigger) triggerTest; + log.info(cronTrigger.toString()); + JobKey jobKey = cronTrigger.getJobKey(); + TriggerKey triggerKey = cronTrigger.getKey(); + Assert.assertEquals("the name of the job is not the same as the expected value", "job_name_" + uid, jobKey.getName()); + Assert.assertEquals("the group of the job is not the same as the expected value", "scheduled", jobKey.getGroup()); + Assert.assertEquals("the name of the trigger is not the same as the expected value", "trigger_name_" + uid, triggerKey.getName()); + Assert.assertEquals("the group of the trigger is not the same as the expected value", "scheduled", triggerKey.getGroup()); + String schedulName = mockRequest.getParameter("scheduling_name"); + Assert.assertEquals("the name of the planification is not the same as the expected value", schedulName, cronTrigger.getDescription()); + Assert.assertEquals("the cron express which manage the planification is not the same as the expected value", "0 " + launchMinute + " " + launchHour + " ? * *", cronTrigger.getCronExpression()); + } + + private MockHttpServletRequest getMockHttpServletRequest() { + MockHttpServletRequest mockRequest = new MockHttpServletRequest(); + mockRequest.setParameter("report_code", "RTest"); + mockRequest.setParameter("scheduling_name", "myPlanif"); + mockRequest.setParameter("period", "daily"); + return mockRequest; + } +} diff --git a/kurt-web/src/test/java/com/capgemini/reports/formatting/MyReportsTest.java b/kurt-web/src/test/java/com/capgemini/reports/formatting/MyReportsTest.java new file mode 100644 index 0000000..d7c8a25 --- /dev/null +++ b/kurt-web/src/test/java/com/capgemini/reports/formatting/MyReportsTest.java @@ -0,0 +1,58 @@ +package com.capgemini.reports.formatting; + +import com.capgemini.framework.common.SettingsHelper; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.reports.exceptions.InvalidInputException; +import junit.framework.Assert; +import org.junit.Test; + + +public class MyReportsTest { + + /** + * JUnit test. + * + * @throws InvalidInputException Should not happen + */ + @Test + public void obtainIntegerPageParamTestSuccess() throws InvalidInputException { + Assert.assertEquals(25, MyReports.obtainIntegerPageParam("25")); + } + + /** + * JUnit test. + * + * @throws InvalidInputException Should not happen + */ + @Test(expected = InvalidInputException.class) + public void obtainIntegerPageParamTestFailed() throws InvalidInputException { + Assert.assertEquals(1, MyReports.obtainIntegerPageParam("sgr " + "Pages: " + + " - " + + "", + MyReports.makePaging(1, 2)); + Assert.assertEquals( + "
     
    " + "Pages: " + + " - " + + " - " + + "", + MyReports.makePaging(2, 3)); + } +} diff --git a/kurt-web/src/test/java/com/capgemini/servlet/test/Report01Test.java b/kurt-web/src/test/java/com/capgemini/servlet/test/Report01Test.java new file mode 100644 index 0000000..7e864c3 --- /dev/null +++ b/kurt-web/src/test/java/com/capgemini/servlet/test/Report01Test.java @@ -0,0 +1,84 @@ +package com.capgemini.servlet.test; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import junit.framework.Assert; + +/** JUnit test. **/ +public class Report01Test { + + /** JUnit setup. **/ + @BeforeClass + public static void setUpBeforeClass() { + // Nothing to do + } + + /** JUnit setup. **/ + @Before + public void setUp() { + // Nothing to do + } + + /** JUnit cleanup. **/ + @After + public void tearDown() { + // Nothing to do + } + + /** JUnit test. **/ + @Test + public void testURLGetsUnits() { + + String url = "http://localhost:8080/kurt-web/report_r01/obtain-data?action=getUnits&dataValues=p5bFrkT9hLofXA"; + + Pattern p = Pattern.compile("action=(.*)&dataValues=(.*)"); + Matcher m = p.matcher(url); + if (m.find()) { + + String action = m.group(1); + String datavalues = m.group(2); + + Assert.assertEquals("Check action ", "getUnits", action); + Assert.assertEquals("Check datavalues ", "p5bFrkT9hLofXA", datavalues); + } + } + + /** JUnit test. **/ + @Test + public void testURLGetGenerics() { + + String url = "http://localhost:8080/kurt-web/report_r01/obtain-data?action=getGenerics&dataValues=p5bFrkT9hLofXA&unit=20"; + + Pattern p = Pattern.compile("action=(.*)&dataValues=(.*)&unit=(.*)"); + Matcher m = p.matcher(url); + if (m.find()) { + + String action = m.group(1); + String datavalues = m.group(2); + String unit = m.group(3); + + Assert.assertEquals("Check action ", "getGenerics", action); + Assert.assertEquals("Check datavalues ", "p5bFrkT9hLofXA", datavalues); + Assert.assertEquals("Check unit ", "20", unit); + } + } + + /** JUnit test. **/ + @Test + public void testGetParams() { + + String urlUnit = "http://localhost:8080/kurt-web/report_r01/obtain-data?action=getUnits&dataValues=p5bFrkT9hLofXA"; + Assert.assertEquals("URL unit 1", "http://localhost:8080/kurt-web/report_r01/obtain-data?action=getUnits&dataValues=p5bFrkT9hLofXA", urlUnit); + + String urlGenerics = "http://localhost:8080/kurt-web/report_r01/obtain-data?action=getGenerics&dataValues=p5bFrkT9hLofXA&unit=20"; + Assert.assertEquals("URL unit 2", + "http://localhost:8080/kurt-web/report_r01/obtain-data?action=getGenerics&dataValues=p5bFrkT9hLofXA&unit=20", urlGenerics); + } + +} diff --git a/kurt-web/src/test/resources/htmlRef/my_reports_failed_ref.html b/kurt-web/src/test/resources/htmlRef/my_reports_failed_ref.html new file mode 100644 index 0000000..e7f61ff --- /dev/null +++ b/kurt-web/src/test/resources/htmlRef/my_reports_failed_ref.html @@ -0,0 +1,28 @@ + + + + Mes rapports - <%= theUserLogin %> + + + + + + +

    Mes rapports - <%= theUserLogin %> : <%= theUserReportCount %> rapport(s)

    + + + Rafraichir +

    + +
    +
    + [[ERROR_MESSAGE]] +

    + + +
    + + + diff --git a/kurt-web/src/test/resources/htmlRef/my_reports_success_ref.html b/kurt-web/src/test/resources/htmlRef/my_reports_success_ref.html new file mode 100644 index 0000000..b850b25 --- /dev/null +++ b/kurt-web/src/test/resources/htmlRef/my_reports_success_ref.html @@ -0,0 +1,46 @@ + + + + Mes rapports - <%= theUserLogin %> + + + + + + + + +

    Mes rapports - [[USER_LOGIN]] : [[USER_REPORT_COUNT]] rapport(s)

    + + + Rafraichir +

    + +
    +
    +
    RapportUtilisateur
    ' + currentReport['reportCode'] + '' + priority + '' + currentReport['login'] + '' + currentReport['requestDate'] + '' + currentReport['startGenerationDate'] + ' ' + + currentError + '' + currentStatus + '
    ' + reportArray[i]['report_code'] + '' + reportArray[i]['planif_name'] + '' + reportArray[i]['period'] + '' + reportArray[i]['date_maj'] + '' + reportArray[i]['user_responsable'] + '' + reportArray[i]['date_start'] + ''; + tableContent += ' \n'; + tableContent += ' '; + tableContent += ' \n'; + tableContent += ' '; + tableContent += ' \n'; + tableContent += '
    ' + currentReport['reportCode'] + '' + currentReport['executionCount'] + '' + currentReport['failedFuncCount'] + '' + currentReport['failedTechCount'] + '' + currentReport['minDuration'] + '' + currentReport['avgDuration'] + '' + currentReport['maxDuration'] + '
    ' + stat['name'] + '' + stat['R01'] + '' + stat['R03'] + '' + stat['R05'] + '' + stat['R06'] + '' + stat['R07'] + '' + stat['R10'] + '' + stat['R11'] + '' + stat['R13'] + '' + stat['R15'] + '' + stat['W15'] + '' + stat['R16'] + '' + stat['R17'] + '' + stat['R19'] + '' + stat['R20'] + '' + stat['R21'] + '' + stat['R22'] + '' + stat['W22'] + '' + stat['R23'] + '' + stat['R24'] + '' + stat['R25'] + '' + stat['R26'] + '' + stat['R27'] + '' + stat['R28'] + '' + stat['Global'] + '
    + + + + + + + + + +
    Code du rapportDate de demandeDate de lancementDate de finInfosStatut
    + + [[PAGING]] + +

    + + +
    + + + diff --git a/kurt-web/src/test/resources/log4j.properties b/kurt-web/src/test/resources/log4j.properties new file mode 100644 index 0000000..8f372cd --- /dev/null +++ b/kurt-web/src/test/resources/log4j.properties @@ -0,0 +1,13 @@ +log4j.logger.com.teamcenter.soa=WARN +log4j.logger.org.apache=WARN +log4j.logger.httpclient=WARN + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.threshold=DEBUG +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %c{1}:%L - %m%n + +# Root logger option +log4j.rootLogger=DEBUG, stdout diff --git a/kurt-web/src/test/resources/logging.properties b/kurt-web/src/test/resources/logging.properties new file mode 100644 index 0000000..1983b8d --- /dev/null +++ b/kurt-web/src/test/resources/logging.properties @@ -0,0 +1,3 @@ +handlers=java.util.logging.ConsoleHandler +java.util.logging.ConsoleHandler.level=FINEST +com.capgemini.level=FINEST diff --git a/kurt-web/src/test/resources/simplelogger.properties b/kurt-web/src/test/resources/simplelogger.properties new file mode 100644 index 0000000..e69de29 diff --git a/kurt-web/src/test/resources/xml/policies/simple_policy.xml b/kurt-web/src/test/resources/xml/policies/simple_policy.xml new file mode 100644 index 0000000..2f3b98d --- /dev/null +++ b/kurt-web/src/test/resources/xml/policies/simple_policy.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kurt-web/src/test/resources/xml/policies/test_policy.xml b/kurt-web/src/test/resources/xml/policies/test_policy.xml new file mode 100644 index 0000000..846457a --- /dev/null +++ b/kurt-web/src/test/resources/xml/policies/test_policy.xml @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..d1d8674 --- /dev/null +++ b/pom.xml @@ -0,0 +1,500 @@ + + + + 4.0.0 + com.capgemini.reports + kurt + pom + 1.32.9 + Kurt + Application de reporting + + + deployment-tool + core-ear + kurt-ejb + kurt-web + kurt-utility + jasper + teamcenter + distribution + + + + http://mrm.apps2.capgemini.com + ${capgemini.cip.project.id}-release-local + AD_DFP_PV_CDS + + + UTF-8 + + + 1.0.4.Final + + + 7.9.Final + + + 2.1.1 + + + 1.7 + 1.7 + + ${project.artifactId}_v${project.version} + distribution + https://coconet-svn-fr-01.capgemini.com/svn/repos/pv-reports + trunk + + + + scm:svn:https://coconet-svn-fr-01.capgemini.com/svn/repos/pv-reports/trunk/kurt + + scm:svn:https://coconet-svn-fr-01.capgemini.com/svn/repos/pv-reports/trunk/kurt + + + + jenkins + https://pvscnecma.pl.s2-eu.capgemini.com/jenkins + + + + + nexus + Internal Snapshot Releases + http://nexus3-core:8081/nexus3/repository/maven-snapshots/ + + + nexus + Internal Releases + http://nexus3-core:8081/nexus3/repository/maven-releases/ + + + + + + + org.jboss.spec + jboss-javaee-6.0 + 1.0.0.Final + pom + import + + + org.jboss.as + jboss-as-parent + 7.1.1.Final + pom + import + + + + org.testng + testng + 6.14.2 + test + + + + org.mockito + mockito-core + 2.12.0 + test + + + + org.assertj + assertj-core + 2.9.0 + test + + + + org.slf4j + slf4j-api + 1.7.7 + + + + org.projectlombok + lombok + 1.16.10 + + + + com.google.guava + guava + 20.0 + + + + org.json + json + 20140107 + + + + + + + + + development + + true + **/*Test.java + **/ExecutionR*Test.* + + + true + + + + + + validation + + **/ExecutionR*Test.* + + + + + + release + + + + org.apache.maven.plugins + maven-release-plugin + 2.5.3 + + https://coconet-svn-fr-01.capgemini.com/svn/repos/pv-reports/tags + svc-fr-plm + Passw0rd + + + + + + + com.maestrodev + collabnet-maven-plugin + 1.4 + + fr_south_t30_plateau_virtuel_sne + PV_SNECMA_interne + ${release.id} + ${project.description} + https://coconet2.capgemini.com + + + + install + install + + deploy-to-releases + + + + + + + + + + + sonar + + **/*Test.java + **/ExecutionR*Test.* + + + + + + org.codehaus.mojo + sonar-maven-plugin + 3.2 + + + + + + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + 2.8.2 + + + org.apache.maven.plugins + maven-jar-plugin + 3.0.2 + + + org.apache.maven.plugins + maven-ejb-plugin + 3.0.1 + + + org.apache.maven.plugins + maven-war-plugin + 3.0.0 + + + org.apache.maven.plugins + maven-ear-plugin + 2.10.1 + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + ${maven.compiler.target} + ${maven.compiler.source} + ${project.build.sourceEncoding} + true + + + + org.apache.maven.plugins + maven-site-plugin + 3.5.1 + + + org.apache.maven.plugins + maven-resources-plugin + 3.0.1 + + + org.apache.maven.plugins + maven-dependency-plugin + 3.0.0 + + + org.apache.maven.plugins + maven-assembly-plugin + 3.0.0 + + + org.apache.maven.plugins + maven-surefire-plugin + 2.20.1 + + 1 + false + -Xmx1024m -XX:MaxPermSize=256m + + + ${maven.surefire.plugin.include.filter} + + + ${maven.surefire.plugin.exclude.filter} + + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.1 + + + + org.codehaus.mojo + versions-maven-plugin + 2.3 + + + + + + org.jboss.as.plugins + jboss-as-maven-plugin + ${version.jboss.maven.plugin} + + + + org.jacoco + jacoco-maven-plugin + 0.7.7.201606060606 + + + + prepare-agent + + + + report + prepare-package + + report + + + + + + + org.projectlombok + lombok-maven-plugin + 1.16.10.0 + + + + + + + com.googlecode.maven-overview-plugin + maven-overview-plugin + 1.6 + + 1200 + 1200 + 1 + true + + + test + + + + com.capgemini.* + + + compile + provided + runtime + + + + + org.codehaus.mojo + versions-maven-plugin + + + org.apache.maven.plugins + maven-site-plugin + + + org.apache.maven.plugins + maven-dependency-plugin + + + analyze + + analyze-only + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + false + + ${*} + + + pdf + + swf + + jpeg + + jpg + + png + + jrxml + + + + + + + default-resources + + + + filter-properties-files + process-resources + + copy-resources + + + + ISO-8859-1 + ${project.build.outputDirectory} + + + src/main/resources + true + + **/*.properties + + + + + + + + copy-other-resources + process-resources + + copy-resources + + + ${project.build.outputDirectory} + + + src/main/resources + true + + **/*.properties + + + + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.jacoco + jacoco-maven-plugin + + + + + diff --git a/scripts/reports_installation_script.pl b/scripts/reports_installation_script.pl new file mode 100644 index 0000000..9988371 --- /dev/null +++ b/scripts/reports_installation_script.pl @@ -0,0 +1,96 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use File::Copy qw/ cp /; # For cp and move command + +# Paths for FMS server +my $installFolderOnFMS = "/appl/plvt/install"; +my $tcdata = $ENV{'TC_DATA'}; +my $tcroot = $ENV{'TC_ROOT'}; + +if($#ARGV==-1) { + print("Error : Missing arguments\n"); + print("First argument accepted values are [fms|bas]\n"); +} else { + print("==== BEGIN ====\n"); + my $serveur = $ARGV[0]; + + if($serveur eq "fms") { + if(!($#ARGV==2)) { + print("Arguments and are mandatory [version number format X.XX.X]\n"); + } else { + my $newVersion = $ARGV[1]; + my $oldVersion = $ARGV[2]; + + print("Server : FMS | new version : $newVersion | old version: $oldVersion \n"); + + if(!(-d "$installFolderOnFMS/rapt$newVersion")) { + die("Process stopped : $installFolderOnFMS/rapt$newVersion does not exist"); + } else { + if(-e "$installFolderOnFMS/rapt$newVersion/snecma-reports-$newVersion.zip") { + + print("Step 1/2 : Unzip delivery package .. \n"); + + system("unzip $installFolderOnFMS/rapt$newVersion/snecma-reports-$newVersion.zip -d $installFolderOnFMS/rapt$newVersion"); + + print("Step 2/2 : Copy of the report_prefs.xml file from the previous installation (version $oldVersion).. \n"); + + if(-e "$installFolderOnFMS/rapt$oldVersion/Installation/teamcenter/data/report_prefs.xml") { + cp("$installFolderOnFMS/rapt$oldVersion/Installation/teamcenter/data/report_prefs.xml","$installFolderOnFMS/rapt$newVersion/Installation/teamcenter/data") or die "Copy failed: $!\n"; + chmod(0755,"$installFolderOnFMS/rapt$newVersion/Installation/teamcenter/data/report_prefs.xml") or die "Cannot chmod file: $!\n"; + } else { + die("Process stopped : The file report_prefs.xml does not exist in $installFolderOnFMS/rapt$oldVersion/Installation/teamcenter/data \n"); + } + } else { + die("Process stopped : snecma-reports-$newVersion.zip delivery package not found in $installFolderOnFMS/rapt$newVersion/"); + } + } + } + } elsif($serveur eq "bas") { + if (!($#ARGV==1)) { + print("Environment argument is mandatory. Accepted values [int|form|mco|ap|op]\n"); + } else { + my $environment = $ARGV[1]; + + if(("$environment" ne "ap") and ("$environment" ne "op") and ("$environment" ne "op") and ("$environment" ne "int") and ("$environment" ne "mco") and ("$environment" ne "form")) { + die("Environment argument accepted values are [int|form|mco|ap|op]\n"); + } + + print("Copy reports policies from FMS to all BAS | environment : $environment \n"); + if(defined($tcdata)) { + + chdir("$tcdata/soa/policies") or die("$tcdata/soa/policies does not exist"); + + if($environment eq "ap") { + system("scp R*pol*xml sp0plv02\@s04995h0:/appl/plvt/simu/tcdata_101/tcdbapdata/soa/policies"); + system("scp R*pol*xml sp0plv02\@s04996s0:/appl/plvt/simu/tcdata_101/tcdbapdata/soa/policies"); + } + if($environment eq "op") { + system("scp R*pol*xml sp0plv12\@s05196f0:/appl/plvt/oper/tcdata_101/tcdbodata/soa/policies"); + system("scp R*pol*xml sp0plv12\@s05197p0:/appl/plvt/oper/tcdata_101/tcdbodata/soa/policies"); + system("scp R*pol*xml sp0plv12\@s05198y0:/appl/plvt/oper/tcdata_101/tcdbodata/soa/policies"); + system("scp R*pol*xml sp0plv12\@s08702t0:/appl/plvt/oper/tcdata_101/tcdbodata/soa/policies"); + system("scp R*pol*xml sp0plv12\@s08914l0:/appl/plvt/oper/tcdata_101/tcdbodata/soa/policies"); + } + if($environment eq "int") { + system("scp R*pol*xml sp0plv42\@s04616m0:/appl/plvt/int/tcdata/tcdbint4data/soa/policies"); + system("scp R*pol*xml sp0plv42\@s07680f0:/appl/plvt/int/tcdata/tcdbint4data/soa/policies"); + system("scp R*pol*xml sp0plv42\@s07681p0:/appl/plvt/int/tcdata/tcdbint4data/soa/policies"); + } + if($environment eq "form") { + system("scp R*pol*xml sp0plv32\@s05804t0:/appl/plvt/form/tcdata_101/tcdbfodata/soa/policies"); + } + if($environment eq "mco") { + system("scp R*pol*xml sp0plv22\@s04648r0:/appl/plvt/mco/tcdata_101/tcdbm2data/soa/policies"); + } + } else { + print("Process stopped : Environment variables $tcdata is not defined \n"); + } + } + } else { + print("First argument accepted values are [fms|bas]\n"); + } + + print("==== END ====\n"); +} \ No newline at end of file diff --git a/standalone-pv-reports-auth.xml b/standalone-pv-reports-auth.xml new file mode 100644 index 0000000..934ebdb --- /dev/null +++ b/standalone-pv-reports-auth.xml @@ -0,0 +1,580 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jdbc:oracle:thin:@10.24.192.36:1521:TC + oracle + + TAC + TAC + + + + jdbc:oracle:thin:@10.24.192.36:1521:TC + oracle + + TAC + TAC + + + + + oracle.jdbc.driver.OracleDriver + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + 102400 + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jms.queue.DLQ + jms.queue.ExpiryQueue + 0 + 10485760 + BLOCK + 10 + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + ${jboss.bind.address:127.0.0.1} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/standalone-pv-reports.xml b/standalone-pv-reports.xml new file mode 100644 index 0000000..9ace584 --- /dev/null +++ b/standalone-pv-reports.xml @@ -0,0 +1,584 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jdbc:h2:mem:test;DB_CLOSE_DELAY=-1 + h2 + + sa + sa + + + + + org.h2.jdbcx.JdbcDataSource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + 102400 + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jms.queue.DLQ + jms.queue.ExpiryQueue + 0 + 10485760 + BLOCK + 10 + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + ${jboss.bind.address:127.0.0.1} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/teamcenter/pom.xml b/teamcenter/pom.xml new file mode 100644 index 0000000..f64f0fb --- /dev/null +++ b/teamcenter/pom.xml @@ -0,0 +1,196 @@ + + + 4.0.0 + teamcenter + jar + teamcenter + + + com.capgemini.reports + kurt + 1.32.9 + + + + + + junit + junit + test + + + + org.projectlombok + lombok + + + + org.slf4j + slf4j-api + + + + org.slf4j + slf4j-log4j12 + 1.7.7 + + + + org.jboss.spec.javax.annotation + jboss-annotations-api_1.1_spec + + + + com.google.guava + guava + + + + + com.teamcenter + tcsoacommon + 10.1.7 + + + + com.teamcenter + tcsoaclient + 10.1.7 + + + + com.teamcenter + tcsoastrongmodel + 10.1.7 + + + + com.teamcenter + tcsoacorestrong + 10.1.7 + + + + com.teamcenter + tcsoacoreloose + 10.1.7 + + + + com.teamcenter + tcsoaquerystrong + 10.1.7 + + + + com.teamcenter + tcsoaquerytypes + 10.1.7 + + + + com.teamcenter + tcsoastrongmodelmodelcore + 10.1.7 + + + + com.teamcenter + tcsoacoretypes + 10.1.7 + + + + com.teamcenter + tcsoacadstrong + 10.1.7 + + + + com.teamcenter + tcsoacadtypes + 10.1.7 + + + + com.teamcenter + tcsoaworkflowstrong + 10.1.7 + + + + com.teamcenter + tcsoaworkflowtypes + 10.1.7 + + + + com.teamcenter + xml-apis + 10.1.6 + + + + com.teamcenter + resolver + 10.1.6 + + + + com.teamcenter + commons-codec + 10.1.6 + + + + com.teamcenter + fccclient + 10.1.7 + + + + com.teamcenter + fscclient + 10.1.7 + + + + com.teamcenter + commons-httpclient + 10.1.6 + + + + com.teamcenter + commons-httpclient-contrib + 10.1.7 + + + + com.teamcenter + icctstubs + 10.1.3 + + + + xerces + xercesImpl + 2.8.0 + + + + log4j + log4j + + + + + + + src/main/resources + true + + + + + diff --git a/teamcenter/src/main/java/com/capgemini/framework/common/BeanHelper.java b/teamcenter/src/main/java/com/capgemini/framework/common/BeanHelper.java new file mode 100644 index 0000000..d191a02 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/common/BeanHelper.java @@ -0,0 +1,79 @@ +package com.capgemini.framework.common; + +import lombok.extern.slf4j.Slf4j; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.InvocationTargetException; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.Map; +import java.util.TreeMap; + +/** + * JAVA bean attribute serializer. + **/ +@Slf4j +public final class BeanHelper { + + private static final String CLASS_ATT = "class"; + + private BeanHelper() { + // Makes this class static + } + + /** + * Map conversion for attributes of the current bean. + * + * @param aJavaBean Serialized JAVA bean + * @return Map with key as property name and value as a String conversion of the attribute value. + */ + public static Map toStringMap(final Object aJavaBean) { + Map theStrMap = new TreeMap<>(); + try { + fillStrMap(aJavaBean, theStrMap); + } catch (IntrospectionException | IllegalArgumentException | IllegalAccessException | InvocationTargetException e) { + log.error("Error occurred during instrospection, unable to analyse JAVA bean: " + aJavaBean.getClass().getName(), e); + } + return theStrMap; + } + + /** + * Sub-method of toStringMap() filling the map. + * + * @param aJavaBean Serialized JAVA bean + * @param aStrMap Map with key as property name and value as a String conversion of the attribute value. + */ + private static void fillStrMap(final Object aJavaBean, final Map aStrMap) + throws IntrospectionException, IllegalAccessException, InvocationTargetException { + + BeanInfo beanInfo = Introspector.getBeanInfo(aJavaBean.getClass()); + for (PropertyDescriptor propertyDesc : beanInfo.getPropertyDescriptors()) { + + /* Get the next property name and ignore the common attribute called "class" */ + String propertyName = propertyDesc.getName(); + if (CLASS_ATT.equals(propertyName)) { + continue; + } + + /* Try to access to the property through its getter */ + Object theAttValue = propertyDesc.getReadMethod().invoke(aJavaBean); + + /* Convert attribute value to string */ + String theAttributeStrValue = StringHelper.EMPTY; + if (theAttValue != null) { + + if (theAttValue instanceof Timestamp) { + theAttributeStrValue = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(theAttValue); + } else { + theAttributeStrValue = theAttValue.toString(); + } + } + + /* Store attribute in map */ + aStrMap.put(propertyName, theAttributeStrValue); + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/common/LanguageHelper.java b/teamcenter/src/main/java/com/capgemini/framework/common/LanguageHelper.java new file mode 100644 index 0000000..ada175d --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/common/LanguageHelper.java @@ -0,0 +1,91 @@ +package com.capgemini.framework.common; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +/** Class which managed the language problematic of string values in reports. */ +public final class LanguageHelper { + + private static final int FIRST_GROUP = 1; + private static final int SECOND_GROUP = 2; + private static final int THIRD_GROUP = 3; + private static final int SIZE_2 = 2; + private static final int SIZE_4 = 4; + private static final String STR_SEPARATOR = "/"; + private static final String EMPTY_STRING = StringHelper.EMPTY; + private static final String REGEX_SEPARATOR = "\\s*\\/\\s*"; // A slash (/) character surrounded by any number of spaces (including none) + + private LanguageHelper() { + + } + + /** + * Extracts left side of a string of the form "French text / English text".
    + * Separator slash may have *any* number (0+) of white spaces around them.
    + * Warning : The form may be "French text 1 / French text 2 / English text 1 / English text 2". and in this case, the two left sides are extracted. + * + * @param string {@link String} - the string value to check + * @return the "French side" (if any "side" exists), an empty string otherwise + */ + public static String french(final String string) { + if (string == null || string.isEmpty()) { + return EMPTY_STRING; + } + String[] list = string.split(REGEX_SEPARATOR); + if (list.length > 0) { + String result; + if (list.length == SIZE_4) { + result = list[0].concat(STR_SEPARATOR).concat(list[1]); + } else { + result = list[0]; + } + return result; + } else { + return EMPTY_STRING; + } + } + + /** + * Extracts right side of a string of the form "French text / English text".
    + * Separator slash may have *any* number (0+) of white spaces around them.
    + * Warning : The form may be "French text 1 / French text 2 / English text 1 / English text 2". and in this case, the two right sides are extracted. + * + * @param string {@link String} - the string value to check + * @return the "English side" (if any "side" exists), an empty string otherwise + */ + public static String english(final String string) { + if (string == null || string.isEmpty()) { + return EMPTY_STRING; + } + String[] list = string.split(REGEX_SEPARATOR); + if (list.length > 0) { + String result; + if (list.length == SIZE_2) { + result = list[FIRST_GROUP]; + } else if (list.length == SIZE_4) { + result = list[SECOND_GROUP].concat(STR_SEPARATOR).concat(list[THIRD_GROUP]); + } else { + result = list[0]; + } + return result; + } else { + return EMPTY_STRING; + } + } + + /** + * Allow to findAll name of a type object without suffix "Revision". + * + * @param nameItemRevision the name + * @return name of type object. + */ + public static String getNameTypeWithoutRevision(String nameItemRevision) { + Pattern pattern = Pattern.compile("(.*)( Revision)"); + Matcher matcher = pattern.matcher(nameItemRevision); + if (matcher.find()) { + return matcher.group(1); + } + return ""; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/common/ReflectionHelper.java b/teamcenter/src/main/java/com/capgemini/framework/common/ReflectionHelper.java new file mode 100644 index 0000000..a89127a --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/common/ReflectionHelper.java @@ -0,0 +1,93 @@ +package com.capgemini.framework.common; + +import lombok.extern.slf4j.Slf4j; + +import java.util.HashMap; +import java.util.Map; + +/** + * Utility class for reflection operations. + **/ +@Slf4j +public final class ReflectionHelper { + + /** + * Cache for getting class object using its name. + **/ + private static final Map> CACHED_CLASS_MAP = new HashMap<>(); + + /** + * Constructor. + **/ + private ReflectionHelper() { + // Constructor of helper classes must be private + } + + /** + * Dynamic instantiation of object using class name. + * + * @param aClassName Specific class name + * @return New object instance + */ + public static Object newFromClassForName(String aClassName) { + + Object theObj = null; + + Class theInvokedClass = getClassForName(aClassName); + if (theInvokedClass != null) { + theObj = newFromClass(theInvokedClass); + } + + return theObj; + } + + /** + * Dynamic instantiation of object using class. + * + * @param anInvokedClass Specific class + * @return New object instance + */ + private static Object newFromClass(Class anInvokedClass) { + + Object theObj = null; + if (anInvokedClass != null) { + // Try instantiation + try { + theObj = anInvokedClass.newInstance(); + } catch (InstantiationException e) { + log.error("Unable to create instance of: " + anInvokedClass.getName(), e); + } catch (IllegalAccessException e) { + log.error("Unable to access an instance of: " + anInvokedClass.getName(), e); + } + } + + return theObj; + } + + /** + * Dynamic creation of class using its name. + * + * @param aClassName Specific class name + * @return Searched class + */ + public static Class getClassForName(String aClassName) { + + // Try to retrieve the class from cache + Class theInvokedClass = CACHED_CLASS_MAP.get(aClassName); + + // Try class invocation when it has not been stored in cache yet + if (theInvokedClass == null) { + try { + // Run invocation + theInvokedClass = Class.forName(aClassName); + + // Save class in cache + CACHED_CLASS_MAP.put(aClassName, theInvokedClass); + } catch (ClassNotFoundException e) { + log.error("Unable to find class: " + aClassName, e); + } + } + + return theInvokedClass; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/common/StringHelper.java b/teamcenter/src/main/java/com/capgemini/framework/common/StringHelper.java new file mode 100644 index 0000000..5376606 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/common/StringHelper.java @@ -0,0 +1,228 @@ +package com.capgemini.framework.common; + +import java.util.Collection; +import java.util.Map; +import java.util.Map.Entry; +import java.util.StringTokenizer; + +/** Utility class for common String operations. **/ +public final class StringHelper { + private static final int DOT_ZERO_LENGTH = 2; + + /** Empty constant. **/ + public static final String EMPTY = ""; + + /** Line feed char constant. **/ + public static final char LINE_FEED = 0x000A; + + /** Tabulation char constant. **/ + public static final String DASH = "-"; + + /** + * Regular expression used for filtering non alpha numerical characters (dot and underscore are authorized). + **/ + public static final String REGEXP_ALPHANUM = "[^a-zA-Z0-9_.]"; + + /** Constructor. **/ + private StringHelper() { + // Constructor of helper classes must be private + } + + /** + * Truncate a string to a specified length. + * + * @param aString String to truncate + * @param aLength Maximal length of string + * @return truncated string + */ + public static String truncate(final String aString, final int aLength) { + + String truncatedString = null; + + // Manage null value + if (aString != null) { + if (aString.length() > aLength) { + truncatedString = aString.substring(0, aLength); + } else { + truncatedString = aString; + } + } + + return truncatedString; + } + + + /** + * Merge array elements in a single String. + * + * @param aDelimiter : Delimiter between each element of the array + * @param aStringArray : Array of string values + * @return Merged String + */ + public static String implode(final String aDelimiter, final String... aStringArray) { + StringBuilder theBuilder = null; + // Browse array elements for concatenation + for (String currentString : aStringArray) { + if (theBuilder == null) { + theBuilder = new StringBuilder(); + } else { + // Add separator + theBuilder.append(aDelimiter); + } + // Add next element + theBuilder.append(currentString == null ? "null" : currentString); + } + // By default return an empty string + if (theBuilder == null) { + return EMPTY; + } + return theBuilder.toString(); + } + + /** + * Merge array elements in a single String. + * + * @param aDelimiter : Delimiter between each element of the array + * @param aStringArray : Array of string values + * @return Merged String + */ + public static String implodeList(final String aDelimiter, final Collection aStringArray) { + StringBuilder theBuilder = null; + + // Browse array elements for concatenation + for (Object obj : aStringArray) { + + if (theBuilder == null) { + theBuilder = new StringBuilder(); + } else { + // Add separator + theBuilder.append(aDelimiter); + } + // Add next element + theBuilder.append(obj == null ? "null" : obj.toString()); + } + + // By default return an empty string + if (theBuilder == null) { + return EMPTY; + } + + return theBuilder.toString(); + } + + /** + * String concatenation of multiple strings. + * + * @param aStringArray Array of value which must be concatenated + * @return Concatenated value in a String + */ + public static String concatToString(final String... aStringArray) { + return concat(aStringArray).toString(); + } + + /** + * String concatenation of multiple strings. + * + * @param aStringArray Array of value which must be concatenated + * @return Concatenated value in a StringBuilder + */ + public static StringBuilder concat(final String... aStringArray) { + StringBuilder theBuilder = new StringBuilder(); + for (String currentValue : aStringArray) { + theBuilder.append(currentValue); + } + return theBuilder; + } + + /** + * Fill value with 0 to format a string number Example: 1 converted to 4 digits => "0001". + * + * @param aValue integer value + * @param aDigitCount digit size + * @return Formated string with the expected digits count + */ + public static String fixedDigits(final double aValue, final int aDigitCount) { + + String theStringConvertion = String.valueOf(aValue); + if (theStringConvertion.endsWith(".0")) { + theStringConvertion = truncate(theStringConvertion, theStringConvertion.length() - DOT_ZERO_LENGTH); + } + StringBuilder theStringBuilder = new StringBuilder(theStringConvertion); + + /* Zero fill */ + int missing0 = aDigitCount - theStringBuilder.length(); + if (missing0 > 0) { + String insertion = truncate("0000000000000000", missing0); + theStringBuilder.insert(0, insertion); + } + + return theStringBuilder.toString(); + } + + /** + * Javascript code conversion for attributes of the current bean. + * + * @param aJsArrayName Name of the javascript array + * @param aJavaBean Serialized JAVA bean + * @return JS code. + */ + public static String toJs(final String aJsArrayName, final Object aJavaBean) { + + StringBuilder theJsCode = new StringBuilder(aJsArrayName).append(" = new Array();\n"); + Map theAttMap = BeanHelper.toStringMap(aJavaBean); + for (Entry currentEntry : theAttMap.entrySet()) { + + /* Avoid quotes or line feed in displayable content */ + String theJsValue = currentEntry.getValue(); + theJsValue = StringHelper.toHtml(theJsValue); + + /* Compute the JS code for current attribute */ + StringBuilder currentAtt = concat(aJsArrayName, "['", currentEntry.getKey(), "']='", theJsValue, "';\n"); + + /* Append to attribute list */ + theJsCode.append(currentAtt); + } + + return theJsCode.append(LINE_FEED).toString(); + } + + /** + * Replace String values with the HTML format. + * + * @param anHtmlCode String to convert + * @return HTML code with entities + */ + public static String toHtml(final String anHtmlCode) { + String filtered = anHtmlCode.replace("'", "'"); + filtered = filtered.replace("\"", ""e;"); + filtered = filtered.replace("\n", "
    "); + return filtered; + } + + /** + * If the input is null, returns "". Otherwise, return the input. + * @param input the input String + * @return a never-null String + */ + public static String replaceNullByEmpty(String input) { + return input == null ? EMPTY : input; + } + + /** + * Split a string to an array from a pattern delimiter in parameter, and not return delimiter as a token. + * + * @param delimiter a delimiter for the successive splits + * @param value a full sentence to splits + * @return string array + */ + public static String[] splitWithoutDelim(final String delimiter, final String value) { + StringTokenizer tokens = new StringTokenizer(value, delimiter, false); + String[] result = new String[tokens.countTokens()]; + int tokenCount = 0; + while (tokens.hasMoreTokens()) { + result[tokenCount] = tokens.nextToken(); + tokenCount++; + } + return result; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/common/TeamcenterDateFormatter.java b/teamcenter/src/main/java/com/capgemini/framework/common/TeamcenterDateFormatter.java new file mode 100644 index 0000000..9055965 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/common/TeamcenterDateFormatter.java @@ -0,0 +1,161 @@ +package com.capgemini.framework.common; + +import lombok.extern.slf4j.Slf4j; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +/** This class formats Date for use with Teamcenter. */ +@Slf4j +public final class TeamcenterDateFormatter { + + /** Date Format of the form 'dd/MM/yyyy HH:mm:ss' which gives '2014/Apr/08 14:08:44' in US timezone. */ + public static final String DD_MM_YYYY_HH_MM_SS = "dd/MM/yyyy HH:mm:ss"; + /** Date Format of the form 'yyyy/MMM/dd' which gives '2014/Apr/08' in US timezone. */ + private static final String YYYY_MMM_DD = "yyyy/MMM/dd"; + /** Date Format of the form 'dd-MMMM-yyyy' which gives '08-April-2014' in US timezone. */ + private static final String DD_MMMM_YYYY = "dd MMMM yyyy"; + /** Date Format of the form 'dd-MMM-yyyy' which gives '08-Apr-2014' in US timezone. */ + private static final String DD_MMM_YYYY = "dd-MMM-yyyy"; + /** Date Format of the form 'dd-MM-yyyy' which gives '08-04-2014'. */ + public static final String DD_MM_YYYY = "dd-MM-yyyy"; + /** Date Format of the form 'dd-MM-yyyy HH:mm' which gives '08-07-2014 10:12'. */ + public static final String DD_MM_YYYY_HH_MM = DD_MM_YYYY + " HH:mm"; + /** Date Format of the form 'yyyyMMdd' which gives '20140408'. */ + public static final String YYYYMMDD = "yyyyMMdd"; + /** Date Format of the form 'YYYYMMDD_hhmmss' which gives '20140408_140844'. */ + public static final String YYYYMMDD_HHMMSS = "yyyyMMdd_HHmmss"; + + private static final Locale LOCAL_US = Locale.US; + private static final String TIME_ZONE_PARIS = "Europe/Paris"; + + private TeamcenterDateFormatter() { + // Private to make this class a Helper. + } + + /** + * Returns the current time with format "dd/MM/yyyy HH:mm:ss". + * + * @return a String + */ + public static String getCurrentTime() { + DateFormat dateFormat = new SimpleDateFormat(DD_MM_YYYY_HH_MM_SS); + Calendar cal = Calendar.getInstance(); + return dateFormat.format(cal.getTime()); // ex: "01/09/2014 16:00:22" + } + + /** + * Make an object Calendar for Teamcenter 10 with String parameter format : dd-MM-yyyy. + * + * @param aDate a string date to parseformat + * @return calendar + */ + public static Calendar makeTeamcenterCalendar(final String aDate) { + if (aDate == null || aDate.isEmpty()) { + return Calendar.getInstance(); + } else { + SimpleDateFormat curFormater = new SimpleDateFormat(DD_MM_YYYY); + try { + Date dateObj = curFormater.parse(aDate); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(dateObj); + calendar.set(Calendar.HOUR, 23); + calendar.set(Calendar.MINUTE, 59); + calendar.set(Calendar.SECOND, 59); + return calendar; + } catch (ParseException e) { + log.error("WRONG format: " + aDate + ", expecting " + DD_MM_YYYY + " defaulting to current date", e); + return Calendar.getInstance(); + } + } + } + + /** + * Takes a {@link Calendar} and formats it to 'dd-MMM-yyyy' using {@link Locale#US} for use in the Saved Query of Teamcenter 10. + * + * @param inputDate (may be null, to represent 'NOW') + * @return a String showing the date in the new format + */ + public static synchronized String translateDateFormatForRequest(final Calendar inputDate) { + return new SimpleDateFormat(DD_MMM_YYYY, LOCAL_US).format(inputDate == null ? Calendar.getInstance().getTime() : inputDate.getTime()); + } + + /** + * Takes a date with format 'dd-MM-yyyy' and formats it to 'dd-MMM-yyyy' for Saved Query of Teamcenter 10. + * + * @param inputDate with this format: dd-MM-yyyy (may be null, to represent 'NOW') + * @return a String showing the date in the new format + */ + public static String translateDateFormatForRequest(final String inputDate) { + // format type + SimpleDateFormat dateFormatInput = new SimpleDateFormat(DD_MM_YYYY); + SimpleDateFormat dateFormatOutput = new SimpleDateFormat(DD_MMM_YYYY, LOCAL_US); + + if (inputDate == null || inputDate.isEmpty()) { + return dateFormatOutput.format(Calendar.getInstance().getTime()); + } else { + try { + Date dateInputParsed = dateFormatInput.parse(inputDate); + return dateFormatOutput.format(dateInputParsed); + } catch (ParseException e1) { + log.error("WRONG format : expecting " + DD_MMM_YYYY, e1); + return DD_MMM_YYYY; + } + } + } + + /** + * Format a date based on a pattern : yyyy/MMM/dd. + * + * @param calendar a Calendar to fromat + * @return date as a String + */ + public static String formatCalendarYearMonthDay(final Calendar calendar) { + SimpleDateFormat sdf = new SimpleDateFormat(YYYY_MMM_DD); + return sdf.format(calendar.getTime()); + } + + /** + * Format a date based on a pattern parameter. + * + * @param calendar a Calendar to format + * @param patternDate a format pattern + * @return date as a String + */ + public static String formatCalendarToPattern(final Calendar calendar, final String patternDate) { + try { + return new SimpleDateFormat(patternDate).format(calendar.getTime()); + } catch (IllegalArgumentException e) { + log.warn("Invalid Date Format received (\"" + patternDate + "\"), defaulting to dd_MM_yyyy", e); + return new SimpleDateFormat(DD_MM_YYYY).format(calendar.getTime()); + } + } + + /** + * Formats a date based on the following pattern : 'dd mmmm yyyy' , also using {@link TimeZone}: Europe (Paris) and french {@link Locale}. + * + * @param calendar a Calendar to format to french + * @return dateFormatFR + */ + public static String formatCalendarToFrench(final Calendar calendar) { + SimpleDateFormat sdf = new SimpleDateFormat(DD_MMMM_YYYY, Locale.FRENCH); + sdf.setTimeZone(getParisTimeZone()); + Calendar theCalendar = calendar == null ? Calendar.getInstance() : calendar; + return sdf.format(theCalendar.getTime()); + } + + /** + * Returns the Paris {@link TimeZone}. + * + * @return a {@link TimeZone} + */ + public static TimeZone getParisTimeZone() { + return TimeZone.getTimeZone(TeamcenterDateFormatter.TIME_ZONE_PARIS); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/common/security/AesEncoded.java b/teamcenter/src/main/java/com/capgemini/framework/common/security/AesEncoded.java new file mode 100644 index 0000000..cb59b9d --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/common/security/AesEncoded.java @@ -0,0 +1,39 @@ +package com.capgemini.framework.common.security; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import sun.misc.BASE64Decoder; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.SecretKeySpec; +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +/** + * This program generates a AES key, retrieves its raw bytes, and then reinstantiates a AES key from the key bytes. The + * reinstantiated key is used to initialize a AES cipher for encryption and decryption. + */ +public class AesEncoded { + private final String encodedText; + + public AesEncoded(final String encodedText) { + this.encodedText = encodedText; + } + + /** + * Décodage d'une chaine de caractères suivant le cryptage défini. + */ + public String decode() throws KurtException { + try { + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec("pvsir123niabppq6".getBytes(), "AES")); + return new String(cipher.doFinal(new BASE64Decoder().decodeBuffer(encodedText))); + } + catch (NoSuchPaddingException | IOException | NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) { + throw new KurtException("Error decoding the string " + encodedText, e); + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/ServiceDataHelper.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/ServiceDataHelper.java new file mode 100644 index 0000000..7bc882b --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/ServiceDataHelper.java @@ -0,0 +1,72 @@ +package com.capgemini.framework.teamcenter; + +import com.teamcenter.soa.client.model.ErrorStack; +import com.teamcenter.soa.client.model.ErrorValue; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.ServiceData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ServiceDataHelper { + private static final Logger LOGGER = LoggerFactory.getLogger(ServiceDataHelper.class); + + private ServiceDataHelper() { + // utility + } + + /** + * Check if the service data has errors. + * + * @param serviceData + * ServiceData instance + * @return True when no error occurs, else return false + */ + public static boolean hasErrors(final ServiceData serviceData) { + return serviceData.sizeOfPartialErrors() > 0; + } + + /** + * Log potential errors throw from a service data. + * + * @param serviceData + * ServiceData instance + * @return True when no error occurs, else return false + */ + public static void displayErrors(final ServiceData serviceData) { + LOGGER.debug("Error count: {}", serviceData.sizeOfPartialErrors()); + for (int i = 0; i < serviceData.sizeOfPartialErrors(); i++) { + displayError(serviceData.getPartialError(i)); + } + } + + /** + * Display error stack from service data. + * + * @param errorStack Stack error from service + */ + private static void displayError(final ErrorStack errorStack) { + LOGGER.debug("Error stack from client: clientIndex = {}, clientId = {}", errorStack.getClientIndex(), + errorStack.getClientId()); + ModelObject associatedObject = errorStack.getAssociatedObject(); + StringBuilder theLogBuilder = new StringBuilder(); + if (associatedObject != null) { + theLogBuilder.append("object UID = [").append(associatedObject.getUid()).append("]"); + } else { + theLogBuilder.append("associatedObject = [null]"); + } + LOGGER.debug(" " + theLogBuilder.toString()); + + ErrorValue[] errorValues = errorStack.getErrorValues(); + if (errorValues == null) { + return; + } + for (ErrorValue currentErrorVal : errorValues) { + if (currentErrorVal != null) { + LOGGER.debug(" errVal :"); + LOGGER.debug(" code = {}", currentErrorVal.getCode()); + LOGGER.debug(" level = {}", currentErrorVal.getLevel()); + LOGGER.debug(" msg = {}", currentErrorVal.getMessage()); + } + } + } +} \ No newline at end of file diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/TeamcenterObjectProperties.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/TeamcenterObjectProperties.java new file mode 100644 index 0000000..0360a5b --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/TeamcenterObjectProperties.java @@ -0,0 +1,146 @@ +package com.capgemini.framework.teamcenter; + +import com.teamcenter.soa.client.model.strong.*; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +/** + * Class regrouping all the properties for objects. + */ +@Slf4j +@EqualsAndHashCode +public class TeamcenterObjectProperties { + + /** + * Property for retrieving all the tasks associated to a Change. + */ + public static final String PROCESS_STAGE_LIST = "process_stage_list"; + /** + * Child tasks of an EPMTask. + */ + public static final String CHILD_TASKS = "child_tasks"; + /** + * List of target objects of an EPMTask. + */ + public static final String ROOT_TARGET_ATTACHMENTS = "root_target_attachments"; + /** + * List of all signoffs attached to an EPMTask. + */ + public static final String SIGNOFF_ATTACHMENTS = "signoff_attachments"; + /** + * Property for retrieving the {@link User} who last modified an object. + */ + public static final String LAST_MOD_USER = "last_mod_user"; + /** + * Property for retrieving the date at which an object was last modified. + */ + public static final String LAST_MOD_DATE = "last_mod_date"; + /** + * Property for retrieving the 'State' of an {@link EPMTask}. + */ + public static final String STATE = "state"; + /** + * Property for retrieving the valid signoffs of a task. + */ + public static final String VALID_SIGNOFFS = "valid_signoffs"; + /** + * End item of an Effectivity. Usually, a Product ID. + */ + public static final String END_ITEM = "end_item"; + /** + * Property for retrieving the main object associated to a TC {@link BOMLine}. + */ + public static final String BL_LINE_OBJECT = "bl_line_object"; + /** + * Property for retrieving the sequence_id of an Object. + */ + public static final String SEQUENCE_ID = "sequence_id"; + /** + * Property for retrieving the date released on a ReleaseStatus. + */ + public static final String DATE_RELEASED = "date_released"; + /** + * Property for retrieving the creationDate of an Object. + */ + public static final String CREATION_DATE = "creation_date"; + /** + * Property for retrieving the ID of an Item. + */ + public static final String ITEM_ID = "item_id"; + /** + * Property for retrieving the revision of an ItemRevision. + */ + public static final String ITEM_REVISION_ID = "item_revision_id"; + /** + * Property for retrieving the list of revision of an Item. + */ + public static final String REVISION_LIST = "revision_list"; + /** + * Property for retrieving the name of a ReleaseStatus. + */ + public static final String NAME = "name"; + /** + * Property for retrieving the name of a ModelObject. + */ + public static final String OBJECT_NAME = "object_name"; + /** + * Property for retrieving the Item of an ItemRevision. + */ + public static final String ITEMS_TAG = "items_tag"; + /** + * Property for retrieving the form of an Item or an ItemRevision. + */ + public static final String ITEM_MASTER_TAG = "item_master_tag"; + /** + * Property for retrieving the direct children of a RF Part Assemb Revision. + */ + public static final String ASSEMBLY_BOM = "AssemblyBom"; + /** + * Property for retrieving the direct children of a RF Part Revision. + */ + public static final String RF_PART_BOM = "RFPartBom"; + /** + * Property for retrieving the 'owning user'. + */ + public static final String OWNING_USER = "owning_user"; + /** + * Property for retrieving the 'user_name'. + */ + public static final String USER_NAME = "user_name"; + /** + * Property for retrieving the 'id'. + */ + public static final String USER_ID = "user_id"; + /** + * Property for retrieving the {@link Person} of a {@link User}. + */ + public static final String PERSON = "person"; + /** + * Property for Decision status on Signoff objects. + */ + public static final String DECISION = "decision"; + /** + * Property for 'Ligne Produit' on every Change Objects. + */ + public static final String PROP_LIGNE_PRODUIT = "pv4_ligne_produit"; + /** + * Property for retrieving the documents in the pseudofolder "Represented by". + */ + public static final String TC_IS_REPRESENTED_BY = "TC_Is_Represented_By"; + + + protected TeamcenterObjectProperties() { + // protected <-- because ObjectProperties will extend this class + } + + /** + * Get item id for an item. + * + * @param item the Item to search + * @return item id + */ + public static String getItemIdOrNull(final Item item) { + return item.get_item_id(); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/TeamcenterObjectTypes.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/TeamcenterObjectTypes.java new file mode 100644 index 0000000..a38956a --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/TeamcenterObjectTypes.java @@ -0,0 +1,83 @@ +package com.capgemini.framework.teamcenter; + +import com.teamcenter.soa.client.model.Type; + +import java.util.Arrays; +import java.util.regex.Pattern; + +/** Class regrouping all the used type of Teamcenter Revision objects. */ +public class TeamcenterObjectTypes { + + protected TeamcenterObjectTypes() { + // Move along, nothing to see + } + + // Some more frequent suffixes + protected static final String REVISION = " Revision"; + protected static final String MASTER = " Master"; + + /** The WokspaceObject type. */ + public static final String WORSKPACE_OBJECT = "WorkspaceObject"; + /** The Teamcenter type for a ReleaseStatus. */ + public static final String RELEASE_STATUS = "ReleaseStatus"; + /** The Teamcenter Item Revision. */ + public static final String ITEM_REVISION = "ItemRevision"; + /** The Teamcenter type for an EPMTask (workflow task). */ + public static final String EPM_TASK = "EPMTask"; + /** The Teamcenter type for an EPMPerformSignoffTask (workflow task). */ + public static final String EPM_PERFORM_SIGNOFF_TASK = "EPMPerformSignoffTask"; + /** The Teamcenter type for an EPMDoTask (workflow task). */ + public static final String EPM_DO_TASK = "EPMDoTask"; + /** The Teamcenter type for a Signoff (Action of a User on a task). */ + public static final String SIGNOFF = "Signoff"; + /** The Teamcenter type for a User. */ + public static final String USER = "User"; + /** The Teamcenter type for a Person. */ + public static final String PERSON = "Person"; + /** The Teamcenter type for a Change Item Revision. */ + public static final String CHANGE_ITEM_REVISION = "ChangeItemRevision"; + /** The Teamcenter type for a Change Request Revision. */ + public static final String CHANGE_REQUEST_REVISION = "ChangeRequestRevision"; + /** The Teamcenter type for a Change Notice Revision. */ + public static final String CHANGE_NOTICE_REVISION = "ChangeNoticeRevision"; + /** The Teamcenter type for a mockup. */ + public static final String MOCKUP = "Mockup"; + /** The Teamcenter type for a mockup revision. */ + public static final String MOCKUP_REVISION = MOCKUP + REVISION; + /** The Teamcenter type for a mockup revision. */ + public static final String MOCKUP_REVISION_MASTER = MOCKUP + REVISION + MASTER; + /** Link from Item to Dataset. */ + public static final String IMAN_SPECIFICATION = "IMAN_specification"; + /** Link from Part PV to Fiche Article. */ + public static final String IMAN_REQUIREMENT = "IMAN_requirement"; + /** Link from Part PV to Fiche Article. */ + public static final String IMAN_REFERENCE = "IMAN_reference"; + + /** + * Returns true if the provided object type String matches a provided item type. + * + * @param objectType the String describing the object type to be tested + * @param authorizedTypes a series of authorized String Types + * @return true if the object type matches any of the provided types, false otherwise + */ + public static boolean isA(final String objectType, final String... authorizedTypes) { + for (String type : authorizedTypes) { + if (Pattern.matches("^(" + type + ")$", objectType)) { + return true; + } + } + return false; + } + + /** + * Verify (recursively) if the candidate {@link Type} is a type (or super type of) the Tc target Class. + * + * @param targetClass the target class name + * @param candidate the candidate Tc {@link Type} + * @return true if any of the super types of the candidate matches the target class name + */ + public static boolean isRecursively(String targetClass, Type candidate) { + return Arrays.asList(candidate.getClassNameHierarchy()).contains(targetClass); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/authent/AuthentPropLoader.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/authent/AuthentPropLoader.java new file mode 100644 index 0000000..11f4b0f --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/authent/AuthentPropLoader.java @@ -0,0 +1,92 @@ +package com.capgemini.framework.teamcenter.authent; + +import lombok.extern.slf4j.Slf4j; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +/** + * Utility class required for loading properties used by teamcenter session authentication. + **/ +@Slf4j +public final class AuthentPropLoader { + + private static final String KURT_PROP_FILENAME = "/reporting.properties"; + private static Properties tcProperties; + + /** + * Constructor. + **/ + private AuthentPropLoader() { + // Utility classes should not have a public constructor + } + + /** + * Retrieve the properties and load them if needed. + * + * @return Property content of file + **/ + private static synchronized Properties getPropLoader() { + // Check if the property file has been already loaded + if (tcProperties == null) { + tcProperties = new Properties(); + try (InputStream thePropStream = readPropertiesFile()) { + tcProperties.load(thePropStream); + } catch (IOException e) { + log.error("Unable to load properties file", e); + } + } + return tcProperties; + } + + // Try to access file in the configuration folder of JBOSS, else use by default the file provided in EAR + private static InputStream readPropertiesFile() { + String theJbossConfPath = System.getenv("JBOSS_HOME") + "/standalone/configuration" + KURT_PROP_FILENAME; + boolean isConfFile = new File(theJbossConfPath).exists(); + if (isConfFile) { + log.debug("JBOSS configuration file has been found in: " + theJbossConfPath); + try { + return new FileInputStream(theJbossConfPath); + } catch (FileNotFoundException e) { + log.error("Unable to load file: " + theJbossConfPath, e); + } + } + // default: JBoss file does not exist or not readable + log.warn("EAR file will be used, no configuration file found in: " + theJbossConfPath); + return AuthentPropLoader.class.getResourceAsStream(KURT_PROP_FILENAME); + } + + /** + * Getter for the property value corresponding to the property key. + * + * @param aPropKey Property key reference + * @return Property value + */ + public static String getString(final String aPropKey) { + return getPropLoader().getProperty(aPropKey); + } + + /** + * Returns an array of symbol-separated values. + * + * @param aPropKey the property name + * @param separator the separator symbol + * @return an array of Strings. Empty array if an empty string was found + */ + public static String[] getStringArray(final String aPropKey, String separator) { + String raw = System.getProperty(aPropKey); + if (raw == null || raw.isEmpty()) { + log.warn("No property array found in tc properties for key " + aPropKey); + return new String[0]; + } + List result = new ArrayList<>(); + for (String tmp : raw.split(separator)) { + if (!tmp.isEmpty()) { + result.add(tmp); + } + } + return result.toArray(new String[result.size()]); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/authent/FscParameters.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/authent/FscParameters.java new file mode 100644 index 0000000..9c0263b --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/authent/FscParameters.java @@ -0,0 +1,20 @@ +package com.capgemini.framework.teamcenter.authent; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** Simple holder class for all data regarding connection to FSC service. */ +@Getter +@AllArgsConstructor +public class FscParameters { + + /** Connection to FSC. */ + private final String clientIPAddress; + /** FSC assigned URL. */ + private final String[] assignedFscURIs; + /** FSC bootstrap URL. */ + private final String[] bootstrapFscURIs; + /** Local cache directory. */ + private final String cacheDir; + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/authent/KurtModelEventListener.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/authent/KurtModelEventListener.java new file mode 100644 index 0000000..2ab0edf --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/authent/KurtModelEventListener.java @@ -0,0 +1,57 @@ +package com.capgemini.framework.teamcenter.authent; + +import com.teamcenter.soa.client.model.ModelEventListener; +import com.teamcenter.soa.client.model.ModelObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; + +/** + * Events logger: object creation, modification and suppression trigger a call to this object's corresponding method. + */ +public class KurtModelEventListener extends ModelEventListener { + private static final Logger LOGGER = LoggerFactory.getLogger(KurtModelEventListener.class); + + @Override + public void localObjectCreate(ModelObject[] createdObjs) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Local objects created: {}", Arrays.toString(createdObjs)); + } + } + + @Override + public void localObjectChange(ModelObject[] changedObjs) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Local objects modified: {}", Arrays.toString(changedObjs)); + } + } + + @Override + public void localObjectDelete(String[] uids) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Local objects deleted: {}", Arrays.toString(uids)); + } + } + + @Override + public void sharedObjectCreate(ModelObject[] createdObjs) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Shared objects created: {}", Arrays.toString(createdObjs)); + } + } + + @Override + public void sharedObjectChange(ModelObject[] changedObjs) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Shared objects modified: {}", Arrays.toString(changedObjs)); + } + } + + @Override + public void sharedObjectDelete(String[] uids) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Shared objects deleted: {}", Arrays.toString(uids)); + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/authent/TcCredentialManager.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/authent/TcCredentialManager.java new file mode 100644 index 0000000..9c9767d --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/authent/TcCredentialManager.java @@ -0,0 +1,77 @@ +package com.capgemini.framework.teamcenter.authent; + +import com.teamcenter.schemas.soa._2006_03.exceptions.InvalidCredentialsException; +import com.teamcenter.schemas.soa._2006_03.exceptions.InvalidUserException; +import com.teamcenter.services.strong.core.SessionService; +import com.teamcenter.soa.client.CredentialManager; +import com.teamcenter.soa.client.model.strong.GroupMember; + +/** + * The CredentialManager is used by the Teamcenter Services framework to findAll the user's credentials when challenged by the server. This can occur after a period of inactivity and the server has timed-out the user's session, at which time the client application will need to re-authenticate. The + * framework will call one of the getCredentials methods (depending on circumstances) and will send the SessionService.login service request. Upon successful completion of the login service request. The last service request (one that caused the challenge) will be resent. + *

    + * The framework will also call the setUserPassword setGroupRole methods when ever these credentials change, thus allowing this implementation of the CredentialManager to cache these values so prompting of the user is not required for re-authentication. + */ +public class TcCredentialManager implements CredentialManager { + + private String name; + private String password; + private String discriminator; + private String group = ""; + private String role = ""; + + // always connect same user to same instance of server + + /** + * Return the type of credentials this implementation provides, standard (user/password) or Single-Sign-On. In this case Standard credentials are returned. + * + * @see com.teamcenter.soa.client.CredentialManager#getCredentialType() + */ + @Override + public int getCredentialType() { + return CredentialManager.CLIENT_CREDENTIAL_TYPE_STD; + } + + /** + * Prompts the user for credentials. This method will only be called by the framework when a login attempt has failed. + * + * @see com.teamcenter.soa.client.CredentialManager#getCredentials(com.teamcenter.schemas.soa._2006_03.exceptions.InvalidCredentialsException) + */ + @Override + public String[] getCredentials(final InvalidCredentialsException anException) { + return new String[]{name, password, group, role, discriminator}; + } + + /** + * Return the cached credentials. This method will be called when a service request is sent without a valid session ( session has expired on the server). + * + * @see com.teamcenter.soa.client.CredentialManager#getCredentials(com.teamcenter.schemas.soa._2006_03.exceptions.InvalidUserException) + */ + @Override + public String[] getCredentials(final InvalidUserException anException) { + return new String[]{name, password, group, role, discriminator}; + } + + /** + * Cache the group and role. This is called after the {@link SessionService#setSessionGroupMember(GroupMember)} service operation is called. + * + * @see com.teamcenter.soa.client.CredentialManager#setGroupRole(java.lang.String, java.lang.String) + */ + @Override + public void setGroupRole(final String group, final String role) { + this.group = group; + this.role = role; + } + + /** + * Cache the User and Password This is called after the SessionService.login service operation is called. + * + * @see com.teamcenter.soa.client.CredentialManager#setUserPassword(java.lang.String, java.lang.String, java.lang.String) + */ + @Override + public void setUserPassword(final String user, final String password, final String discriminator) { + this.name = user; + this.password = password; + this.discriminator = discriminator; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/authent/TcExceptionHandler.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/authent/TcExceptionHandler.java new file mode 100644 index 0000000..b71de44 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/authent/TcExceptionHandler.java @@ -0,0 +1,108 @@ +package com.capgemini.framework.teamcenter.authent; + +import com.capgemini.framework.teamcenter.exceptions.runtime.ConnectionLostException; +import com.teamcenter.schemas.soa._2006_03.exceptions.ConnectionException; +import com.teamcenter.schemas.soa._2006_03.exceptions.InternalServerException; +import com.teamcenter.schemas.soa._2006_03.exceptions.ProtocolException; +import com.teamcenter.soa.client.ExceptionHandler; +import com.teamcenter.soa.exceptions.CanceledOperationException; +import lombok.extern.slf4j.Slf4j; + +/** Implementation of the ExceptionHandler for Teamcenter requests. **/ +@Slf4j +public class TcExceptionHandler implements ExceptionHandler { + + /** If delay between two Exceptions is higher than this, then the two exceptions are non-related, so we can restart the countdown, ms. */ + private static final long MAX_INTERVAL_BETWEEN_BREAKUPS = 60 * 60 * 1000; // 60 minutes + /** Number maximum of consecutive retries before fatal exception is thrown. */ + private static final int MAX_COUNTDOWN = 10; + /** Wait time between consecutive retries, ms. */ + private static final int WAIT_BETWEEN_RETRIES_MS = 10000; // 10s + + long firstErrorTimeMillis; + int countdown; + + /** + * Creates an Exception Handler.
    + * The typical behaviour of this handler when subject to an {@link InternalServerException} is the following: + *

      + *
    • If the exception is a {@link ProtocolException}, a RuntimeException is thrown to interrupt report generation, as these ProtocolException are usually not recoverable from.
    • + *
    • If the exception is a {@link ConnectionException}, then the following happens: + *
        + *
      1. The connection is retried after a delay of
      2. + *
      3. + *
      + *
    • + *
    • Otherwise the exception is an unknown InternalServerException, a RuntimeException (actually a {@link ConnectionLostException}) is thrown
    • + *
    + */ + public TcExceptionHandler() { + firstErrorTimeMillis = System.currentTimeMillis(); + countdown = 0; + } + + /** + * Takes care of {@link InternalServerException}s. + * + * @see com.teamcenter.soa.client.ExceptionHandler#handleException(com.teamcenter.schemas.soa._2006_03.exceptions.InternalServerException) + */ + @Override + public void handleException(final InternalServerException anException) { + if (anException instanceof ProtocolException) { + // ProtocolException are typically due to programming errors (content of HTTP request is incorrect). These generally cannot be recovered from. + throw new ConnectionLostException("Internal Teamcenter ProtocolException encountered, not recoverable", anException); + } + else if (anException instanceof ConnectionException) { + handleTemporaryConnectionException((ConnectionException) anException); + } + else { + throw new ConnectionLostException("InternalServerException encountered, not recoverable", anException); + } + } + + private void handleTemporaryConnectionException(final ConnectionException anException) { + // ConnectionException are typically due to a network error (server down .etc) and can be recovered from (the last request can be sent again, after the problem is corrected). + long time = System.currentTimeMillis(); + if (time > MAX_INTERVAL_BETWEEN_BREAKUPS + firstErrorTimeMillis) { + // This is the first Exception of a new series of errors + countdown = 0; + firstErrorTimeMillis = time; + log.error("The teamcenter server returned an protocol error: " + anException.getMessage(), anException); + } + else { + // This is the continuation of an on-going series of error, so we increment the countdown + countdown++; + } + if (countdown > MAX_COUNTDOWN) { + // The maximum number of consecutive errors has been reached, the connection is definitely lost, let's findAll out of here! + throw new ConnectionLostException("Maximum number of retries reached during connection loss", anException); + } + else { + // To let the TC servers time to recover, let's wait a bit + try { + String msg = "A series of " + countdown + + " errors from the Teamcenter servers has been detected. A retry will be attempted within " + + WAIT_BETWEEN_RETRIES_MS + "ms. Last exception encountered: " + anException.getMessage(); + log.error(msg, anException); + Thread.sleep(WAIT_BETWEEN_RETRIES_MS); + } + catch (InterruptedException e) { + log.info("Exception handler was interrupted during sleep, while awaiting to recover from a previous connection exception (" + + anException.getMessage() + ")", e); // Oh, the irony! + } + } + // Continuing normally will eventually lead to re-trying to perform the operation that did not succeed because of the InternalServerException + } + + /** + * Takes care of {@link CanceledOperationException}s. + * + * @see com.teamcenter.soa.client.ExceptionHandler#handleException(com.teamcenter.soa.exceptions.CanceledOperationException) + */ + @Override + public void handleException(final CanceledOperationException aCanceledOpException) { + log.error("Teamcenter server returned a CanceledOperationException:\nIt could be caused by invalid credential during login operation", + aCanceledOpException); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/authent/TcSession.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/authent/TcSession.java new file mode 100644 index 0000000..0d8b38f --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/authent/TcSession.java @@ -0,0 +1,716 @@ +package com.capgemini.framework.teamcenter.authent; + +import com.capgemini.framework.common.security.AesEncoded; +import com.capgemini.framework.teamcenter.ServiceDataHelper; +import com.capgemini.framework.teamcenter.exceptions.ConnectionMisconguredException; +import com.capgemini.framework.teamcenter.exceptions.FailedRelationshipActionException; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.MalformedDataSetException; +import com.capgemini.framework.teamcenter.exceptions.NoSuchRevisionRuleException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.exceptions.runtime.ConnectionLostException; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRule; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindow; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindowConfiguration; +import com.capgemini.framework.teamcenter.object.runtime.TcBomWindowFactory; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.teamcenter.schemas.soa._2006_03.exceptions.InvalidCredentialsException; +import com.teamcenter.schemas.soa._2006_03.exceptions.ServiceException; +import com.teamcenter.services.loose.core._2006_03.FileManagement.DatasetFileInfo; +import com.teamcenter.services.loose.core._2006_03.FileManagement.GetDatasetWriteTicketsInputData; +import com.teamcenter.services.strong.cad.StructureManagementService; +import com.teamcenter.services.strong.cad._2007_01.StructureManagement.GetRevisionRulesResponse; +import com.teamcenter.services.strong.cad._2007_01.StructureManagement.RevisionRuleInfo; +import com.teamcenter.services.strong.core.DataManagementService; +import com.teamcenter.services.strong.core.SessionService; +import com.teamcenter.services.strong.core._2006_03.DataManagement.CreateRelationsResponse; +import com.teamcenter.services.strong.core._2006_03.DataManagement.Relationship; +import com.teamcenter.services.strong.core._2007_01.DataManagement.WhereReferencedInfo; +import com.teamcenter.services.strong.core._2007_01.DataManagement.WhereReferencedOutput; +import com.teamcenter.services.strong.core._2007_01.DataManagement.WhereReferencedResponse; +import com.teamcenter.services.strong.core._2007_12.Session.StateNameValue; +import com.teamcenter.services.strong.core._2010_04.DataManagement.CreateDatasetsResponse; +import com.teamcenter.services.strong.core._2010_04.DataManagement.DatasetInfo; +import com.teamcenter.services.strong.core._2010_09.DataManagement.NameValueStruct1; +import com.teamcenter.services.strong.core._2010_09.DataManagement.PropInfo; +import com.teamcenter.services.strong.core._2010_09.DataManagement.SetPropertyResponse; +import com.teamcenter.services.strong.core._2011_06.Session.Credentials; +import com.teamcenter.services.strong.core._2011_06.Session.LoginResponse; +import com.teamcenter.services.strong.core._2012_02.DataManagement.WhereUsedConfigParameters; +import com.teamcenter.services.strong.core._2012_02.DataManagement.WhereUsedInputData; +import com.teamcenter.services.strong.core._2012_02.DataManagement.WhereUsedParentInfo; +import com.teamcenter.services.strong.core._2012_02.DataManagement.WhereUsedResponse; +import com.teamcenter.services.strong.query.FinderService; +import com.teamcenter.services.strong.query.SavedQueryService; +import com.teamcenter.services.strong.workflow.WorkflowService; +import com.teamcenter.soa.SoaConstants; +import com.teamcenter.soa.client.Connection; +import com.teamcenter.soa.client.FileManagementUtility; +import com.teamcenter.soa.client.model.ErrorStack; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.ServiceData; +import com.teamcenter.soa.client.model.strong.ImanRelation; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.RevisionRule; +import com.teamcenter.soa.client.model.strong.User; +import com.teamcenter.soa.client.model.strong.WorkspaceObject; +import com.teamcenter.soaictstubs.ICCTRevisionRule; +import com.teamcenter.soaictstubs.ICCTSession; +import com.teamcenter.soaictstubs.StringHolder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Closeable; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + + +/** + * Teamcenter connection management. + **/ +public class TcSession implements Closeable { + /** + * Default user login. + **/ + private static final String USERNAME = System.getProperty("teamcenter.session.login"); // Prefix is required + private static final Logger LOGGER = LoggerFactory.getLogger(TcSession.class); + /** + * Teamcenter server URL. + **/ + private static final String URL = System.getProperty("teamcenter.url"); + private static final String ERROR_MSG_UNABLE_TO_OBTAIN_SESSION_INFO_TC_SERVER_ID = "Unable to obtain usual session info: TcServerID"; + private static final String TC_SERVER_ID = "TcServerID"; + private static final int TIMEOUT_SEC = 120; + private static final String ERROR_MSG_LOGIN_TIMEOUT = "Timed out during login to Tc Servers after " + TIMEOUT_SEC + "sec"; + /** + * Default user password. + **/ + private static final String PASSWORD = System.getProperty("teamcenter.session.password"); // Prefix is required + + private static final String FSC_CLIENT_IP = System.getProperty("fsc.clientip"); // Prefix is required + private static final String FSC_CACHE_DIR = System.getProperty("fsc.cachedir"); // Prefix is required + private static final String[] FSC_ASSIGNED_URI = AuthentPropLoader.getStringArray("fsc.assignedURI", ","); // Prefix is required + private static final String[] FSC_BOOTSTRAP_URI = AuthentPropLoader.getStringArray("fsc.bootstrapURI", ","); // Prefix is required + private static final FscParameters DEFAULT_FSC_PARAMS = new FscParameters(FSC_CLIENT_IP, FSC_ASSIGNED_URI, FSC_BOOTSTRAP_URI, FSC_CACHE_DIR); + private final FscParameters fscParams; + /** + * Single instance of the Connection object that is shared throughout the application.
    + * This Connection object is needed whenever a Service stub is instantiated. + */ + private Connection connection; + + /** + * Connection status. Helps prevent double-logout, double login, or logout without prior login. + */ + private LoginResponse loggedIn; + /** + * Common service for structure resolutions. Lazily initialized, use getter method. + **/ + private StructureManagementService structureManagementService; + /** + * Common service for finding records in Teamcenter. Lazily initialized, use getter method. + **/ + private FinderService finderService; + /** + * Saved Query Service. Lazily initialized, use getter method. + */ + private SavedQueryService savedQueryService; + /** + * file Management Utility. Lazily initialized, use getter method. + */ + private FileManagementUtility fileManagementUtility; + /** + * Worfklow service. Lazily initialized, use getter method. + */ + private WorkflowService workflowService; + private String discriminator; + + /** + * Default constructor using settings from properties. + **/ + public TcSession() { + this(URL, DEFAULT_FSC_PARAMS); + } + + /** + * Create an instance of the Session with a connection to the specified server. + *

    + * Add implementations of the ExceptionHandler, PartialErrorListener, ChangeListener, and DeleteListeners. + * + * @param aConnectionUrl Address of the host to connect to, http://serverName:port/tc + * @param fscParameters the FSC connection parameters + */ + public TcSession(final String aConnectionUrl, final FscParameters fscParameters) { + this.fscParams = fscParameters; + initHostConnection(aConnectionUrl); + } + + /** + * Connection status. + * + * @return true if the connection is logged in. + */ + private boolean isLoggedIn() { + return loggedIn != null; + } + + /** + * Create an instance of the CredentialManager.
    + * This is used by the SOA Framework to findAll the user's credentials when challenged by the server
    + * (session timeout on the web tier). + **/ + private void initHostConnection(final String aConnectionUrl) { + TcCredentialManager credentialManager = new TcCredentialManager(); + LOGGER.debug("Initialize connection to URL: {}", aConnectionUrl); + String connectionUrl; + String protocol; + String envNameTccs = null; + if (aConnectionUrl.startsWith("http")) { + protocol = SoaConstants.HTTP; + connectionUrl = aConnectionUrl; + } else if (aConnectionUrl.startsWith("tccs")) { + protocol = SoaConstants.TCCS; + connectionUrl = aConnectionUrl.trim(); + int envNameStart = connectionUrl.indexOf('/') + 2; + envNameTccs = connectionUrl.substring(envNameStart, connectionUrl.length()); + connectionUrl = ""; + } else { + protocol = SoaConstants.IIOP; + connectionUrl = aConnectionUrl; + } + + // Create the Connection object, no contact is made with the server until a service request is made + connection = new Connection(connectionUrl, credentialManager, SoaConstants.REST, protocol); + + if (protocol.equals(SoaConstants.TCCS)) { + connection.setOption(Connection.TCCS_ENV_NAME, envNameTccs); + } + + connection.getModelManager().addModelEventListener(new KurtModelEventListener()); + + // Add an ExceptionHandler to the Connection, this will handle any InternalServerException, communication errors, XML marshaling errors + connection.setExceptionHandler(new TcExceptionHandler()); + } + + /** + * Login to the Teamcenter Server. This method is guaranteed to terminate. + * + * @return a {@link LoginResponse} object + * @throws NoTeamcenterConnectionException if unable to setup the connection (Tc might not be responding) + */ + public LoginResponse login() throws NoTeamcenterConnectionException { + if (loggedIn != null) { + return loggedIn; + } + // Timeout the logout in async thread + ExecutorService executor = Executors.newSingleThreadExecutor(); + Future future = executor.submit(new LoginTask()); // Start performing the logout... + try { + loggedIn = future.get(TIMEOUT_SEC, TimeUnit.SECONDS); // Check if successful, do not wait more than this + emptyPolicy(); + enableBypass(); + LOGGER.info("TcSession logged in {}/{}", USERNAME, discriminator); + } catch (TimeoutException e) { + // More than xxx seconds for a login? the Tc servers must be hanging, findAll out + future.cancel(true); + throw new NoTeamcenterConnectionException(ERROR_MSG_LOGIN_TIMEOUT, e); + } catch (InterruptedException e) { + throw new NoTeamcenterConnectionException("Login interrupted", e); + } catch (Exception e) { + Throwable rootCause = e.getCause(); + if (rootCause instanceof InvalidCredentialsException) { + NoTeamcenterConnectionException noTeamcenterConnectionException = + new NoTeamcenterConnectionException("Failed connection to Tc services", rootCause); + noTeamcenterConnectionException.addSuppressed(e); + throw noTeamcenterConnectionException; + } else if (rootCause instanceof ConnectionLostException) { // Connections as made, but no session were available + throw (ConnectionLostException) rootCause; + } else if (rootCause instanceof ServiceException) { + throw new NoTeamcenterConnectionException("Service Exception encountered during login", rootCause); + } else { + throw new NoTeamcenterConnectionException("Connection to Teamcenter failed", e); + } + } + executor.shutdown(); + return loggedIn; + } + + /** + * Terminate the session with the Teamcenter Server gracefully. + */ + @Override + public void close() { + if (isLoggedIn()) { + // Terminate an optional FileManagementUtility separately + if (fileManagementUtility != null) { + fileManagementUtility.term(); + } + + // Timeout the logout in async thread + ExecutorService executor = Executors.newSingleThreadExecutor(); + Future future = executor.submit(new LogoutTask()); // Start performing the logout... + try { + LOGGER.debug(future.get(TIMEOUT_SEC, TimeUnit.SECONDS)); // Check if successful, do not wait more than that + LOGGER.info("TcSession logged out {}/{}", USERNAME, discriminator); + } catch (TimeoutException e) { + // More than xxx seconds for a logout? the Tc servers must be hanging, findAll out + future.cancel(true); + LOGGER.info("Timed out during logout of Tc Servers", e); + } catch (InterruptedException e) { + LOGGER.info("Logout interrupted", e); + } catch (ExecutionException e) { + Throwable rootCause = e.getCause(); + if (rootCause instanceof ConnectionLostException) { + // This is ok, we can't LOGGER out because lost connection in the first place + LOGGER.trace("Unable to logout of Tc session", e); + } else { + LOGGER.info("Unable to logout of Tc session", e); + } + } + executor.shutdown(); + loggedIn = null; + } else { + LOGGER.warn("Trying to logout of the session, but the session is not logged in"); + } + } + + public void setObjectPropPolicy(final PolicyLocation policy) throws InvalidConfigurationException { + boolean success = setPolicy(policy.getIdentifier()); + LOGGER.info(success ? "Policy \"{}\" file is now the active policy" : "Policy \"{}\" file could not be loaded ({})", policy.getIdentifier()); + } + + public void emptyPolicy() throws InvalidConfigurationException { + setPolicy("Empty"); + } + + /** + * Changes the policy on the server, for this session. + */ + private boolean setPolicy(String identifier) throws InvalidConfigurationException { + try { + return SessionService.getService(connection).setObjectPropertyPolicy(identifier); + } catch (ServiceException e) { + throw new InvalidConfigurationException("Teamcenter could not load Object Property Policy file \"" + identifier + "\"", e); + } + } + + /** + * Enable bypass for dba user. + */ + private void enableBypass() { + StateNameValue property = new StateNameValue(); + property.name = "bypassFlag"; + property.value = Boolean.TRUE.toString(); + SessionService sessionService = SessionService.getService(connection); + ServiceData response = sessionService.setUserSessionState(new StateNameValue[]{property}); + if (ServiceDataHelper.hasErrors(response)) { + ServiceDataHelper.displayErrors(response); + } + } + + /** + * Getter for structureManagementService. + * + * @return Service instance for structure management + **/ + public StructureManagementService getStructureManagementService() { + if (structureManagementService == null) { + structureManagementService = StructureManagementService.getService(connection); + } + return structureManagementService; + } + + /** + * Getter for finderService. + * + * @return Service instance for finder + **/ + public FinderService getFinderService() { + if (finderService == null) { + finderService = FinderService.getService(connection); + } + return finderService; + } + + /** + * Returns a {@link SavedQueryService} to perform searches using Saved Queries. + * + * @return a SavedQueryService + */ + public SavedQueryService getSavedQueryService() { + if (savedQueryService == null) { + savedQueryService = SavedQueryService.getService(connection); + } + return savedQueryService; + } + + /** + * Returns a new instance of {@link WorkflowService}. + * + * @return a new instance of the service + */ + public WorkflowService getWorkflowService() { + if (workflowService == null) { + workflowService = WorkflowService.getService(connection); + } + return workflowService; + } + + /** + * Returns a {@link FileManagementUtility} instance. + *

    + * There is no need to {@link FileManagementUtility#term() term()} this instance after usage.
    + * Cleanup will be performed by this {@link TcSession} upon being {@link TcSession#close() closed}.
    + * This instance is created on-demand, and cached for later use, as the object is rather heavy (server-side). + * + * @return a {@link FileManagementUtility} instance + * @throws ConnectionMisconguredException if FSC parameters are incorrect + */ + public FileManagementUtility getFileManagementUtility() throws ConnectionMisconguredException { + if (fileManagementUtility == null) { + String clientIPAddress = fscParams.getClientIPAddress(); + String[] assignedFscURIs = fscParams.getAssignedFscURIs(); + String[] bootstrapFscURIs = fscParams.getBootstrapFscURIs(); + String cacheDir = fscParams.getCacheDir(); + try { + fileManagementUtility = new FileManagementUtility(connection, clientIPAddress, assignedFscURIs, bootstrapFscURIs, cacheDir); + } catch (FileNotFoundException e) { + throw new ConnectionMisconguredException("Failed to start FileManagementUtility, FSC parameters might not be set properly", e); + } + } + return fileManagementUtility; + } + + public TcBomWindow createBomWindow(final TcBomWindowConfiguration bomWindowConfiguration) throws KurtException { + return new TcBomWindowFactory(this, bomWindowConfiguration).create(); + } + + public TcRevisionRule findRevRule(final String revRuleNameToFind) throws KurtException { + try { + GetRevisionRulesResponse revisionRulesResponse = getStructureManagementService().getRevisionRules(); + if (ServiceDataHelper.hasErrors(revisionRulesResponse.serviceData)) { + ServiceDataHelper.displayErrors(revisionRulesResponse.serviceData); + throw new NoSuchRevisionRuleException("Error while loading revision rules."); + } + for (RevisionRuleInfo revisionRuleInfo: revisionRulesResponse.output) { + RevisionRule revRule = revisionRuleInfo.revRule; + loadProperties(revRule, "object_name"); + String revRuleName = revRule.get_object_name(); + if (revRuleNameToFind.equals(revRuleName)) { + LOGGER.debug("Revision rule {} found.", revRuleName); + return new TcRevisionRule(this, revRule); + } + } + } catch (ServiceException e) { + throw new NoSuchRevisionRuleException("Teamcenter could not load the revision rules.", e); + } + throw new NoSuchRevisionRuleException("Unable to find the Revision Rule: " + revRuleNameToFind); + } + + public List findR26RevRule(String reportRevRule) throws NoSuchRevisionRuleException { + List revisionRules = new ArrayList<>(); + try { + GetRevisionRulesResponse revisionRulesResponse = getStructureManagementService().getRevisionRules(); + if (ServiceDataHelper.hasErrors(revisionRulesResponse.serviceData)) { + ServiceDataHelper.displayErrors(revisionRulesResponse.serviceData); + throw new NoSuchRevisionRuleException("Error while loading revision rules."); + } + for (RevisionRuleInfo revisionRuleInfo: revisionRulesResponse.output) { + RevisionRule revRule = revisionRuleInfo.revRule; + loadProperties(revRule, "object_name"); + String revRuleName = revRule.get_object_name(); + if (revRuleName.startsWith(reportRevRule + "-")) { + LOGGER.debug("Revision rule {} found.", revRuleName); + revisionRules.add(revRule); + } + } + } catch (ServiceException e) { + throw new NoSuchRevisionRuleException("Teamcenter could not load the revision rules.", e); + } + return revisionRules; + } + + public void loadProperties(ModelObject modelObjects, String... properties) { + loadProperties(new ModelObject[]{modelObjects}, properties); + } + + public void loadProperties(ModelObject[] modelObjects, String... properties) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Loading {} properties on objects {}", properties.length == 0 ? "all" : Arrays.toString(properties), Arrays.toString(modelObjects)); + } + ServiceData serviceData = DataManagementService.getService(connection).getProperties(modelObjects, properties); + if (ServiceDataHelper.hasErrors(serviceData)) { + ServiceDataHelper.displayErrors(serviceData); + } + } + + public void setProperties(ModelObject modelObject, Map map) { + PropInfo propInfo = new PropInfo(); + propInfo.object = modelObject; + propInfo.vecNameVal = new NameValueStruct1[map.size()]; + + int i = 0; + for (Map.Entry entry : map.entrySet()) { + NameValueStruct1 nameValueStruct1 = new NameValueStruct1(); + nameValueStruct1.name = entry.getKey(); + + Object propertyValue = entry.getValue(); + if (propertyValue != null) { + if (propertyValue.getClass().equals(String.class)) { + nameValueStruct1.values = new String[1]; + nameValueStruct1.values[0] = (String) propertyValue; + + propInfo.vecNameVal[i] = nameValueStruct1; + i++; + } else if (propertyValue.getClass().equals(String[].class)) { + nameValueStruct1.values = (String[]) propertyValue; + + propInfo.vecNameVal[i] = nameValueStruct1; + i++; + } + } + } + + SetPropertyResponse setPropertyResponse = DataManagementService.getService(connection).setProperties(new PropInfo[]{propInfo}, new String[]{}); + if (ServiceDataHelper.hasErrors(setPropertyResponse.data)) { + ServiceDataHelper.displayErrors(setPropertyResponse.data); + } + } + + public List loadObjects(String... uids) { + List objectLoaded = new ArrayList<>(); + ServiceData serviceData = DataManagementService.getService(connection).loadObjects(uids); + if (ServiceDataHelper.hasErrors(serviceData)) { + ServiceDataHelper.displayErrors(serviceData); + } + for (int objectIndex = 0; objectIndex < serviceData.sizeOfPlainObjects(); objectIndex++) { + T object = (T) serviceData.getPlainObject(objectIndex); + objectLoaded.add(object); + } + return objectLoaded; + } + + public List whereReferenced(final WorkspaceObject workspaceObject, final int level, final Map> relationAndTypesFilter) throws KurtException { + WhereReferencedResponse whereReferencedResponse = DataManagementService.getService(connection).whereReferenced(new WorkspaceObject[]{workspaceObject}, level); + if (ServiceDataHelper.hasErrors(whereReferencedResponse.serviceData)) { + ServiceDataHelper.displayErrors(whereReferencedResponse.serviceData); + throw new KurtException("Some errors were encountered while performing 'referencedBy' request"); + } + List referencedObjects = new ArrayList<>(); + WhereReferencedOutput[] response = whereReferencedResponse.output; + for (WhereReferencedOutput whereReferencedOutput: response) { + LOGGER.debug("InputObject client : {}", whereReferencedOutput.inputObject); + for (WhereReferencedInfo outputInfo: whereReferencedOutput.info) { + String objectType = workspaceObject.getTypeObject().getName(); + LOGGER.debug("object candidate {} relation {}", objectType, outputInfo.relation); + List listRelationTypes = relationAndTypesFilter.get(objectType); + if (listRelationTypes != null && listRelationTypes.contains(outputInfo.relation)) { + referencedObjects.add((ItemRevision) outputInfo.referencer); + } + } + } + return referencedObjects; + } + + public GetDatasetWriteTicketsInputData createDatasets(final DatasetInfo[] datasetProperties, final DatasetFileInfo[] currFiles) throws MalformedDataSetException { + // Perform dataset request using properties + CreateDatasetsResponse resp = DataManagementService.getService(connection).createDatasets(datasetProperties); + if (ServiceDataHelper.hasErrors(resp.servData)) { + ServiceDataHelper.displayErrors(resp.servData); + throw new MalformedDataSetException("Unable to perform the request, dataset creation failed"); + } + + // dataset accepted, now fill the response with dataset data + GetDatasetWriteTicketsInputData dataSetInfoAndData = new GetDatasetWriteTicketsInputData(); + dataSetInfoAndData.dataset = resp.datasetOutput[0].dataset; + dataSetInfoAndData.createNewVersion = false; + dataSetInfoAndData.datasetFileInfos = currFiles; + return dataSetInfoAndData; + } + + public ImanRelation createRelation(final ModelObject primary, final ModelObject secondary, final String relationType) throws FailedRelationshipActionException { + Relationship relation = new Relationship(); + relation.clientId = "KURT-reports"; + relation.primaryObject = primary; + relation.secondaryObject = secondary; + relation.relationType = relationType; + CreateRelationsResponse relationCreationResult = DataManagementService.getService(connection).createRelations(new Relationship[]{relation}); + if (ServiceDataHelper.hasErrors(relationCreationResult.serviceData)) { + ServiceDataHelper.displayErrors(relationCreationResult.serviceData); + } + if (relationCreationResult.output.length == 0) { + throw new FailedRelationshipActionException("The requested relationship could not be created."); + } + return relationCreationResult.output[0].relation; + } + + public void deleteRelations(final ModelObject primary, final ModelObject secondary, final String relationType) throws FailedRelationshipActionException { + Relationship relation = new Relationship(); + relation.clientId = "KURT-reports"; + relation.primaryObject = primary; + relation.secondaryObject = secondary; + relation.relationType = relationType; + ServiceData relationDeletionResult = DataManagementService.getService(connection).deleteRelations(new Relationship[]{relation}); + if (ServiceDataHelper.hasErrors(relationDeletionResult)) { + ServiceDataHelper.displayErrors(relationDeletionResult); + } + if (relationDeletionResult.sizeOfDeletedObjects() == 0) { + throw new FailedRelationshipActionException("The requested relationship could not be destroyed."); + } + } + + public void deleteObjects(final ModelObject... modelObjects) { + ServiceData serviceData = DataManagementService.getService(connection).deleteObjects(modelObjects); + if (ServiceDataHelper.hasErrors(serviceData)) { + ServiceDataHelper.displayErrors(serviceData); + } + } + + + public List whereUsed(final ItemRevision inputObject, final String typeWanted) throws KurtException { + + WhereUsedConfigParameters configParameters = new WhereUsedConfigParameters(); + configParameters.stringMap.put("Type", typeWanted); + configParameters.intMap.put("numLevels", BigInteger.valueOf(1)); + + WhereUsedInputData inputData = new WhereUsedInputData(); + inputData.inputObject = inputObject; + inputData.inputParams = configParameters; + + WhereUsedResponse allResponses = DataManagementService.getService(connection).whereUsed(new WhereUsedInputData[]{inputData}, configParameters); + + List results = new ArrayList<>(); + + if (ServiceDataHelper.hasErrors(allResponses.serviceData)) { + ServiceDataHelper.displayErrors(allResponses.serviceData); + throw new KurtException("Error while retrieving whereUsed on " + inputObject.get_item_id() ); + } + + + + for (WhereUsedParentInfo info: allResponses.output[0].info) { + + if (info.level == 1) { + ItemRevision result = (ItemRevision) info.parentObject; + if (typeWanted.equals(result.getTypeObject().getName())) { + + results.add(result); + } + } + } + + return results; + } + + + + public List whereUsed(final WorkspaceObject inputObject, final int level, final RevisionRule revisionRule) { + WhereUsedConfigParameters configParameters = new WhereUsedConfigParameters(); + configParameters.intMap.put("numLevels", BigInteger.valueOf(level)); + if (revisionRule != null) { + configParameters.tagMap.put("revision_rule", revisionRule); + } + + WhereUsedInputData inputData = new WhereUsedInputData(); + inputData.inputObject = inputObject; + inputData.inputParams = configParameters; + + WhereUsedResponse allResponses = DataManagementService.getService(connection).whereUsed(new WhereUsedInputData[]{inputData}, configParameters); + List results = new ArrayList<>(); + for (WhereUsedParentInfo info: allResponses.output[0].info) { + ItemRevision itemRevision = (ItemRevision) info.parentObject; + + loadProperties(itemRevision, "active_seq"); + int activeSeq = itemRevision.get_active_seq(); + + // only add item last sequence (means the active sequence) + if (activeSeq != 0) { + results.add((ItemRevision) info.parentObject); + } + } + return results; + } + + /** + * Login task. This {@link Callable} can be executed concurrently to perform login. Outcome is the {@link User} logged in. + */ + private final class LoginTask implements Callable { + @Override + public LoginResponse call() throws IOException, KurtException { + try { + SessionService sessionService = SessionService.getService(connection); + Credentials crd = new Credentials(); + crd.user = USERNAME; + crd.password = new AesEncoded(PASSWORD).decode(); + discriminator = UUID.randomUUID().toString(); + crd.descrimator = discriminator; + crd.locale = "FR"; + LoginResponse loginResponse = sessionService.login(crd); + for (Object obj: loginResponse.serverInfo.entrySet()) { + @SuppressWarnings("unchecked") + Map.Entry entry = (Map.Entry) obj; + LOGGER.info(entry.getKey() + " : " + entry.getValue()); + } + return loginResponse; + } finally { + if (Thread.interrupted()) { // The Future got cancelled (probably because of Timeout)... + close(); // ...so we make sure to close() the session (the caller has given up and won't do it) + } + } + } + } + + /** + * Logout task. This {@link Callable} can be executed concurrently to perform logout. Outcome is the {@link User} logged out. + */ + private final class LogoutTask implements Callable { + @Override + public String call() throws ServiceException { + SessionService sessionService = SessionService.getService(connection); + if (LOGGER.isDebugEnabled()) { + try { + LOGGER.debug("[LOGOUT] Showing TCInfo content for session {} : {}", discriminator, sessionService.getTCSessionInfo().extraInfo.get(TC_SERVER_ID).toString()); + } catch (ServiceException e) { + LOGGER.warn(ERROR_MSG_UNABLE_TO_OBTAIN_SESSION_INFO_TC_SERVER_ID, e); + } + } + sessionService.logout(); + return "Logout successful"; + } + } + + + /** + * Clone revision rule: a new Revision Rule is created with the name defined in parameter. + */ + public void cloneRevisionRule(RevisionRule revRuleToCopy, String name) throws Exception { + ICCTSession icctSession = new ICCTSession(connection); + int markpoint = icctSession.placeMarkpoint(new String[0]); + try { + ICCTRevisionRule icctRevisionRule = new ICCTRevisionRule(connection, revRuleToCopy.getTypeObject().getName(), revRuleToCopy.getTypeObject().getUid()); + StringHolder newRevRule = new StringHolder(); + StringHolder revisionRuleType = new StringHolder(); + icctRevisionRule.create(name, name, newRevRule, revisionRuleType); + icctRevisionRule.cloneInstance(revRuleToCopy.getUid(), newRevRule.value); + icctRevisionRule.save(newRevRule.value); + icctSession.forgetMarkpoint(markpoint); + } + catch (Exception e) { + icctSession.rollToMarkpoint(markpoint); + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/ConnectionMisconguredException.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/ConnectionMisconguredException.java new file mode 100644 index 0000000..957030a --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/ConnectionMisconguredException.java @@ -0,0 +1,24 @@ +package com.capgemini.framework.teamcenter.exceptions; + +/** Exception thrown if the Connection to Teamcenter or to the FSC is not configured properly. */ +public class ConnectionMisconguredException extends KurtException { + private static final long serialVersionUID = -8984259943413332487L; + + /** + * Usual constructor. + * @param aMessage a message + */ + public ConnectionMisconguredException(String aMessage) { + super(aMessage); + } + + /** + * Usual constructor with root cause. + * @param aMessage a message + * @param rootCause the root exception + */ + public ConnectionMisconguredException(String aMessage, Throwable rootCause) { + super(aMessage, rootCause); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/EmptyNomenclatureException.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/EmptyNomenclatureException.java new file mode 100644 index 0000000..70d9d59 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/EmptyNomenclatureException.java @@ -0,0 +1,35 @@ +package com.capgemini.framework.teamcenter.exceptions; + +/** Error occurring if the resolution structure doesn't work. */ +public class EmptyNomenclatureException extends KurtException { + + private static final long serialVersionUID = -3412885624655787481L; + + /** + * Constructor. + * + * @param aMessage String - the message + */ + public EmptyNomenclatureException(final String aMessage) { + super(aMessage); + } + + /** + * Constructor. + * + * @param aMessage String - the message + * @param anException {@link Throwable} - the exception + */ + public EmptyNomenclatureException(final String aMessage, final Throwable anException) { + super(aMessage, anException); + } + + /** + * Constructor. + * + * @param anException {@link Throwable} - the exception + */ + public EmptyNomenclatureException(final Throwable anException) { + super(anException.getMessage(), anException); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/FailedRelationshipActionException.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/FailedRelationshipActionException.java new file mode 100644 index 0000000..b48b5d5 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/FailedRelationshipActionException.java @@ -0,0 +1,29 @@ +package com.capgemini.framework.teamcenter.exceptions; + +import com.teamcenter.services.strong.core._2006_03.DataManagement.Relationship; + +/** This exception is thrown when unable to perform an operation on {@link Relationship} between objects. */ +public class FailedRelationshipActionException extends KurtException { + + private static final long serialVersionUID = 4835457230745841725L; + + /** + * Simple constructor. For an original exception. + * + * @param msg the tech error message + */ + public FailedRelationshipActionException(final String msg) { + super(msg); + } + + /** + * Simple constructor. For an derived exception. + * + * @param msg the tech error message + * @param exc original exception + */ + public FailedRelationshipActionException(final String msg, final Throwable exc) { + super(msg, exc); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/InvalidConfigurationException.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/InvalidConfigurationException.java new file mode 100644 index 0000000..a8f82cd --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/InvalidConfigurationException.java @@ -0,0 +1,29 @@ +package com.capgemini.framework.teamcenter.exceptions; + +/** + * {@link Exception} thrown when the configuration is invalid.
    + * It may be missing data or, or maybe the Generic does not exist under the specified Product etc. + */ +public class InvalidConfigurationException extends KurtException { + + private static final long serialVersionUID = 1271823633534992733L; + + /** + * Simple constructor. For an original exception. + * + * @param msg the tech error message + */ + public InvalidConfigurationException(final String msg) { + super(msg); + } + + /** + * Simple constructor. For an derived exception. + * + * @param msg the tech error message + * @param exc original exception + */ + public InvalidConfigurationException(final String msg, final Throwable exc) { + super(msg, exc); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/KurtException.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/KurtException.java new file mode 100644 index 0000000..a3f26d1 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/KurtException.java @@ -0,0 +1,40 @@ +package com.capgemini.framework.teamcenter.exceptions; + +/** + * Generic Exception to be able to catch all the KURT-Generated exceptions in a single catch. + * + */ +public class KurtException extends Exception { + + /** Serialization UID. **/ + private static final long serialVersionUID = -7235562571986874642L; + + /** + * Simple Constructor. Takes an input error message as parameter. + * + * @param aMessage Error message + */ + public KurtException(final String aMessage) { + super(aMessage); + } + + /** + * Constructor. + * + * @param aMessage Error message + * @param anException Original exception + */ + public KurtException(final String aMessage, final Throwable anException) { + super(aMessage, anException); + } + + /** + * Returns the message to be sent to the user. + * + * @return the message + */ + public String getErrorMessageForUser() { + return "Une erreur interne s’est produite."; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/MalformedDataSetException.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/MalformedDataSetException.java new file mode 100644 index 0000000..9ee2036 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/MalformedDataSetException.java @@ -0,0 +1,27 @@ +package com.capgemini.framework.teamcenter.exceptions; + +/** Exception encountered when a DataSet could not be created because of incoorect inputs. */ +public class MalformedDataSetException extends KurtException { + + private static final long serialVersionUID = 1852176831050983022L; + + /** + * Simple constructor. For an original exception. + * + * @param msg the tech error message + */ + public MalformedDataSetException(final String msg) { + super(msg); + } + + /** + * Simple constructor. For an derived exception. + * + * @param msg the tech error message + * @param exc original exception + */ + public MalformedDataSetException(final String msg, final Throwable exc) { + super(msg, exc); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/NoSuchBomViewException.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/NoSuchBomViewException.java new file mode 100644 index 0000000..d58f9d8 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/NoSuchBomViewException.java @@ -0,0 +1,28 @@ +package com.capgemini.framework.teamcenter.exceptions; + +import com.teamcenter.soa.client.model.strong.BOMView; + +/** Exception thrown whan the Request {@link BOMView} does not exist on an object. */ +public class NoSuchBomViewException extends KurtException { + + private static final long serialVersionUID = -7773553173685231832L; + + /** + * Exception thrown when the Request {@link BOMView} does not exist on an object. + * + * @param msg the reason + */ + public NoSuchBomViewException(final String msg) { + super(msg); + } + + /** + * Simple constructor. For an derived exception. + * + * @param msg the reason + * @param exc original exception + */ + public NoSuchBomViewException(final String msg, final Throwable exc) { + super(msg, exc); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/NoSuchRevisionRuleException.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/NoSuchRevisionRuleException.java new file mode 100644 index 0000000..bdd2702 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/NoSuchRevisionRuleException.java @@ -0,0 +1,29 @@ +package com.capgemini.framework.teamcenter.exceptions; + +import com.teamcenter.soa.client.model.strong.RevisionRule; + +/** {@link Exception} thrown when the requested {@link RevisionRule} does not seem to exist on the TC servers. */ +public class NoSuchRevisionRuleException extends KurtException { + + private static final long serialVersionUID = -1497854843179454406L; + + /** + * Simple constructor. For an Original exception. + * + * @param msg the tech error message + */ + public NoSuchRevisionRuleException(final String msg) { + super(msg); + } + + /** + * Simple constructor. For a derived exception. + * + * @param msg the tech error message + * @param exc original exception + */ + public NoSuchRevisionRuleException(final String msg, final Throwable exc) { + super(msg, exc); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/NoTeamcenterConnectionException.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/NoTeamcenterConnectionException.java new file mode 100644 index 0000000..ea305f7 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/NoTeamcenterConnectionException.java @@ -0,0 +1,27 @@ +package com.capgemini.framework.teamcenter.exceptions; + +/** Thrown when no connection could be obtained to a Tc server. */ +public class NoTeamcenterConnectionException extends KurtException { + + private static final long serialVersionUID = 7317052053857458609L; + + /** + * Simple constructor. For an Original exception. + * + * @param aMessage the tech error message + */ + public NoTeamcenterConnectionException(String aMessage) { + super(aMessage); + } + + /** + * Simple constructor. For a derived exception. + * + * @param aMessage the tech error message + * @param anException original exception + */ + public NoTeamcenterConnectionException(String aMessage, Throwable anException) { + super(aMessage, anException); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/QueryDoesNotExist.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/QueryDoesNotExist.java new file mode 100644 index 0000000..02f9d9a --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/QueryDoesNotExist.java @@ -0,0 +1,27 @@ +package com.capgemini.framework.teamcenter.exceptions; + +/** Exception to be used when the requested SavedQuery does not exist. */ +public class QueryDoesNotExist extends KurtException { + + private static final long serialVersionUID = 5026463541399654426L; + + /** + * Usual constructor for a newly found exception. + * + * @param msg error message + */ + public QueryDoesNotExist(final String msg) { + super(msg); + } + + /** + * Usual constructor to explain an incoming exception. + * + * @param msg error message + * @param exc original exception + */ + public QueryDoesNotExist(final String msg, final Throwable exc) { + super(msg, exc); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/UnableToCreateStatusException.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/UnableToCreateStatusException.java new file mode 100644 index 0000000..771525c --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/UnableToCreateStatusException.java @@ -0,0 +1,28 @@ +package com.capgemini.framework.teamcenter.exceptions; + +/** Exception encountered when unable to create a Status on an Object. */ +public class UnableToCreateStatusException extends KurtException { + + private static final long serialVersionUID = 5026463541399654426L; + + /** + * Usual constructor for a newly found exception. + * + * @param msg error message + */ + public UnableToCreateStatusException(final String msg) { + super(msg); + } + + /** + * Usual constructor to explain an incoming exception. + * + * @param msg error message + * @param exc original exception + */ + public UnableToCreateStatusException(final String msg, final Throwable exc) { + super(msg, exc); + } + + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/runtime/ConnectionLostException.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/runtime/ConnectionLostException.java new file mode 100644 index 0000000..fa2e125 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/runtime/ConnectionLostException.java @@ -0,0 +1,19 @@ +package com.capgemini.framework.teamcenter.exceptions.runtime; + +import com.teamcenter.schemas.soa._2006_03.exceptions.InternalServerException; + +/** {@link RuntimeException} thrown when connection is suddenly lost. */ +public class ConnectionLostException extends KurtRuntimeException { + + private static final long serialVersionUID = -7645238831152306945L; + + /** + * Builds an {@link ConnectionLostException} that has a custom error message, and originates from a Tc {@link InternalServerException}. + * @param message custom error message + * @param anException original Tc exception + */ + public ConnectionLostException(final String message, final InternalServerException anException) { + super(message, anException); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/runtime/KurtRuntimeException.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/runtime/KurtRuntimeException.java new file mode 100644 index 0000000..7988f8d --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/exceptions/runtime/KurtRuntimeException.java @@ -0,0 +1,26 @@ +package com.capgemini.framework.teamcenter.exceptions.runtime; + +/** + * Super type of any {@link RuntimeException} thrown by the KURT application. + */ +public class KurtRuntimeException extends RuntimeException { + private static final long serialVersionUID = 6157368198636151053L; + + public KurtRuntimeException() { + } + + public KurtRuntimeException(String message) { + super(message); + } + + /** + * Builds an {@link KurtRuntimeException} that has a custom error message, and originates from an original exception. + * + * @param message custom error message + * @param anException original exception + */ + public KurtRuntimeException(final String message, final Throwable anException) { + super(message, anException); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/files/DatasetPreparator.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/files/DatasetPreparator.java new file mode 100644 index 0000000..047c590 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/files/DatasetPreparator.java @@ -0,0 +1,154 @@ +package com.capgemini.framework.teamcenter.files; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.MalformedDataSetException; +import com.capgemini.framework.teamcenter.files.FileManagement.FileType; +import com.google.common.base.Optional; +import com.teamcenter.services.loose.core._2006_03.FileManagement.DatasetFileInfo; +import com.teamcenter.services.loose.core._2006_03.FileManagement.GetDatasetWriteTicketsInputData; +import com.teamcenter.services.strong.core._2010_04.DataManagement.DatasetInfo; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.io.File; +import java.util.Comparator; +import java.util.Set; +import java.util.TreeSet; + +/** + * This class compiles and prepare the necessary data for creating a dataset, then is able to create it on the TC servers.
    + * The dataset may contain several files. + */ +@Getter(value = AccessLevel.PROTECTED) +public class DatasetPreparator { + + /** + * constant for debugging and retrieving the origin of a dataset. + */ + private static final String CLIENT_ID = "KurtReport_FromWorkflow"; + + /** + * We apparently cannot upload two files with the same name to the same Dataset because this creates a relation name conflict.
    + * So this comparator ensures there are no two files with the same filenames. + */ + private static final Comparator fileNameComparator = new Comparator() { + @Override + public int compare(final DataBundle obj1, final DataBundle obj2) { + return obj1.getDatasetInfo().fileName.compareTo(obj2.getDatasetInfo().fileName); + } + }; + + private final String datasetName; + private final String datasetDescription; + private final Set filesInDataSet = new TreeSet<>(fileNameComparator); + private final TcSession session; + private Optional datasetTicket = Optional.absent(); + + /** + * Constructs a {@link DatasetPreparator}, defines its name and description. + */ + public DatasetPreparator(final TcSession session, final String datasetName, final String datasetDescription) throws MalformedDataSetException { + this.session = session; + if (datasetName == null || datasetName.isEmpty()) { + throw new MalformedDataSetException("Insufficient parameters for dataset creation"); + } + this.datasetName = datasetName; + this.datasetDescription = datasetDescription == null ? "" : datasetDescription; + } + + /** + * Returns true if a dataset ticket has been created. + * + * @return true if a dataset ticket has been created. + */ + public boolean isCreated() { + return datasetTicket.isPresent(); + } + + /** + * Obtain the Dataset ticket (a {@link GetDatasetWriteTicketsInputData} object).
    + * This method only works if {@link DatasetPreparator#isCreated()} is true. + */ + public GetDatasetWriteTicketsInputData getCreatedDataset() { + return datasetTicket.get(); + } + + /** + * Add a file to the dataset. + *

    + * Be careful, no two files may have the same name:
    + * If a file already exists with the same name, the new file will NOT be added, and the method will return false (just like in {@link Set} definition). + * + * @param file the File to be added (please ensure the file does exist) + * @param type the {@link FileType} of the file + * @return true if the operation is successful, false if not (maybe a file with same name already exists?) + * @throws MalformedDataSetException when the provided File is null, does not exist, or name is null, empty, or no type is specified + */ + public boolean addFile(final File file, final FileType type) throws MalformedDataSetException { + // Pre conditions + if (file == null || !file.exists()) { + throw new MalformedDataSetException("File for dataset does not exist"); + } + + // Prepare file info + DatasetFileInfo fileInfo = new DatasetFileInfo(); + fileInfo.clientId = CLIENT_ID; + fileInfo.fileName = file.getAbsolutePath(); + fileInfo.namedReferencedName = type.getNamedReferenceName(); + fileInfo.isText = type.isText(); + fileInfo.allowReplace = false; + + + // Prepare dataset request properties + DatasetInfo properties = new DatasetInfo(); + properties.clientId = CLIENT_ID; + properties.type = type.getType(); + properties.name = datasetName; + properties.description = datasetDescription; + + // Store this demand + return filesInDataSet.add(new DataBundle(fileInfo, properties)); + } + + /** + * Creates the dataset on the TC servers. + */ + public GetDatasetWriteTicketsInputData prepare() throws MalformedDataSetException { + if (filesInDataSet.isEmpty()) { + throw new MalformedDataSetException("Insufficient parameters for dataset creation"); + } + if (isCreated()) { + throw new MalformedDataSetException("This Dataset has already been created, cannot ask to create it twice"); + } + + DatasetInfo[] currProps = new DatasetInfo[filesInDataSet.size()]; + DatasetFileInfo[] currFiles = new DatasetFileInfo[filesInDataSet.size()]; + int num = 0; + for (DataBundle bundle : filesInDataSet) { + currProps[num] = bundle.getDatasetProperties(); + currFiles[num] = bundle.getDatasetInfo(); + num++; + } + + GetDatasetWriteTicketsInputData dataSetInfoAndData = session.createDatasets(currProps, currFiles); + datasetTicket = Optional.of(dataSetInfoAndData); + return dataSetInfoAndData; + } + + /** + * Tells if this dataset does not have any files into it. + * + * @return true if no files are specified + */ + public boolean isEmpty() { + return filesInDataSet.isEmpty(); + } + + @AllArgsConstructor + @Getter + private static class DataBundle { + private final DatasetFileInfo datasetInfo; + private final DatasetInfo datasetProperties; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/files/FileManagement.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/files/FileManagement.java new file mode 100644 index 0000000..7307423 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/files/FileManagement.java @@ -0,0 +1,117 @@ +package com.capgemini.framework.teamcenter.files; + +import com.capgemini.framework.teamcenter.ServiceDataHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.ConnectionMisconguredException; +import com.capgemini.framework.teamcenter.exceptions.MalformedDataSetException; +import com.teamcenter.services.loose.core._2006_03.FileManagement.GetDatasetWriteTicketsInputData; +import com.teamcenter.soa.client.model.ServiceData; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * Use this class to transfer files into datasets. + */ +@Getter(value = AccessLevel.PROTECTED) +public class FileManagement { + + private final TcSession session; + private final List dataSets = new ArrayList<>(); + + public FileManagement(final TcSession session) { + this.session = session; + } + + /** + * Creates a Dataset with a single file in it. + * + * @param session a logged-in {@link TcSession} + * @param datasetName the name of the dataset + * @param dataSetDescription a description for the dataset (optional: null or empty allowed)) + * @param file a valid {@link File} pointing to the file on local file system to upload on the Tc servers + * @param type the {@link FileType} of file + * @return a {@link GetDatasetWriteTicketsInputData} containing data on the dataset that has been created. + * @throws MalformedDataSetException if anything goes wrong: missing file, conflicting names, wrong types etc. + */ + public static GetDatasetWriteTicketsInputData addSingleDataSet(final TcSession session, final String datasetName, + final String dataSetDescription, final File file, final FileType type) throws MalformedDataSetException, ConnectionMisconguredException { + FileManagement fileManagement; + fileManagement = new FileManagement(session); + fileManagement.addDataSetWithSingleFile(datasetName, dataSetDescription, file, type); + fileManagement.upload(); + return fileManagement.dataSets.get(0); // Only one element + } + + /** + * Adds a dataset definition to the list of datasets to create, with a single file in it. + * + * @param datasetName the name of the dataset + * @param dataSetDescription a description for the dataset (optional: null or empty allowed)) + * @param file a valid {@link File} pointing to the file on local file system to upload on the Tc servers + * @param type the {@link FileType} of file + * @throws MalformedDataSetException if anything goes wrong: missing file, conflicting names, wrong types etc. + */ + public void addDataSetWithSingleFile(final String datasetName, final String dataSetDescription, final File file, final FileType type) + throws MalformedDataSetException { + DatasetPreparator dataset = new DatasetPreparator(session, datasetName, dataSetDescription); + dataset.addFile(file, type); + addDataSet(dataset); + } + + /** + * Adds a custom {@link DatasetPreparator} instance to the batch of datasets to be uploaded.
    + */ + public void addDataSet(final DatasetPreparator dataset) throws MalformedDataSetException { + if (!dataset.isCreated()) { + dataset.prepare(); + } + dataSets.add(dataset.getCreatedDataset()); + } + + /** + * Uploads the files to each registered dataset in Tc. + * + * @throws MalformedDataSetException if anything goes wrong (the files were not uploaded + */ + public void upload() throws MalformedDataSetException, ConnectionMisconguredException { + if (dataSets.isEmpty()) { + throw new MalformedDataSetException("No dataset was provided, unable to create the datasets."); + } + GetDatasetWriteTicketsInputData[] datasetTickets = dataSets.toArray(new GetDatasetWriteTicketsInputData[dataSets.size()]); + ServiceData response = session.getFileManagementUtility().putFiles(datasetTickets); + if (ServiceDataHelper.hasErrors(response)) { + ServiceDataHelper.displayErrors(response); + throw new MalformedDataSetException("Unable to perform fully the request, file upload may have failed"); + } + } + + /** + * Enums of each file type supported as a Teamcenter dataset file. + */ + @Getter + @AllArgsConstructor + public enum FileType { + /** + * Generic Text document. + */ + TEXT_FILE("Text", "Text", true), + /** + * 'Fiche Article' PDF document on Parts. + */ + FICHE_ARTICLE("Fiche Article", "PDF_Reference", false), + /** + * Generic PDF document. + */ + PDF("PDF", "PDF_Reference", false); + + private final String type; + private final String namedReferenceName; + private final boolean text; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/SnecmaObjectProperties.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/SnecmaObjectProperties.java new file mode 100644 index 0000000..269d615 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/SnecmaObjectProperties.java @@ -0,0 +1,221 @@ +package com.capgemini.framework.teamcenter.object; + +import com.capgemini.framework.teamcenter.TeamcenterObjectProperties; +import lombok.EqualsAndHashCode; + +/** Class regrouping all the properties for objects. */ +@EqualsAndHashCode(callSuper = true) +public final class SnecmaObjectProperties extends TeamcenterObjectProperties { + + /** Property for retrieving the Tc type of an object. */ + public static final String OBJECT_TYPE = "object_type"; + /** Property for retrieving the documents in the pseudofolder "Documents de definition". */ + public static final String PV_DEFINITION_DOCS = "_PV_definition_docs"; + /** Property for retrieving the documents in the pseudofolder "Documents de reference". */ + public static final String PV_REFERENCE_DOCS = "_PV_reference_docs"; + /** Property for retrieving the ChangeRequests in the pseudofolder CR. */ + public static final String PV4_RUNTIME_CR_RELATED = "pv4_runtime_cr_related"; + /** Property for retrieving the ChangeRequests in the pseudofolder CN. */ + public static final String PV4_RUNTIME_CN_RELATED = "pv4_runtime_cn_related"; + /** Property for retrieving the list of ReleaseStatus. */ + public static final String RELEASE_STATUS_LIST = "release_status_list"; + /** Property for retrieving the due date on a EPMTask. */ + public static final String DUE_DATE = "due_date"; + /** Property for retrieving the list of changes for a Unit via the pseudofolder "liste des modifications". */ + public static final String PV_CHANGE_LIST = "_PV_change_list"; + /** Property for retrieving the list of Units for a Product via the pseudofolder "Unit". */ + public static final String PV_UNIT = "_PV_unit"; + /** Property for retrieving the domain of a Product Revision. */ + public static final String PV_DOMAINE = "pv_domaine"; + /** Property for retrieving the ligne produit. */ + public static final String PV_LIGNE_PRODUIT = "pv_ligne_produit"; + /** Property for retrieving Oui/Yes if the Unit is exceptionnel. Else Non/No. */ + public static final String PV_UNIT_EXCEPTIONNEL = "pv_unit_exceptionnel"; + /** Property for retrieving the deliverables. */ + public static final String PV_DELIVERABLES = "_PV_deliverables"; + /** Property for retrieving the generic for a Unit via the pseudofolder "generique". */ + public static final String PV_GENERIC = "_PV_generic"; + /** Property for retrieving the ChangeNotice implementing a ChangeRequest, or the ChangeRequest implementing a ProblemReport. */ + public static final String CM_IMPLEMENTED_BY = "CMImplementedBy"; + /** Pseudo-folder where the Change object links to the Parts that are solution of the change. */ + public static final String CM_HAS_SOLUTION_ITEM = "CMHasSolutionItem"; + /** Property for retrieving the ChangeRequest of an Object. */ + public static final String CM_IMPLEMENTS = "CMImplements"; + /** Property for retrieving the 'external approbation'. */ + public static final String PV_EXTERNAL_APPROBATION = "_PV_external_approbation"; + /** Property for retrieving the 'numero d'approbation SO' (services officiels). */ + public static final String PV_NUMERO_APPROBATION = "pv_numero_approbation_so"; + /** Property for retrieving the type of a modification. */ + public static final String PV4_TYPE_MODIFICATION = "pv4_type_modification"; + /** Property for retrieving the list of generic with interruption for a ChangeItem. */ + public static final String PV_IMP_GENERICS_WITH_INTER = "_PV_imp_generics_with_inter"; + /** Property for retrieving the list of generic without interruption for a ChangeItem. */ + public static final String PV_IMP_GENERICS_WITHOUT_INTER = "_PV_imp_generics_without_inter"; + /** Property for retrieving the 'indice plan'. */ + public static final String PV_INDICE_PLAN = "pv_indice_plan"; + /** Property for retrieving the 'indice cartouche'. */ + public static final String PV_INDICE_CARTOUCHE = "pv_indice_cartouche"; + /** Property for retrieving the 'id origine'. */ + public static final String PV_ID_ORIGINE = "pv_id_origine"; + /** Property for retrieving the security message. */ + public static final String PV_SENSIBILITE_SECURITE = "pv_sensibilite_securite"; + /** Property for retrieving the 'niveau de sensibilite'. */ + public static final String NIVEAU_SENSIBILITE = "ip_classification"; + /** Property for retrieving the 'indice' of a document. */ + public static final String PV_INDICE_DOCUMENT = "pv_indice_document"; + /** Property for retrieving the 'type DocTechnic 1'. */ + public static final String PV_TYPE_DOC_TECHNIC_1 = "pv_type_doc_technic_1"; + /** Property for retrieving the 'type DocTechnic 2'. */ + public static final String PV_TYPE_DOC_TECHNIC_2 = "pv_type_doc_technic_2"; + /** Property for retrieving the mass (double). */ + public static final String PV_MASSE_INDICATIVE = "pv_masse_indicative"; + /** Property for retrieving the mass unit. */ + public static final String PV_UNITE_MASSE = "pv_unite_masse"; + /** Property for retrieving the 'Date de péremption'. */ + public static final String PV4_EXPIRATION_DATE = "pv4_Expiration_date"; + /** Property for retrieving the 'suivi duree de vie'. */ + public static final String PV_SUIVI_DUREE_VIE = "pv_suivi_duree_vie"; + /** Property for retrieving the 'duree de vie'. */ + public static final String PV_DUREE_VIE = "pv_duree_vie"; + /** Property for retrieving the 'unite duree de vie'. */ + public static final String PV_UNITE_DUREE_VIE = "pv_unite_duree_vie"; + /** DMD value of type docNorm */ + public static final String DMD_VALUE_OF_TYPE_DOCNORM = "DMD-Document Matériaux Définition"; + /** DMF value of type docNorm */ + public static final String DMF_VALUE_OF_TYPE_DOCNORM = "DMF général-Document Matériaux Fabrication"; + /** Property for retrieving the 'suivi utilisation'. */ + public static final String PV_SUIVI_UTILISATION = "pv_suivi_utilisation"; + /** Property for retrieving the effectivity. */ + public static final String PV4_TYPE_EFFECTIVITY = "pv4_type_effectivite"; + /** + * Property for retrieving the 'suivi utilisation'. + */ + public static final String PV_SUIVI_DEVELOPPEMENT = "pv_suivi_developpement"; + /** Property for retrieving the 'suivi montage'. */ + public static final String PV_SUIVI_MONTAGE = "pv_suivi_montage"; + /** + * Property for retrieving the 'transfert lien logitique'. + */ + public static final String PV_TRANSFERT_LIEN_LOGISTI = "pv_transfert_lien_logisti"; + /** + * Property for retrieving the 'transfert lien montage'. + */ + public static final String PV_TRANSFERT_LIEN_MONTAGE = "pv_transfert_lien_montage"; + /** Property for retrieving the 'classement'. */ + public static final String PV_CLASSEMENT = "pv_classement"; + /** Property for retrieving the 'classement matiere'. */ + public static final String PV_CLASSEMENT_MATIERE = "pv_classement_matiere"; + /** Property for retrieving the 'responsable conception' user id. */ + public static final String PV_RESPONSABLE_CONCEPTION = "pv_responsable_conception"; + /** Property for retrieving the 'fournisseurs' (Array of String). */ + public static final String PV_FOURNISSEURS = "pv4_pv_fournisseurs"; + /** Property for retrieving the responsable repere of a Form. */ + public static final String PV_RESPONSABLE_REPERE = "pv_responsable_repere"; + /** Property for retrieving the reference transposee snecma of a Form. */ + public static final String PV_REF_TRANSPO_SNECMA = "pv_ref_transpo_snecma"; + /** Property for retrieving the designationEN of a Form. */ + public static final String PV_REF_COMPLETE_CONCEPTEUR = "pv_ref_complete_concepteur"; + /** Property for retrieving the designationEN of a Form. */ + public static final String PV_DESIGNATION_EN = "pv_designation_en"; + /** Property for retrieving the document controle of a Part. */ + public static final String PV_DOCUMENT_CONTROLE = "pv_document_controle"; + /** Property for retrieving the obturation of a Part. */ + public static final String PV_OBTURATION = "pv_obturation"; + /** Property for retrieving the ref associated. */ + public static final String PV_REF_ASSOCIEE = "pv_ref_associee"; + /** Property for retrieving the coherence control. */ + public static final String PV_COHERENCE_CONTROL = "pv_controle_coherence"; + /** Property for retrieving the equivalent sns sin of a RF. */ + public static final String PV_EQUIVALENT_SNS_SIN = "pv_equivalent_sns_sin"; + /** + * Property for retrieving the equivalent maquette int ext of a RF Admin / RF Admin A. + */ + public static final String PV_MAQ_INT_EXT = "pv_maq_int_ext"; + /** Property for retrieving the type produit of a Part PV. */ + public static final String PV_TYPE_PRODUIT = "pv_type_produit"; + /** Property for retrieving the frontiere cooperant of a RF Admin Revision. */ + public static final String PV_FRONTIERE_COOPERANT = "pv_frontiere_cooperant"; + /** Property for retrieving the frontiere avion of a RF Admin Revision. */ + public static final String PV_FRONTIERE_AVION = "pv_frontiere_avion"; + /** Property for retrieving the 'origine demande'. */ + public static final String PV_ORIGINE_DEMANDE = "pv4_origine_demande"; + /** Property for retrieving the status of a User. */ + public static final String STATUS = "status"; + /** Property for retrieving the parts which are alternatives to an Alt Part. */ + public static final String PV_ALTERNATIVE = "_PV_alternative"; + /** Property for retrieving the 'Clause de propriete'. */ + public static final String PV_CLAUSE_PROPRIETE = "pv_clause_propriete"; + /** + * Property for retrieving the Effectivities of an effectivity TcReleaseStatus. + */ + public static final String EFFECTIVITIES = "effectivities"; + + // Internal Object types + /** Property for retrieving the type alternative 1 of an Alternate Revision Master. */ + public static final String PV_TYPE_ALTERNATIVE_1 = "pv_type_alternative_1"; + /** Property for retrieving the type alternative 2 of an Alternate Revision Master. */ + public static final String PV_TYPE_ALTERNATIVE_2 = "pv_type_alternative_2"; + /** Property for retrieving the type det 1 of a DET Revision Master. */ + public static final String PV_TYPE_DET_1 = "pv_type_det_1"; + /** Property for retrieving the type det 2 of a DET Revision Master. */ + public static final String PV_TYPE_DET_2 = "pv_type_det_2"; + /** Property for retrieving the type part montage 1 of a Part Assemb Revision Master. */ + public static final String PV_TYPE_PART_MONTAGE_1 = "pv_type_part_montage_1"; + /** Property for retrieving the type part montage 2 of a Part Assemb Revision Master. */ + public static final String PV_TYPE_PART_MONTAGE_2 = "pv_type_part_montage_2"; + /** Property for retrieving the type part non aero of a Part No Aero Revision Master. */ + public static final String PV_TYPE_PART_NON_AERO = "pv_type_part_non_aero"; + /** Property for retrieving the type part aero 3 of a Part Aero Revision Master. */ + public static final String PV_TYPE_PART_AERO_3 = "pv_type_part_aero_3"; + /** Property for retrieving the type part aero 2 of a Part Aero Revision Master. */ + public static final String PV_TYPE_PART_AERO_2 = "pv_type_part_aero_2"; + /** Property for retrieving the type part aero 1 of a Part Aero Revision Master. */ + public static final String PV_TYPE_PART_AERO_1 = "pv_type_part_aero_1"; + /** Property for retrieving the type standard of a Standard Revision Master. */ + public static final String PV_TYPE_STANDARD = "pv_type_standard"; + /** Property for retrieving the type of a DocNorm. */ + public static final String PV_TYPE_DOC_NORM = "pv_type_doc_norm"; + + // TcReleaseStatus names + /** TcReleaseStatus name 'Def Approved'. */ + public static final String DEF_APPROVED = "Def Approved"; + + // Geometry properties + /** Property for retrieving the 'geometrie piece rigide'. */ + public static final String PV_GEOMETRIE_PIECE_RIGIDE = "pv_geo_piece_rigide"; + /** Property for retrieving the 'geometrie simplifiee'. */ + public static final String PV_GEOMETRIE_SIMPLIFIEE = "pv_geo_piece_simplifiee"; + /** Property for retrieving the 'enveloppe cinematique'. */ + public static final String PV_ENVELOPPE_CINEMATIQUE = "pv_enveloppe_cinematique"; + /** Property for retrieving the 'enveloppe maintenance'. */ + public static final String PV_ENVELOPPE_MAINTENANCE = "pv_enveloppe_maintenance"; + /** Property for retrieving the 'enveloppe montage'. */ + public static final String PV_ENVELOPPE_MONTAGE = "pv_enveloppe_montage"; + /** Property for retrieving the 'trace axiale'. */ + public static final String PV_TRACE_AXIALE = "pv_trace_axiale"; + /** Property for retrieving the 'interface RF Admn'. */ + public static final String PV_INTERFACE_RF_ADMIN = "pv_interface"; + public static final String PV_PROJET_MOTEUR = "pv_projet_moteur"; + public static final String PV_MAQ_ECHANGEABLE = "pv_maq_echangeable"; + public static final String PV_WORKPACKAGE = "pv_workpackage"; + + // TcEffectivity properties + /** Property for retrieving the date_range_text of a date TcEffectivity. */ + public static final String DATE_TEXT_RANGE = "date_range_text"; + /** Property for retrieving the unit_range_text of a Unit. */ + public static final String UNIT_RANGE_TEXT = "unit_range_text"; + + // documentation pseudo-folder (Specific Snecma) + /** Property for retrieving the REACH documents of a Part. */ + public static final String FOLDER_PV_REACH_DOCS = "_PV_reach_docs"; + /** Property for retrieving the ITAR documents of a Part. */ + public static final String FOLDER_PV_ITAR_DOCS = "_PV_itar_docs"; + /** Property for retrieving the definition documents of a Part. */ + public static final String FOLDER_PV_DEFINITION_DOCS = "_PV_definition_docs"; + + // Spare Parts form properties + /** Property for retrieving the 'mot cle EN' */ + public static final String PV_MOT_CLEF_EN = "pv_mot_clef_en"; + /** Property for retrieving the 'mot cle FR' */ + public static final String PV_MOT_CLEF_FR = "pv_mot_clef_fr"; +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/TcBusinessObject.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/TcBusinessObject.java new file mode 100644 index 0000000..33de617 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/TcBusinessObject.java @@ -0,0 +1,4 @@ +package com.capgemini.framework.teamcenter.object; + +public interface TcBusinessObject extends TcModelObject { +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/TcModelObject.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/TcModelObject.java new file mode 100644 index 0000000..6e9860c --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/TcModelObject.java @@ -0,0 +1,6 @@ +package com.capgemini.framework.teamcenter.object; + +public interface TcModelObject { + + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/TcPomObject.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/TcPomObject.java new file mode 100644 index 0000000..6ec23ae --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/TcPomObject.java @@ -0,0 +1,6 @@ +package com.capgemini.framework.teamcenter.object.pom; + +import com.capgemini.framework.teamcenter.object.TcBusinessObject; + +public interface TcPomObject extends TcBusinessObject { +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/status/StatusEnum.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/status/StatusEnum.java new file mode 100644 index 0000000..0d91940 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/status/StatusEnum.java @@ -0,0 +1,273 @@ +package com.capgemini.framework.teamcenter.object.pom.status; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.ReleaseStatus; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Enumeration of status. Use {@link StatusEnum#toString()} for the user-friendly name, and {@link StatusEnum#getIdentifier()} for the actual Tc code name. + */ +@Slf4j +@Getter +@AllArgsConstructor +public enum StatusEnum { + AD_CANCELLED("AD Cancelled"), + AD("AD"), + J0("J0"), + J1("J1"), + J2("J2"), + J3A("J3A"), + J3B("J3B"), + STUDY_CLOSED("Study closed"), + STUDY_FINISHED("PV4_STU_FINISHED"), + STUDY_FINISHED_A("PV4_STU_FINISHED_A"), + PRELIM_DEF_READY("Prelim Def Ready"), + DEF_READY("Def Ready"), + PRELIM_DEF_APPROVED("Prelim Def Approved"), + DEF_APPROVED("Def Approved"), + DEF_FINISHED("PV4_DEF_FINISHED"), + PUBLISHED("Published"), + FROZEN_IN_PROCESS("Frozen in process"), + FROZEN("Frozen"), + CREATED("Created"), + PRELIM_CREATED("Prelim Created"), + OPENING_IN_PROCESS("Opening in process"), + OPEN("Open"), + CANCELLED("Cancelled"), + FINISHED("Finished"), + PB_REPORT_APPROVED("Pb Report Approved"), + SB_DISTRIBUTED("SB distributed"), + + INTERFACE_TODO("Interface TODO"), + DMU_KO_PART_R("DMU KO PART R"), + DMU_KO_PART_S("DMU KO PART S"), + DMU_KO_PART_P("DMU KO PART P"), + DMU_KO_PART_K("DMU KO PART K"), + DMU_KO_PART_M("DMU KO PART M"), + DMU_KO_PART_I("DMU KO PART I"), + DMU_KO_PART_C("DMU KO PART C"), + DMU_OK("DMU OK"), + DMU_READY("DMU Ready"), + + EFFECTIVITY(SnecmaObjectTypes.EFFECTIVITY), + SET_EFFECTIVITY("Set_Effectivity"), + OLD_EFFECTIVITY("Old effectivity"), + UNKNOWN_STATUS("Unknown"); + + /** + * Filter that keeps only DMU statuses. + */ + public static final AbstractStatusFilter ONLY_DMU = + new StatusInclusionFilter(DMU_KO_PART_C, DMU_KO_PART_I, DMU_KO_PART_K, DMU_KO_PART_M, DMU_KO_PART_P, DMU_KO_PART_R, DMU_KO_PART_S); + /** + * Filter that keeps only TcEffectivity statuses. + */ + public static final AbstractStatusFilter ONLY_EFFECTIVITIES = new StatusInclusionFilter(EFFECTIVITY, SET_EFFECTIVITY, OLD_EFFECTIVITY); + /** + * Filter that keeps Change Maturity statuses. + */ + public static final AbstractStatusFilter CHANGE_MATURITY = new StatusInclusionFilter(AD, AD_CANCELLED, CANCELLED, CREATED, DEF_APPROVED, + DEF_READY, DEF_FINISHED, FINISHED, J0, J1, J2, J3A, J3B, PB_REPORT_APPROVED, PRELIM_CREATED, PRELIM_DEF_APPROVED, PRELIM_DEF_READY, + SB_DISTRIBUTED, STUDY_CLOSED, STUDY_FINISHED, STUDY_FINISHED_A); + /** + * Filter that keeps Unit Maturity statuses. + */ + public static final AbstractStatusFilter UNIT_MATURITY = + new StatusInclusionFilter(OPENING_IN_PROCESS, OPEN, J3A, J3B, FROZEN_IN_PROCESS, FROZEN, CANCELLED); + private final String identifier; + + /** + * Give the appropriate {@link StatusEnum} associate to the string value.
    + * Else return null. + * + * @param value String - the string value + * @return the appropriate {@link StatusEnum}. Return {@link StatusEnum#UNKNOWN_STATUS} if the string value doesn't exist. + */ + public static StatusEnum getStatusEnum(final String value) { + for (StatusEnum status : StatusEnum.values()) { + if (status.identifier.equals(value)) { + return status; + } + } + log.warn("Unsupported status found. The string {} is not valid.", value); + return UNKNOWN_STATUS; + } + + /** + * Creates a {@link AbstractStatusFilter} object which will only allow the provided StatusEnum. + * + * @param authorized the authorized {@link StatusEnum}s. + * @return the {@link AbstractStatusFilter} + */ + public static AbstractStatusFilter allow(final StatusEnum... authorized) { + return new StatusInclusionFilter(authorized); + } + + /** + * Creates a {@link AbstractStatusFilter} object which will only not allow the provided StatusEnum. + * + * @param forbidden the forbidden {@link StatusEnum}s. + * @return the {@link AbstractStatusFilter} + */ + public static AbstractStatusFilter forbid(final StatusEnum... forbidden) { + return new StatusExclusionFilter(forbidden); + } + + /** + * Definition of a filter that may allow or not a StatusEnum based on its (String) name, or on its StatusEnum instance. + */ + public abstract static class AbstractStatusFilter { + + /** + * Returns true if the provided status should be excluded. + * + * @param status the status to evaluate + * @return true if it should be excluded, false otherwise + */ + public abstract boolean isExcluded(final StatusEnum status); + + /** + * Returns true if the provided status should be included. + * + * @param status the status to evaluate + * @return true if it should be included, false otherwise + */ + public abstract boolean isIncluded(final StatusEnum status); + + /** + * Returns true if the provided status name should be excluded. + * + * @param status the status to evaluate + * @return true if it should be excluded, false otherwise. + */ + public boolean isExcluded(final TcReleaseStatus status) { + StatusEnum statusEnum = status.getStatusEnum(); + return isExcluded(statusEnum); + } + + /** + * Returns true if the provided status name should be included. + * + * @param status the status to evaluate + * @return true if it should be included, false otherwise. + */ + public boolean isIncluded(final TcReleaseStatus status) { + StatusEnum statusEnum = status.getStatusEnum(); + return isIncluded(statusEnum); + } + + /** + * Returns true if the provided status name should be excluded. + * + * @param status the name of the status to evaluate + * @return true if it should be excluded, false otherwise. + */ + public boolean isExcluded(final String status) { + StatusEnum statusEnum = getStatusEnum(status); + return isExcluded(statusEnum); + } + + /** + * Returns true if the provided status name should be included. + * + * @param status the name of the status to evaluate + * @return true if it should be included, false otherwise. + */ + public boolean isIncluded(final String status) { + StatusEnum statusEnum = getStatusEnum(status); + return isIncluded(statusEnum); + } + + /** + * Returns true if the provided {@link ReleaseStatus} name should be excluded. + * + * @param status the status to evaluate + * @return true if it should be excluded, false otherwise. + */ + public boolean isExcluded(final ReleaseStatus status) { + StatusEnum statusEnum = getStatusEnum(status.get_name()); + return isExcluded(statusEnum); + } + + /** + * Returns true if the provided {@link ReleaseStatus} name should be included. + * + * @param status the status to evaluate + * @return true if it should be included, false otherwise. + */ + public boolean isIncluded(final ReleaseStatus status) { + StatusEnum statusEnum = getStatusEnum(status.get_name()); + return isIncluded(statusEnum); + } + + /** + * Filter the statuses of the provided {@link ItemRevision}. + * + * @param curItemRevision the item carrying some statuses. + * @return a {@link List} of {@link ReleaseStatus} that comply with this filter. + */ + public List filterStatusOf(final TcSession session, final ItemRevision curItemRevision) { + List selected = new ArrayList<>(); + session.loadProperties(curItemRevision, "release_status_list"); + ReleaseStatus[] releaseStatuses = curItemRevision.get_release_status_list(); + session.loadProperties(releaseStatuses); + for (ReleaseStatus status : releaseStatuses) { + String statusName = status.get_name(); + if (isIncluded(statusName)) { + selected.add(status); + } + } + return selected; + } + } + + static class StatusInclusionFilter extends AbstractStatusFilter { + + private final StatusEnum[] authorized; + + protected StatusInclusionFilter(final StatusEnum... authorized) { + super(); + this.authorized = authorized; + Arrays.sort(authorized); + } + + @Override + public boolean isExcluded(final StatusEnum status) { + return !isIncluded(status); + } + + @Override + public boolean isIncluded(final StatusEnum status) { + return Arrays.binarySearch(authorized, status) >= 0; + } + } + + private static class StatusExclusionFilter extends AbstractStatusFilter { + + private final StatusEnum[] forbidden; + + protected StatusExclusionFilter(final StatusEnum... forbidden) { + super(); + this.forbidden = forbidden; + Arrays.sort(forbidden); + } + + @Override + public boolean isExcluded(final StatusEnum type) { + return Arrays.binarySearch(forbidden, type) >= 0; + } + + @Override + public boolean isIncluded(final StatusEnum type) { + return !isExcluded(type); + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/status/TcEffectivity.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/status/TcEffectivity.java new file mode 100644 index 0000000..6fb3d6a --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/status/TcEffectivity.java @@ -0,0 +1,62 @@ +package com.capgemini.framework.teamcenter.object.pom.status; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.teamcenter.soa.client.model.strong.Effectivity; +import com.teamcenter.soa.client.model.strong.Item; + +import java.io.Serializable; + +/** + * Represents a Unit effectivity. + */ +public final class TcEffectivity implements Serializable { + private static final long serialVersionUID = -181276898335854241L; + private final Effectivity effectivity; + private final TcSession session; + + public TcEffectivity(TcSession session, final Effectivity effectivity) { + this.session = session; + this.effectivity = effectivity; + } + + public String endItemId() { + session.loadProperties(effectivity, "end_item"); + Item endItem = effectivity.get_end_item(); + if (endItem != null) { + session.loadProperties(endItem, "item_id"); + return endItem.get_item_id(); + } else { + return ""; + } + } + + public Item endItem() { + session.loadProperties(effectivity, "end_item"); + return effectivity.get_end_item(); + } + + public int[] unitNumbers() { + session.loadProperties(effectivity, "effectivity_units"); + return effectivity.get_effectivity_units(); + } + + public String unitRange() { + session.loadProperties(effectivity, "unit_range_text"); + return effectivity.get_unit_range_text(); + } + + public String dateRange() { + session.loadProperties(effectivity, "date_range_text"); + return effectivity.get_date_range_text(); + } + + public int unitOpenEndedStatus() { + session.loadProperties(effectivity, "unit_open_ended_status"); + return effectivity.get_unit_open_ended_status(); + } + + @Override + public String toString() { + return "TcEffectivity " + endItemId() + "[" + ((unitRange() == null || unitRange().isEmpty()) ? dateRange() : unitRange()) + "]"; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/status/TcReleaseStatus.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/status/TcReleaseStatus.java new file mode 100644 index 0000000..caf3971 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/status/TcReleaseStatus.java @@ -0,0 +1,202 @@ +package com.capgemini.framework.teamcenter.object.pom.status; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Effectivity; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.ReleaseStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Comparator; +import java.util.List; + +import static com.capgemini.framework.teamcenter.TeamcenterObjectProperties.NAME; + +/** + * Represents a Release TcReleaseStatus.
    + * A Release TcReleaseStatus may represent either of the following : + *

      + *
    • An effectivity
      + * In this case the ReleaseStatus is named "TcEffectivity" and owns a {@link List} of {@link TcEffectivity Effectivities}
    • + *
    • A Maturity (J3A, J3B etc.)
    • + *
    • Any other TcReleaseStatus ('Interface Todo', etc.)
    • + *
    + */ +public class TcReleaseStatus { + private static final Logger LOGGER = LoggerFactory.getLogger(TcReleaseStatus.class); + + private final ReleaseStatus releaseStatus; + private TcSession session; + + public TcReleaseStatus(final TcSession session, final ReleaseStatus status) { + this.session = session; + this.releaseStatus = status; + } + + /** + * Filters a {@code List} of {@link TcReleaseStatus} according to a list of eligible statuses. + * + * @param releaseStatusList List<{@link TcReleaseStatus}> - all the releaseStatus of an object + * @param eligible ({@link StatusEnum}) - Enumeration of eligible statuses + * @return the list of the appropriate releaseStatus + */ + public static List filter(final List releaseStatusList, final StatusEnum... eligible) { + List listOfChosenRS = new ArrayList<>(); + for (TcReleaseStatus status : releaseStatusList) { + if (status != null) { + for (StatusEnum wantedStatus : eligible) { + if (wantedStatus == status.getStatusEnum()) { + listOfChosenRS.add(status); + } + } + } + } + return listOfChosenRS; + } + + /** + * Obtains the list of {@link ReleaseStatus} and filter them according to a list of eligible statuses. + * + * @param itemRevision {@link ItemRevision} + * @param eligibleStatus Enumeration of wanted releaseStatus ({@link StatusEnum}). + * @return List + */ + public static List getChosenStatus(final TcSession session, final ItemRevision itemRevision, final StatusEnum... eligibleStatus) { + List listOfChosenRS = new ArrayList<>(); + session.loadProperties(itemRevision, "release_status_list"); + ReleaseStatus[] releaseStatuses = itemRevision.get_release_status_list(); + session.loadProperties(releaseStatuses); + for (ReleaseStatus status : releaseStatuses) { + if (status != null) { + for (StatusEnum wantedStatus : eligibleStatus) { + if (wantedStatus.getIdentifier().equals(status.get_name())) { + listOfChosenRS.add(status); + } + } + } + } + return listOfChosenRS; + } + + /** + * Get the list of {@link ReleaseStatus} and filter the {@link ReleaseStatus} in function of the forbidden releaseStatus. + * + * @param itemRevision {@link ItemRevision} + * @param forbiddenStatus Enumeration of forbidden releaseStatus({@link StatusEnum}) + * @return List + */ + public static List getAllStatusExceptSome(final TcSession session, final ItemRevision itemRevision, final StatusEnum... forbiddenStatus) { + List listOfChosenRS = new ArrayList<>(); + session.loadProperties(itemRevision, "release_status_list"); + ReleaseStatus[] releaseStatuses = itemRevision.get_release_status_list(); + session.loadProperties(releaseStatuses); + for (ReleaseStatus status : releaseStatuses) { + if (status != null) { + boolean isSelected = true; + for (StatusEnum wantedStatus : forbiddenStatus) { + if (wantedStatus.getIdentifier().equals(status.get_name())) { + isSelected = false; + } + } + if (isSelected) { + listOfChosenRS.add(status); + } + } + } + return listOfChosenRS; + } + + public StatusEnum getStatusEnum() { + session.loadProperties(releaseStatus, "name"); + return StatusEnum.getStatusEnum(releaseStatus.get_name()); + } + + public Calendar dateReleased() { + session.loadProperties(releaseStatus, "date_released"); + return releaseStatus.get_date_released(); + } + + public String getDisplayableName() { + return releaseStatus.getPropertyObject(NAME).getDisplayableValue(); + } + + public TcEffectivity getEffectivity() { + if (isEffectivity()) { + session.loadProperties(releaseStatus, "effectivities"); + ModelObject[] effectivities = releaseStatus.get_effectivities(); + session.loadProperties(effectivities); + if (effectivities == null || effectivities.length == 0) { + LOGGER.debug("ReleaseStatus named '{}' does not contain Effectivities", getDisplayableName()); + } + else { + ModelObject objectEffectivity = effectivities[0]; // There should only be one effectivity, we ignore the rest of the list's content + // Cast of the ModelObject to the TcEffectivity of Teamcenter, do not confuse with the TcEffectivity of this application + return new TcEffectivity(session, (Effectivity) objectEffectivity); + } + } + return null; + } + + public List getEffectivities() { + List tcEffectivities = new ArrayList<>(); + if (isEffectivity()) { + session.loadProperties(releaseStatus, "effectivities"); + ModelObject[] effectivities = releaseStatus.get_effectivities(); + session.loadProperties(effectivities); + for (ModelObject effectivity : effectivities) { + tcEffectivities.add(new TcEffectivity(session, (Effectivity) effectivity)); + } + } + return tcEffectivities; + } + + public boolean isEffectivity() { + StatusEnum statusName = getStatusEnum(); + return StatusEnum.ONLY_EFFECTIVITIES.isIncluded(statusName) || StatusEnum.ONLY_DMU.isIncluded(statusName); + } + + /** + * Returns true if this ReleaseStatus controls a Change's maturity. + * + * @return true if the releaseStatus represents a Maturity + */ + public boolean isChangeMaturity() { + return StatusEnum.CHANGE_MATURITY.isIncluded(getStatusEnum()); + } + + public boolean isOneOf(StatusEnum... statuses) { + StatusEnum statusEnum = getStatusEnum(); + for (StatusEnum status : statuses) { + if (statusEnum.equals(status)) { + return true; + } + } + return false; +} + + @Override + public String toString() { + TcEffectivity effectivity = getEffectivity(); + if (effectivity == null) { + return "TcReleaseStatus with NAME= " + getStatusEnum(); + } + else { + return "TcReleaseStatus with NAME= " + getStatusEnum() + " RANGE= " + effectivity.unitRange(); + } + } + + public enum Order implements Comparator { + BY_RELEASE_DATE() { + @Override + public int compare(final TcReleaseStatus releaseStatus1, final TcReleaseStatus releaseStatus2) { + return releaseStatus1.dateReleased().compareTo(releaseStatus2.dateReleased()); + } + }; + + @Override + public abstract int compare(final TcReleaseStatus releaseStatus1, final TcReleaseStatus releaseStatus2); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/TcItem.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/TcItem.java new file mode 100644 index 0000000..978d83f --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/TcItem.java @@ -0,0 +1,5 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace; + +public interface TcItem extends TcWorkspaceObject { + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/TcItemRevision.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/TcItemRevision.java new file mode 100644 index 0000000..c28913c --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/TcItemRevision.java @@ -0,0 +1,4 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace; + +public interface TcItemRevision extends TcWorkspaceObject { +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/TcWorkspaceObject.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/TcWorkspaceObject.java new file mode 100644 index 0000000..79cbd8d --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/TcWorkspaceObject.java @@ -0,0 +1,6 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace; + +import com.capgemini.framework.teamcenter.object.pom.TcPomObject; + +public interface TcWorkspaceObject extends TcPomObject { +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/TcBomObject.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/TcBomObject.java new file mode 100644 index 0000000..c6587a0 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/TcBomObject.java @@ -0,0 +1,8 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom; + +import com.capgemini.framework.teamcenter.object.pom.workspace.TcWorkspaceObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement.CreateWindowsInfo2; + +public interface TcBomObject extends TcWorkspaceObject { + void addInfo(final CreateWindowsInfo2 createWindowsInfo2); +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/TcBomObjectFactory.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/TcBomObjectFactory.java new file mode 100644 index 0000000..85a0d86 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/TcBomObjectFactory.java @@ -0,0 +1,105 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.generic.*; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.part.*; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.product.TcProduct; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.product.TcProductRevision; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.WorkspaceObject; + +public class TcBomObjectFactory { + private final WorkspaceObject modelObject; + private final TcSession session; + + public TcBomObjectFactory(final TcSession session, final WorkspaceObject modelObject) { + this.session = session; + this.modelObject = modelObject; + } + + + public TcBomObject create() throws KurtException { + TcBomObject tcBomObject; + switch (modelObject.getTypeObject().getName()) { + case SnecmaObjectTypes.PRODUCT: + tcBomObject = new TcProduct(session, (Item) modelObject); + break; + case SnecmaObjectTypes.GENERIC: + tcBomObject = new TcGeneric((Item) modelObject); + break; + case SnecmaObjectTypes.RF_GENERIC: + tcBomObject = new TcRFGeneric((Item) modelObject); + break; + case SnecmaObjectTypes.GENERIC_ASSEMB: + tcBomObject = new TcGenericAssemb((Item) modelObject); + break; + case SnecmaObjectTypes.GENERIC_REVISION: + tcBomObject = new TcGenericRevision((ItemRevision) modelObject); + break; + case SnecmaObjectTypes.GENERIC_ASSEMB_REVISION: + tcBomObject = new TcGenericAssembRevision((ItemRevision) modelObject); + break; + /*case SnecmaObjectTypes.SUPERMODEL_REVISION: + tcBomObject = new TcSuper + */ + case SnecmaObjectTypes.RF_GENERIC_REVISION: + tcBomObject = new TcRFGenericRevision((ItemRevision) modelObject); + break; + case SnecmaObjectTypes.PART_AERO_REVISION: + tcBomObject = new TcPartAeroRevision((ItemRevision) modelObject); + break; + case SnecmaObjectTypes.PART_NO_AERO_REVISION: + tcBomObject = new TcPartNoAeroRevision((ItemRevision) modelObject); + break; + case SnecmaObjectTypes.PART_MAT_REVISION: + tcBomObject = new TcPartMatRevision((ItemRevision) modelObject); + break; + case SnecmaObjectTypes.STANDARD_REVISION: + tcBomObject = new TcStandardRevision((ItemRevision) modelObject); + break; + case SnecmaObjectTypes.DET_REVISION: + tcBomObject = new TcDetRevision((ItemRevision) modelObject); + break; + case SnecmaObjectTypes.ALTERNATE_REVISION: + tcBomObject = new TcAlternateRevision((ItemRevision) modelObject); + break; + case SnecmaObjectTypes.PART_ASSEMB_REVISION: + tcBomObject = new TcPartAssembRevision((ItemRevision) modelObject); + break; + case SnecmaObjectTypes.RF_PART_REVISION: + tcBomObject = new TcRFPartRevision((ItemRevision) modelObject); + break; + case SnecmaObjectTypes.ALTERNATE: + tcBomObject = new TcAlternate((Item) modelObject); + break; + case SnecmaObjectTypes.DET: + tcBomObject = new TcDet((Item) modelObject); + break; + case SnecmaObjectTypes.PART_AERO: + tcBomObject = new TcPartAero((Item) modelObject); + break; + case SnecmaObjectTypes.PART_ASSEMB: + tcBomObject = new TcPartAssemb((Item) modelObject); + break; + case SnecmaObjectTypes.PART_MAT: + tcBomObject = new TcPartMat((Item) modelObject); + break; + case SnecmaObjectTypes.PART_NO_AERO: + tcBomObject = new TcPartNoAero((Item) modelObject); + break; + case SnecmaObjectTypes.STANDARD: + tcBomObject = new TcStandard((Item) modelObject); + break; + case SnecmaObjectTypes.PRODUCT_REVISION: + tcBomObject = new TcProductRevision(session, (ItemRevision) modelObject); + break; + default: + throw new KurtException("Invalid Teamcenter type for: (" + modelObject.getTypeObject().getName() + ")" + modelObject.getUid()); + } + + return tcBomObject; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/TcRFPartRevision.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/TcRFPartRevision.java new file mode 100644 index 0000000..9ef4806 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/TcRFPartRevision.java @@ -0,0 +1,17 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom; + +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +public class TcRFPartRevision implements TcBomObject { + private final ItemRevision itemRevision; + + public TcRFPartRevision(final ItemRevision itemRevision) { + this.itemRevision = itemRevision; + } + + @Override + public void addInfo(StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.itemRev = itemRevision; + } +} \ No newline at end of file diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/TcRevisionRule.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/TcRevisionRule.java new file mode 100644 index 0000000..a5866ea --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/TcRevisionRule.java @@ -0,0 +1,29 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.pom.workspace.TcWorkspaceObject; +import com.teamcenter.services.strong.cad._2007_01.StructureManagement.RevisionRuleConfigInfo; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.RevisionRule; + +import java.util.Map; + +public class TcRevisionRule implements TcWorkspaceObject { + private TcSession session; + private final RevisionRule revisionRule; + + public TcRevisionRule(final TcSession session, final RevisionRule revisionRule) { + this.session = session; + this.revisionRule = revisionRule; + } + + + public void addInfo(final RevisionRuleConfigInfo revRuleConfigInfo) { + revRuleConfigInfo.revRule = revisionRule; + } + + public void setProperties(Map map) { + session.setProperties(revisionRule, map); + } + +} \ No newline at end of file diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/TcRevisionRuleProperties.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/TcRevisionRuleProperties.java new file mode 100644 index 0000000..0fffd6f --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/TcRevisionRuleProperties.java @@ -0,0 +1,43 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.product.TcProduct; +import com.teamcenter.services.strong.cad._2007_01.StructureManagement.RevisionRuleConfigInfo; +import com.teamcenter.services.strong.cad._2007_01.StructureManagement.RevisionRuleEntryProps; + +import java.util.Calendar; + +public class TcRevisionRuleProperties { + private final TcProduct product; + private final int unit; + private final Calendar effectivityDate; + + public TcRevisionRuleProperties(final TcProduct product, final int unit) { + this(product, unit, null); + } + + public TcRevisionRuleProperties(final Calendar effectivityDate) { + this(null, 0, effectivityDate); + } + + public TcRevisionRuleProperties(final TcProduct product, final int unit, final Calendar effectivityDate) { + this.product = product; + this.unit = unit; + this.effectivityDate = effectivityDate; + } + + public void addInfo(final RevisionRuleConfigInfo revisionRuleConfigInfo) { + RevisionRuleEntryProps props = new RevisionRuleEntryProps(); + // Date used by configuration, else the current date is used for configuration + if (effectivityDate != null) { + props.date = effectivityDate; + } else { + props.today = true; + } + + if (product != null) { + product.addInfo(props); + } + props.unitNo = unit; + revisionRuleConfigInfo.props = props; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcGeneric.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcGeneric.java new file mode 100644 index 0000000..c8d3d87 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcGeneric.java @@ -0,0 +1,21 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.generic; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.soa.client.model.strong.Item; +import lombok.Getter; + +import static com.teamcenter.services.strong.cad._2013_05.StructureManagement.CreateWindowsInfo2; + +@Getter +public class TcGeneric implements TcGenericPv, TcBomObject { + private final Item item; + + public TcGeneric(final Item item) { + this.item = item; + } + + @Override + public void addInfo(final CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.item = item; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcGenericAssemb.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcGenericAssemb.java new file mode 100644 index 0000000..c129a3c --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcGenericAssemb.java @@ -0,0 +1,19 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.generic; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.soa.client.model.strong.Item; + +import static com.teamcenter.services.strong.cad._2013_05.StructureManagement.CreateWindowsInfo2; + +public class TcGenericAssemb implements TcGenericPv, TcBomObject { + private final Item item; + + public TcGenericAssemb(final Item item) { + this.item = item; + } + + @Override + public void addInfo(final CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.item = item; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcGenericAssembRevision.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcGenericAssembRevision.java new file mode 100644 index 0000000..6ec658a --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcGenericAssembRevision.java @@ -0,0 +1,18 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.generic; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +public class TcGenericAssembRevision implements TcGenericPv, TcBomObject { + private final ItemRevision itemRevision; + + public TcGenericAssembRevision(final ItemRevision itemRevision) { + this.itemRevision = itemRevision; + } + + @Override + public void addInfo(StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.itemRev = itemRevision; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcGenericPv.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcGenericPv.java new file mode 100644 index 0000000..dfb52e6 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcGenericPv.java @@ -0,0 +1,6 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.generic; + +import com.capgemini.framework.teamcenter.object.pom.workspace.TcItem; + +public interface TcGenericPv extends TcItem { +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcGenericPvRevision.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcGenericPvRevision.java new file mode 100644 index 0000000..b51d9a9 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcGenericPvRevision.java @@ -0,0 +1,6 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.generic; + +import com.capgemini.framework.teamcenter.object.pom.workspace.TcItemRevision; + +public interface TcGenericPvRevision extends TcItemRevision { +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcGenericRevision.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcGenericRevision.java new file mode 100644 index 0000000..798bc4a --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcGenericRevision.java @@ -0,0 +1,18 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.generic; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +public class TcGenericRevision implements TcGenericPv, TcBomObject { + private final ItemRevision itemRevision; + + public TcGenericRevision(final ItemRevision itemRevision) { + this.itemRevision = itemRevision; + } + + @Override + public void addInfo(StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.itemRev = itemRevision; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcRFGeneric.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcRFGeneric.java new file mode 100644 index 0000000..2790867 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcRFGeneric.java @@ -0,0 +1,18 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.generic; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.Item; + +public class TcRFGeneric implements TcGenericPv, TcBomObject { + private final Item item; + + public TcRFGeneric(final Item item) { + this.item = item; + } + + @Override + public void addInfo(StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.item = item; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcRFGenericRevision.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcRFGenericRevision.java new file mode 100644 index 0000000..a3d27c9 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/generic/TcRFGenericRevision.java @@ -0,0 +1,16 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.generic; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +public class TcRFGenericRevision implements TcGenericPv, TcBomObject { + private final ItemRevision itemRevision; + + public TcRFGenericRevision(final ItemRevision itemRevision) { + this.itemRevision = itemRevision; + } + + @Override + public void addInfo(StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { createWindowsInfo2.itemRev = itemRevision; } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcAlternate.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcAlternate.java new file mode 100644 index 0000000..16f67c3 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcAlternate.java @@ -0,0 +1,20 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.part; + +import com.capgemini.framework.teamcenter.object.pom.workspace.TcItem; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.Item; + +public class TcAlternate implements TcItem, TcBomObject { + private final Item item; + + public TcAlternate(final Item item) { + this.item = item; + } + + @Override + public void addInfo(final StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.item = item; + } +} + diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcAlternateRevision.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcAlternateRevision.java new file mode 100644 index 0000000..7d855a6 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcAlternateRevision.java @@ -0,0 +1,18 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.part; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +public class TcAlternateRevision implements TcBomObject { + private final ItemRevision itemRevision; + + public TcAlternateRevision(final ItemRevision itemRevision) { + this.itemRevision = itemRevision; + } + + @Override + public void addInfo(StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.itemRev = itemRevision; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcDet.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcDet.java new file mode 100644 index 0000000..8697bb5 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcDet.java @@ -0,0 +1,20 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.part; + +import com.capgemini.framework.teamcenter.object.pom.workspace.TcItem; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.Item; + +public class TcDet implements TcItem, TcBomObject { + private final Item item; + + public TcDet(final Item item) { + this.item = item; + } + + @Override + public void addInfo(final StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.item = item; + } +} + diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcDetRevision.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcDetRevision.java new file mode 100644 index 0000000..0798f62 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcDetRevision.java @@ -0,0 +1,18 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.part; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +public class TcDetRevision implements TcBomObject { + private final ItemRevision itemRevision; + + public TcDetRevision(final ItemRevision itemRevision) { + this.itemRevision = itemRevision; + } + + @Override + public void addInfo(StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.itemRev = itemRevision; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartAero.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartAero.java new file mode 100644 index 0000000..593dc39 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartAero.java @@ -0,0 +1,19 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.part; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.Item; + +public class TcPartAero implements TcBomObject { + private final Item item; + + public TcPartAero(final Item item) { + this.item = item; + } + + @Override + public void addInfo(final StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.item = item; + } +} + diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartAeroRevision.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartAeroRevision.java new file mode 100644 index 0000000..851cfb3 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartAeroRevision.java @@ -0,0 +1,18 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.part; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +public class TcPartAeroRevision implements TcBomObject { + private final ItemRevision itemRevision; + + public TcPartAeroRevision(final ItemRevision itemRevision) { + this.itemRevision = itemRevision; + } + + @Override + public void addInfo(StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.itemRev = itemRevision; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartAssemb.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartAssemb.java new file mode 100644 index 0000000..828a3d7 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartAssemb.java @@ -0,0 +1,18 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.part; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.Item; + +public class TcPartAssemb implements TcBomObject { + private final Item item; + + public TcPartAssemb(final Item item) { + this.item = item; + } + + @Override + public void addInfo(final StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.item = item; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartAssembRevision.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartAssembRevision.java new file mode 100644 index 0000000..a34e6dd --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartAssembRevision.java @@ -0,0 +1,18 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.part; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +public class TcPartAssembRevision implements TcBomObject { + private final ItemRevision itemRevision; + + public TcPartAssembRevision(final ItemRevision itemRevision) { + this.itemRevision = itemRevision; + } + + @Override + public void addInfo(StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.itemRev = itemRevision; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartMat.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartMat.java new file mode 100644 index 0000000..2f4a4d8 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartMat.java @@ -0,0 +1,18 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.part; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.Item; + +public class TcPartMat implements TcBomObject { + private final Item item; + + public TcPartMat(final Item item) { + this.item = item; + } + + @Override + public void addInfo(final StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.item = item; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartMatRevision.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartMatRevision.java new file mode 100644 index 0000000..78349f4 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartMatRevision.java @@ -0,0 +1,18 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.part; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +public class TcPartMatRevision implements TcBomObject { + private final ItemRevision itemRevision; + + public TcPartMatRevision(final ItemRevision itemRevision) { + this.itemRevision = itemRevision; + } + + @Override + public void addInfo(StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.itemRev = itemRevision; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartNoAero.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartNoAero.java new file mode 100644 index 0000000..a7512a9 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartNoAero.java @@ -0,0 +1,18 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.part; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.Item; + +public class TcPartNoAero implements TcBomObject { + private final Item item; + + public TcPartNoAero(final Item item) { + this.item = item; + } + + @Override + public void addInfo(final StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.item = item; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartNoAeroRevision.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartNoAeroRevision.java new file mode 100644 index 0000000..567d143 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcPartNoAeroRevision.java @@ -0,0 +1,18 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.part; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +public class TcPartNoAeroRevision implements TcBomObject { + private final ItemRevision itemRevision; + + public TcPartNoAeroRevision(final ItemRevision itemRevision) { + this.itemRevision = itemRevision; + } + + @Override + public void addInfo(StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.itemRev = itemRevision; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcStandard.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcStandard.java new file mode 100644 index 0000000..7770c99 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcStandard.java @@ -0,0 +1,18 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.part; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.Item; + +public class TcStandard implements TcBomObject { + private final Item item; + + public TcStandard(final Item item) { + this.item = item; + } + + @Override + public void addInfo(final StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.item = item; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcStandardRevision.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcStandardRevision.java new file mode 100644 index 0000000..f929a63 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/part/TcStandardRevision.java @@ -0,0 +1,18 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.part; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +public class TcStandardRevision implements TcBomObject { + private final ItemRevision itemRevision; + + public TcStandardRevision(final ItemRevision itemRevision) { + this.itemRevision = itemRevision; + } + + @Override + public void addInfo(StructureManagement.CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.itemRev = itemRevision; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/product/TcProduct.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/product/TcProduct.java new file mode 100644 index 0000000..927942d --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/product/TcProduct.java @@ -0,0 +1,43 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.product; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.pom.workspace.TcItem; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2007_01.StructureManagement.RevisionRuleEntryProps; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement.CreateWindowsInfo2; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import java.util.ArrayList; +import java.util.List; + +public class TcProduct implements TcItem, TcBomObject { + private final TcSession session; + private final Item item; + + public TcProduct(final TcSession session, final Item item) { + this.session = session; + this.item = item; + } + + @Override + public void addInfo(final CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.item = item; + } + + public void addInfo(final RevisionRuleEntryProps revisionRulesProps) { + revisionRulesProps.endItem = item; + } + + public List revisions() { + List revisions = new ArrayList<>(); + session.loadProperties(item, "revision_list"); + ModelObject[] revisionObjects = item.get_revision_list(); + session.loadProperties(revisionObjects); + for (ModelObject revision : revisionObjects) { + revisions.add(new TcProductRevision(session, (ItemRevision) revision)); + } + return revisions; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/product/TcProductRevision.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/product/TcProductRevision.java new file mode 100644 index 0000000..1c3ae96 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/product/TcProductRevision.java @@ -0,0 +1,219 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.product; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.object.pom.workspace.TcItemRevision; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.unit.TcUnitRevision; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.google.common.base.Optional; +import com.google.common.collect.ArrayListMultimap; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement.CreateWindowsInfo2; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.*; +import static com.capgemini.framework.teamcenter.object.pom.status.StatusEnum.*; + +public class TcProductRevision implements TcItemRevision, TcBomObject { + private final TcSession session; + private final ItemRevision itemRevision; + private static final Logger LOGGER = LoggerFactory.getLogger(TcProductRevision.class); + + public TcProductRevision(final TcSession session, final ItemRevision itemRevision) { + this.session = session; + this.itemRevision = itemRevision; + } + + @Override + public void addInfo(final CreateWindowsInfo2 createWindowsInfo2) { + createWindowsInfo2.itemRev = itemRevision; + } + + /** + * Method specific to r23. + * Returns a list of TcUnitRevision corresponding to R23 criteria + * */ + public List r23UnitRevisions(boolean isWithFrozenUnit, ProductUnit productUnitForUnit, ProductUnit productUnitFromUnit, String nbDaysSinceFrozenStr) throws KurtException { + List r23UnitRevisions = new ArrayList<>(); + LOGGER.debug("== r23UnitRevisions method -> START"); + List filteredUnitRevision = filterOnlyMostRecentReleasedUnitRevisions(); + if(!productUnitForUnit.getUnitStr().isEmpty()) { // Case : We search a specific unit + productUnitForUnit.parseUserUnit(); + int unitNumber = productUnitForUnit.getUnit(); + LOGGER.debug("We search only the unit : [{}]", unitNumber); + for (TcUnitRevision unitRevision : filteredUnitRevision) { + if(unitRevision.unitNumber() == unitNumber) { + r23UnitRevisions.add(unitRevision); + } + } + } else { // Case : we first get all units + Collections.sort(filteredUnitRevision, TcUnitRevision.Order.BY_UNIT_NUMBER); + List finalUnitRevisionList = new ArrayList<>(); + if(!productUnitFromUnit.getUnitStr().isEmpty()) { // Case : We take units "from a given one" + productUnitFromUnit.parseUserUnit(); + int unit = productUnitFromUnit.getUnit(); + LOGGER.debug("We search units from unit : [{}]", unit); + for (TcUnitRevision unitRevision : filteredUnitRevision) { + if(unitRevision.unitNumber() >= unit) { + finalUnitRevisionList.add(unitRevision); + } + } + } else { + finalUnitRevisionList = filteredUnitRevision; + } + for (TcUnitRevision unitRevision : finalUnitRevisionList) { + if (unitRevision.isValidUnitToR23(isWithFrozenUnit, nbDaysSinceFrozenStr)) { + r23UnitRevisions.add(unitRevision); + } + } + } + StringBuilder stringBuilder = new StringBuilder(); + for(TcUnitRevision unitRevision : r23UnitRevisions) { + if(stringBuilder.length() > 0) { + stringBuilder.append(";"); + } + stringBuilder.append(unitRevision.unitNumber()); + } + LOGGER.info("List of unit selected : [{}]", stringBuilder); + LOGGER.debug("== r23UnitRevisions method -> END"); + return r23UnitRevisions; + } + + /** + * Return a list of TcUnitRevision containing the revision with the most recent release date of each unit of the the Product + * */ + private List filterOnlyMostRecentReleasedUnitRevisions() throws KurtException { + List filteredUnitRevisions = new ArrayList<>(); + ArrayListMultimap unitMap = ArrayListMultimap.create(); + for (TcUnitRevision unitRevision : unitRevisions()) { + unitMap.put(unitRevision.unitNumber(), unitRevision); + } + for (Integer unitNum : unitMap.keySet()) { + List tcUnitRevisions = unitMap.get(unitNum); + Collections.sort(tcUnitRevisions, TcUnitRevision.Order.BY_RELEASE_DATE); + filteredUnitRevisions.add(tcUnitRevisions.get(tcUnitRevisions.size() - 1)); + } + return filteredUnitRevisions; + } + + private TcUnitRevision refUnitRevision(List filteredUnitRevision) { + for (int i = 0; i < filteredUnitRevision.size(); i++) { + TcUnitRevision unitRevision = filteredUnitRevision.get(i); + if (unitRevision.hasStatus(OPEN) && !unitRevision.isExceptionnel()) { + for (int j = i - 1; j >= 0; j--) { + TcUnitRevision searchedUnitRevision = filteredUnitRevision.get(j); + if (searchedUnitRevision.hasStatus(J3A, J3B, FROZEN) && !searchedUnitRevision.isExceptionnel()) { + return searchedUnitRevision; + } + } + } + } + return null; + } + + public List unitRevisionsWithStatus(final StatusEnum... statuses) { + List unitRevisions = new ArrayList<>(); + for (TcUnitRevision unitRevision : unitRevisions()) { + if (unitRevision.hasStatus(statuses)) { + unitRevisions.add(unitRevision); + } + } + return unitRevisions; + } + + public Optional unitRevision(int unitNumber) throws KurtException { + for (TcUnitRevision unitRevision : unitRevisions()) { + if (unitRevision.unitNumber() == unitNumber) { + return Optional.of(unitRevision); + } + } + return Optional.absent(); + } + + /** + * Method to retrieve the latest open status unit revision + * @param unitNumber Unit number of the unit to retrieve + * @return the Unit Revision as an Optional. + * @throws KurtException + */ + public Optional openUnitRevision(int unitNumber) throws KurtException { + for (TcUnitRevision unitRevision : unitRevisions()) { + if (unitRevision.unitNumber() == unitNumber && unitRevision.hasStatus(OPEN)) { + return Optional.of(unitRevision); + } + } + return Optional.absent(); + } + + /** + * Method that returns the latest uncancelled unit revision for a given unit number + * @param unitNumber Unit number of the unit to retrieve + * @return the Unit Revision as an Optional. + * @throws KurtException + */ + public Optional notCancelledRevision(int unitNumber) throws KurtException { + for (TcUnitRevision unitRevision : unitRevisions()) { + if (unitRevision.unitNumber() == unitNumber && !unitRevision.hasStatus(CANCELLED)) { + return Optional.of(unitRevision); + } + } + return Optional.absent(); + } + + public String ligneProduit() { + Form masterForm = masterForm(); + session.loadProperties(masterForm, PV_LIGNE_PRODUIT); + return masterForm.getPropertyObject(PV_LIGNE_PRODUIT).getStringValue(); + } + + private List unitRevisions() { + List unitRevisions = new ArrayList<>(); + session.loadProperties(itemRevision, PV_UNIT); + ModelObject[] listOfUnitsBelowProduct = itemRevision.getPropertyObject(PV_UNIT).getModelObjectArrayValue(); + session.loadProperties(listOfUnitsBelowProduct); + for (ModelObject unitRevision : listOfUnitsBelowProduct) { + if (SnecmaObjectTypes.UNIT_REVISION.equals(unitRevision.getTypeObject().getName())) { + unitRevisions.add(new TcUnitRevision(session, (ItemRevision) unitRevision)); + } + } + return unitRevisions; + } + + public String productType() { + Form masterForm = masterForm(); + session.loadProperties(masterForm, PV_TYPE_PRODUIT); + return masterForm().getPropertyObject(PV_TYPE_PRODUIT).getStringValue(); + } + + private Form masterForm() { + session.loadProperties(itemRevision, "item_master_tag"); + return itemRevision.get_item_master_tag(); + } + + public PSBOMView bomViewRev(){ + PSBOMView modelBom = null; + session.loadProperties(itemRevision ,"structure_revisions"); + for (ModelObject psBomViewRev : itemRevision.get_structure_revisions() ) { + session.loadProperties(psBomViewRev, "bom_view"); + PSBOMView bomView = ((PSBOMViewRevision) psBomViewRev).get_bom_view(); + session.loadProperties(bomView, "view_type"); + PSViewType viewType = bomView.get_view_type(); + session.loadProperties(viewType,"name"); + String bvrTypeName = viewType.get_name(); + if ("ModelListBom".equals(bvrTypeName)) { + modelBom = bomView; + break; + } + } + return modelBom; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/unit/TcUnitRevision.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/unit/TcUnitRevision.java new file mode 100644 index 0000000..ea8a148 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/pom/workspace/bom/unit/TcUnitRevision.java @@ -0,0 +1,177 @@ +package com.capgemini.framework.teamcenter.object.pom.workspace.bom.unit; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.object.pom.status.TcEffectivity; +import com.capgemini.framework.teamcenter.object.pom.status.TcReleaseStatus; +import com.capgemini.framework.teamcenter.object.pom.workspace.TcItemRevision; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.generic.TcGeneric; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.generic.TcGenericAssemb; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.generic.TcGenericPv; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Form; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.ReleaseStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Comparator; +import java.util.List; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_GENERIC; +import static com.capgemini.framework.teamcenter.object.pom.status.StatusEnum.*; +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.GENERIC; +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.GENERIC_ASSEMB; + +public class TcUnitRevision implements TcItemRevision { + private final TcSession session; + private final ItemRevision itemRevision; + private static final Logger LOGGER = LoggerFactory.getLogger(TcUnitRevision.class); + + public TcUnitRevision(TcSession session, final ItemRevision itemRevision) { + this.session = session; + this.itemRevision = itemRevision; + } + + public boolean hasStatus(final StatusEnum... statuses) { + for (TcReleaseStatus releaseStatus : releaseStatuses()) { + if (releaseStatus.isOneOf(statuses)) { + return true; + } + } + return false; + } + + public int unitNumber() throws KurtException { + for (TcReleaseStatus releaseStatus : releaseStatuses()) { + if (releaseStatus.isEffectivity()) { + TcEffectivity tcEffectivity = releaseStatus.getEffectivity(); + if (tcEffectivity != null) { + return tcEffectivity.unitNumbers()[0]; + } + } + } + throw new KurtException("Aucune effectivité portant un numéro de unit trouvé sur le Unit " + itemRevision.getUid()); + } + + public Calendar dateReleased() { + session.loadProperties(itemRevision, "date_released"); + return itemRevision.get_date_released(); + } + + public boolean isExceptionnel() { + Form formRev = getMasterFormRev(); + session.loadProperties(formRev, "pv_unit_exceptionnel"); + return "Oui / Yes".equalsIgnoreCase(formRev.getPropertyObject("pv_unit_exceptionnel").getStringValue()); + } + + + public List genericPvs() { + List generics = new ArrayList<>(); + session.loadProperties(itemRevision, PV_GENERIC); + ModelObject[] genericObjs = itemRevision.getPropertyObject(PV_GENERIC).getModelObjectArrayValue(); + session.loadProperties(genericObjs); + for (ModelObject generic : genericObjs) { + String typeName = generic.getTypeObject().getName(); + if (GENERIC.equals(typeName)) { + generics.add(new TcGeneric((Item) generic)); + } + else if (GENERIC_ASSEMB.equals(typeName)) { + generics.add(new TcGenericAssemb((Item) generic)); + } + } + return generics; + } + + private List releaseStatuses() { + List releaseStatuses = new ArrayList<>(); + session.loadProperties(itemRevision, "release_status_list"); + ReleaseStatus[] statuses = itemRevision.get_release_status_list(); + session.loadProperties(statuses); + for (ReleaseStatus releaseStatus : statuses) { + releaseStatuses.add(new TcReleaseStatus(session, releaseStatus)); + } + return releaseStatuses; + } + + private TcReleaseStatus frozenStatus() { + for (TcReleaseStatus releaseStatus : releaseStatuses()) { + if (releaseStatus.isOneOf(StatusEnum.FROZEN)) { + return releaseStatus; + } + } + return null; + } + + private Form getMasterFormRev() { + session.loadProperties(itemRevision, "item_master_tag"); + return itemRevision.get_item_master_tag(); + } + + public boolean isValidUnitToR23(boolean withFrozenUnits, String nbDaysSinceFrozenStr) { + int unit = 0; + String rev = this.getUnitRev(); + try { + unit = this.unitNumber(); + } catch (KurtException e) { + LOGGER.debug("Error message when trying access unitNumber of TcUnitRevision : [{}]", e.getMessage()); + } + LOGGER.debug("Check validity of unit [{}] rev [{}] for R23, withFrozenUnit = [{}], nbDaysSinceFrozen = [{}]", + unit, rev, withFrozenUnits, nbDaysSinceFrozenStr); + if(withFrozenUnits) { + if(!nbDaysSinceFrozenStr.isEmpty()) { + int nbJour = Integer.parseInt(nbDaysSinceFrozenStr); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Calendar c = Calendar.getInstance(); // Get current date + c.add(Calendar.DAY_OF_MONTH, -nbJour); + LOGGER.debug("Date after soustraction of {} day(s) : {}", nbJour, sdf.format(c.getTime())); + LOGGER.debug("Unit [{}] has status OPEN OR (date release after [{}] AND a status FROZEN, FROZEN_IN_PROCESS, J3A or J3B) ? : [{}]", unit, sdf.format(c.getTime()), hasStatus(J3A, J3B, FROZEN, FROZEN_IN_PROCESS)); + return hasStatus(OPEN) || (dateReleased().after(c) && hasStatus(J3A, J3B, FROZEN, FROZEN_IN_PROCESS)); + } + LOGGER.debug("Unit [{}] has status OPEN or FROZEN, FROZEN_IN_PROCESS, J3A or J3B ? : [{}]", unit, hasStatus(OPEN, J3A, J3B, FROZEN, FROZEN_IN_PROCESS)); + return hasStatus(OPEN, J3A, J3B, FROZEN, FROZEN_IN_PROCESS); + } else { + LOGGER.debug("Unit [{}] has status OPEN ? : [{}]", unit, hasStatus(OPEN)); + return hasStatus(OPEN); + } + } + + /** Get unit revision "item_revision_id" attribute */ + public String getUnitRev() { + session.loadProperties(itemRevision, "item_revision_id"); + return itemRevision.get_item_revision_id(); + } + + public enum Order implements Comparator { + BY_FROZEN_RELEASE_DATE() { + @Override + public int compare(final TcUnitRevision unitRevision1, final TcUnitRevision unitRevision2) { + TcReleaseStatus frozenStatus1 = unitRevision1.frozenStatus(); + TcReleaseStatus frozenStatus2 = unitRevision2.frozenStatus(); + return TcReleaseStatus.Order.BY_RELEASE_DATE.compare(frozenStatus1, frozenStatus2); + } + }, + BY_RELEASE_DATE() { + @Override + public int compare(final TcUnitRevision unitRevision1, final TcUnitRevision unitRevision2) { + return unitRevision1.dateReleased().compareTo(unitRevision2.dateReleased()); + } + }, + BY_UNIT_NUMBER() { + @Override + public int compare(final TcUnitRevision unitRevision1, final TcUnitRevision unitRevision2) { + try { + return Integer.compare(unitRevision1.unitNumber(), unitRevision2.unitNumber()); + } + catch (KurtException e) { + return -1; + } + } + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/runtime/TcBomLine.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/runtime/TcBomLine.java new file mode 100644 index 0000000..ac335bd --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/runtime/TcBomLine.java @@ -0,0 +1,23 @@ +package com.capgemini.framework.teamcenter.object.runtime; + +import com.teamcenter.soa.client.model.strong.BOMLine; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TcBomLine implements TcRuntimeBusinessObject { + private static final Logger LOGGER = LoggerFactory.getLogger(TcBomLine.class); + private static final String NO_FILTER = "None2"; + + private final BOMLine bomLine; + + + public TcBomLine(final BOMLine bomLine) { + this.bomLine = bomLine; + } + + @Override + public String toString() { + return "TcBomLine{bomLine=" + bomLine.getUid() + '}'; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/runtime/TcBomWindow.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/runtime/TcBomWindow.java new file mode 100644 index 0000000..bb52aba --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/runtime/TcBomWindow.java @@ -0,0 +1,32 @@ +package com.capgemini.framework.teamcenter.object.runtime; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.teamcenter.soa.client.model.strong.BOMLine; +import com.teamcenter.soa.client.model.strong.BOMWindow; + +public class TcBomWindow implements TcRuntimeBusinessObject, AutoCloseable { + + private final BOMWindow bomWindow; + private final TcSession session; + + public TcBomWindow(final TcSession session, final BOMWindow bomWindow) { + this.session = session; + this.bomWindow = bomWindow; + } + + public BOMLine topLine() throws EmptyNomenclatureException { + session.loadProperties(bomWindow, "top_line"); + BOMLine topLine = (BOMLine) bomWindow.get_top_line(); + session.loadProperties(topLine, "bl_line_object"); + if (topLine == null || topLine.get_bl_line_object() == null) { + throw new EmptyNomenclatureException("The top item provided does not seem to be effective under the selected configuration"); + } + return topLine; + } + + @Override + public void close() { + session.getStructureManagementService().closeBOMWindows(new BOMWindow[]{bomWindow}); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/runtime/TcBomWindowConfiguration.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/runtime/TcBomWindowConfiguration.java new file mode 100644 index 0000000..63cc306 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/runtime/TcBomWindowConfiguration.java @@ -0,0 +1,30 @@ +package com.capgemini.framework.teamcenter.object.runtime; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcBomObject; +import com.teamcenter.services.strong.cad._2013_05.StructureManagement.CreateWindowsInfo2; +import com.teamcenter.soa.client.model.strong.PSBOMView; + +public class TcBomWindowConfiguration { + private final TcBomObject topLineObject; + private final PSBOMView bomview; + private final TcRevisionRulesConfiguration tcRevisionRulesConfiguration; + + public TcBomWindowConfiguration(final TcBomObject topLineObject, final TcRevisionRulesConfiguration tcRevisionRulesConfiguration) { + this(topLineObject, null, tcRevisionRulesConfiguration); + } + + public TcBomWindowConfiguration(final TcBomObject topLineObject, final PSBOMView bomview, final TcRevisionRulesConfiguration tcRevisionRulesConfiguration) { + this.topLineObject = topLineObject; + this.bomview = bomview; + this.tcRevisionRulesConfiguration = tcRevisionRulesConfiguration; + } + + public CreateWindowsInfo2[] toTcInfo() { + CreateWindowsInfo2[] createBOMWindowsInfo = new CreateWindowsInfo2[1]; + createBOMWindowsInfo[0] = new CreateWindowsInfo2(); + topLineObject.addInfo(createBOMWindowsInfo[0]); + tcRevisionRulesConfiguration.addInfo(createBOMWindowsInfo[0].revRuleConfigInfo); + createBOMWindowsInfo[0].bomView = bomview; + return createBOMWindowsInfo; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/runtime/TcBomWindowFactory.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/runtime/TcBomWindowFactory.java new file mode 100644 index 0000000..fcf37f5 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/runtime/TcBomWindowFactory.java @@ -0,0 +1,27 @@ +package com.capgemini.framework.teamcenter.object.runtime; + +import com.capgemini.framework.teamcenter.ServiceDataHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.teamcenter.services.strong.cad._2007_01.StructureManagement.CreateBOMWindowsOutput; +import com.teamcenter.services.strong.cad._2007_01.StructureManagement.CreateBOMWindowsResponse; + +public class TcBomWindowFactory { + private final TcBomWindowConfiguration bomWindowConfiguration; + private final TcSession session; + + public TcBomWindowFactory(final TcSession session, final TcBomWindowConfiguration bomWindowConfiguration) { + this.session = session; + this.bomWindowConfiguration = bomWindowConfiguration; + } + + public TcBomWindow create() throws KurtException { + CreateBOMWindowsResponse createBOMWindowsResponse = session.getStructureManagementService().createBOMWindows2(bomWindowConfiguration.toTcInfo()); + if (ServiceDataHelper.hasErrors(createBOMWindowsResponse.serviceData)) { + ServiceDataHelper.displayErrors(createBOMWindowsResponse.serviceData); + throw new KurtException("Error while creating bom window."); + } + CreateBOMWindowsOutput bomWindowsOutput = createBOMWindowsResponse.output[0]; + return new TcBomWindow(session, bomWindowsOutput.bomWindow); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/runtime/TcRevisionRulesConfiguration.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/runtime/TcRevisionRulesConfiguration.java new file mode 100644 index 0000000..5ee9c61 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/runtime/TcRevisionRulesConfiguration.java @@ -0,0 +1,27 @@ +package com.capgemini.framework.teamcenter.object.runtime; + +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRule; +import com.capgemini.framework.teamcenter.object.pom.workspace.bom.TcRevisionRuleProperties; +import com.teamcenter.services.strong.cad._2007_01.StructureManagement.RevisionRuleConfigInfo; + +public class TcRevisionRulesConfiguration { + + private final TcRevisionRule revisionRule; + private final TcRevisionRuleProperties revisionRuleProperties; + + public TcRevisionRulesConfiguration(final TcRevisionRule revisionRule) { + this(revisionRule, null); + } + + public TcRevisionRulesConfiguration(final TcRevisionRule revisionRule, final TcRevisionRuleProperties revisionRuleProperties) { + this.revisionRule = revisionRule; + this.revisionRuleProperties = revisionRuleProperties; + } + + public void addInfo(final RevisionRuleConfigInfo revRuleConfigInfo) { + revisionRule.addInfo(revRuleConfigInfo); + if (revisionRuleProperties != null) { + revisionRuleProperties.addInfo(revRuleConfigInfo); + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/runtime/TcRuntimeBusinessObject.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/runtime/TcRuntimeBusinessObject.java new file mode 100644 index 0000000..52b85f1 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/runtime/TcRuntimeBusinessObject.java @@ -0,0 +1,6 @@ +package com.capgemini.framework.teamcenter.object.runtime; + +import com.capgemini.framework.teamcenter.object.TcBusinessObject; + +public interface TcRuntimeBusinessObject extends TcBusinessObject { +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/types/SnecmaObjectTypes.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/types/SnecmaObjectTypes.java new file mode 100644 index 0000000..e63b8cb --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/object/types/SnecmaObjectTypes.java @@ -0,0 +1,465 @@ +package com.capgemini.framework.teamcenter.object.types; + +import com.capgemini.framework.teamcenter.TeamcenterObjectTypes; +import com.google.common.base.Joiner; + +import java.util.regex.Pattern; + +/** + * Class regrouping all the used type of Teamcenter Revision objects. + */ +public final class SnecmaObjectTypes extends TeamcenterObjectTypes { + + /** + * The Teamcenter type for an Effectivity. + */ + public static final String EFFECTIVITY = "Effectivity"; + /** + * The Teamcenter type for a Product. + */ + public static final String PRODUCT = "Product"; + /** + * The Teamcenter type for a Product Revision. + */ + public static final String PRODUCT_REVISION = PRODUCT + REVISION; + /** + * The Teamcenter type for a Product Revision Master. + */ + public static final String PRODUCT_REVISION_MASTER = PRODUCT + REVISION + MASTER; + /** + * The Teamcenter type for a Generic. + */ + public static final String GENERIC = "Generic"; + /** + * The Teamcenter type for a Generic Revision. + */ + public static final String GENERIC_REVISION = GENERIC + REVISION; + /** + * The Teamcenter type for a SuperModel Revision. + */ + public static final String SUPERMODEL = "Super Model"; + /** + * The Teamcenter type for a SuperModel Revision. + */ + public static final String SUPERMODEL_REVISION = SUPERMODEL + REVISION; + /** + * The Teamcenter type for a Generic Assemb. + */ + public static final String GENERIC_ASSEMB = "Generic Assemb"; + /** + * The Teamcenter type for a Generic Assemb Revision. + */ + public static final String GENERIC_ASSEMB_REVISION = GENERIC_ASSEMB + REVISION; + /** + * The Teamcenter type for a Generic PV Revision Master (for both Generic and Generic Assemb). + */ + public static final String GENERIC_PV_REVISION_MASTER = "Generic PV Revision Master"; + /** + * The Teamcenter type for a RF Generic. + */ + public static final String RF_GENERIC = "RF Generic"; + /** + * The Teamcenter type for a RF Generic Revision. + */ + public static final String RF_GENERIC_REVISION = RF_GENERIC + REVISION; + /** + * The Teamcenter type for a RF Part. + */ + public static final String RF_PART = "RF Part"; + /** + * The Teamcenter type for a RF Part Revision. + */ + public static final String RF_PART_REVISION = RF_PART + REVISION; + /** + * The Teamcenter type for a RF Part Assemb. + */ + public static final String RF_PART_ASSEMB = "RF Part Assemb"; + /** + * The Teamcenter type for a RF Part Assemb Revision. + */ + public static final String RF_PART_ASSEMB_REVISION = RF_PART_ASSEMB + REVISION; + /** + * The Teamcenter type for a RF Admin 1 Revision Master. + */ + public static final String RF_ADMIN_1_REVISION_MASTER = "RF Admin 1 Revision Master"; + /** + * The Teamcenter type for a RF Admin. + */ + public static final String RF_ADMIN = "RF Admin"; + /** + * The Teamcenter type for a RF Master. + */ + public static final String RF_MASTER = "RF Master"; + /** + * The Teamcenter type for a RF Admin Revision. + */ + public static final String RF_ADMIN_REVISION = RF_ADMIN + REVISION; + /** + * The Teamcenter type for a RF Admin Revision Master. + */ + public static final String RF_ADMIN_REVISION_MASTER = RF_ADMIN_REVISION + MASTER; + + /** + * The Teamcenter type for a RF Admin A Revision. + */ + public static final String RF_ADMIN_A_REVISION = "RF Admin A Revision"; + + /** + * The Teamcenter type for a RF Admin AP Revision. + */ + public static final String RF_ADMIN_AP_REVISION = "RF Admin AP Revision"; + /** + * The Teamcenter type for a RF Admin AG Revision. + */ + public static final String RF_ADMIN_AG_REVISION = "RF Admin AG Revision"; + /** + * The Teamcenter type for a Descriptif. + */ + public static final String DESCRIPTIF = "Descriptif"; + /** + * The Teamcenter type for a Descriptif Revision. + */ + public static final String DESCRIPTIF_REVISION = DESCRIPTIF + REVISION; + /** + * The Teamcenter type for a Alternate. + */ + public static final String ALTERNATE = "Alternate"; + /** + * The Teamcenter type for a Alternate Revision. + */ + public static final String ALTERNATE_REVISION = ALTERNATE + REVISION; + /** + * The Teamcenter type for a DET. + */ + public static final String DET = "DET"; + /** + * The Teamcenter type for a DET Revision. + */ + public static final String DET_REVISION = DET + REVISION; + /** + * The Teamcenter type for a Part Aero. + */ + public static final String PART_AERO = "Part Aero"; + /** + * The Teamcenter type for a Part Aero Revision. + */ + public static final String PART_AERO_REVISION = PART_AERO + REVISION; + /** + * The Teamcenter type for a Part No Aero. + */ + public static final String PART_NO_AERO = "Part No Aero"; + /** + * The Teamcenter type for a Part No Aero Revision. + */ + public static final String PART_NO_AERO_REVISION = PART_NO_AERO + REVISION; + /** + * The Teamcenter type for a Part Assemb. + */ + public static final String PART_ASSEMB = "Part Assemb"; + /** + * The Teamcenter type for a Part Assemb Revision. + */ + public static final String PART_ASSEMB_REVISION = PART_ASSEMB + REVISION; + /** + * The Teamcenter type for a Part Assemb Revision Master. + */ + public static final String PART_ASSEMB_REVISION_MASTER = PART_ASSEMB_REVISION + MASTER; + /** + * The Teamcenter type for a Part Mat. + */ + public static final String PART_MAT = "Part Mat"; + /** + * The Teamcenter type for a Part Mat Revision. + */ + public static final String PART_MAT_REVISION = PART_MAT + REVISION; + /** + * The Teamcenter type for a Part Mat Revision Master. + */ + public static final String PART_MAT_REVISION_MASTER = PART_MAT_REVISION + MASTER; + /** + * The Teamcenter type for a Standard. + */ + public static final String STANDARD = "Standard"; + /** + * The Teamcenter type for a Standard Revision. + */ + public static final String STANDARD_REVISION = STANDARD + REVISION; + /** + * The Teamcenter type for a Standard Revision. + */ + public static final String STANDARD_REVISION_MASTER = STANDARD_REVISION + MASTER; + /** + * The Teamcenter type for a UnitRevision. + */ + public static final String UNIT_REVISION = "Unit Revision"; + /** + * The Teamcenter type for the Master Form of a UnitRevision. + */ + public static final String UNIT_REVISION_MASTER = UNIT_REVISION + MASTER; + /** + * The Teamcenter type for a geomertry. + */ + public static final String GEOMETRY = "Geometry"; + /** + * The Teamcenter type for a geomertry REVISION. + */ + public static final String GEOMETRY_REVISION = GEOMETRY + REVISION; + /** + * The Teamcenter type for a geomertry Revision Master. + */ + public static final String GEOMETRY_REVISION_MASTER = GEOMETRY_REVISION + MASTER; + /** + * The Teamcenter type for a changeRequest of type MACE. + */ + public static final String PV4_MACE_REVISION = "PV4_MACERevision"; + /** + * The Teamcenter type for a changeRequest of type DCAD. + */ + public static final String PV4_DCAD_REVISION = "PV4_DCADRevision"; + /** + * The Teamcenter type for a changeRequest of type CAD SCR (with effectivity). + */ + public static final String PV4_CAD_SCR_REVISION = "PV4_CAD_SCRRevision"; + /** + * The Teamcenter type for a changeRequest of type CAD ACR (without effectivity). + */ + public static final String PV4_CAD_ACR_REVISION = "PV4_CAD_ACRRevision"; + /** + * The Teamcenter type for a (Deprecated) changeRequest of type CR Deprec. + */ + public static final String PV4_CR_DEPREC = "PV4_CR_DEPREC"; + /** + * The Teamcenter type for a CN Deprecié Revision. + */ + public static final String CN_DEPRECIE_REVISION = "CN Déprécié Revision"; + /** + * The Teamcenter type for a CR Deprecié Revision. + */ + public static final String CR_DEPRECIE_REVISION = "CR Déprécié Revision"; + /** + * The Teamcenter type for a PV4_CN_DEPRECRevision. + */ + public static final String PV4_CN_DEPREC_REVISION = "PV4_CN_DEPRECRevision"; // No space! + /** + * The Teamcenter type for a PV4_CR_DEPRECRevision. + */ + public static final String PV4_CR_DEPREC_REVISION = "PV4_CR_DEPRECRevision"; // No space! + /** + * The Teamcenter type for a Revision EngChange. + */ + public static final String REVISION_ENG_CHANGE = "Revision EngChange"; + /** + * The Teamcenter type for a FPP Revision. + */ + public static final String FPP_REVISION = "PV4_FPPRevision"; + /** + * The Teamcenter Father type of all Documents. + */ + public static final String DOC_PV_REVISION = "Doc PV Revision"; + /** + * The Teamcenter type for a DocTechnic. + */ + public static final String DOC_TECHNIC = "DocTechnic"; + /** + * The Teamcenter type for a DocTechnic Revision. + */ + public static final String DOC_TECHNIC_REVISION = "DocTechnic Revision"; + /** + * The Teamcenter type for a DocTechnic Revision Master. + */ + public static final String DOC_TECHNIC_REVISION_MASTER = DOC_TECHNIC_REVISION + MASTER; + /** + * The Teamcenter type for a Geometry. + */ + public static final String DOC_GEOMETRY = "Geometry"; + /** + * The Teamcenter type for a Geometry Revision. + */ + public static final String DOC_GEOMETRY_REVISION = "Geometry Revision"; + /** + * The Teamcenter type for a DocDrawing. + */ + public static final String DOC_DRAWING = "DocDrawing"; + /** + * The Teamcenter type for a DocDrawing Revision. + */ + public static final String DOC_DRAWING_REVISION = "DocDrawing Revision"; + /** + * The Teamcenter type for a DocDrawing Revision Master. + */ + public static final String DOC_DRAWING_REVISION_MASTER = "DocDrawing Revision Master"; + /** + * The Teamcenter type for a doc PV Revision Master. + */ + public static final String DOC_PV_REVISION_MASTER = "Doc PV Revision Master"; + /** + * The Teamcenter type for a DocNorm. + */ + public static final String DOC_NORM = "DocNorm"; + /** + * The Teamcenter type for a DocNorm Revision. + */ + public static final String DOC_NORM_REVISION = DOC_NORM + REVISION; + /** + * The Teamcenter type for a DocNorm Master. + */ + public static final String DOC_NORM_MASTER = DOC_NORM + MASTER; + /** + * The Teamcenter type for a DocNorm Master. + */ + public static final String DOC_NORM_REVISION_MASTER = DOC_NORM_REVISION + MASTER; + /** + * The Teamcenter type for a DocDrawing Revision Master. + */ + public static final String DOC_NORM_STANDARD = "DocNormStandard"; + /** + * The Teamcenter type for a DocDrawing Revision Master. + */ + public static final String DOC_NORM_STANDARD_REVISION = DOC_NORM_STANDARD + REVISION; + /** + * The Teamcenter type for an Approbation SO. + */ + public static final String APPROBATION_SO = "Approbation SO"; + /** + * The Teamcenter type IMAN Relation: REACH Documents. + */ + public static final String FOLDER_PV_REACH_DOCS = "_PV_reach_docs"; + /** + * The Teamcenter type IMAN Relation: ITAR Documents. + */ + public static final String FOLDER_PV_ITAR_DOCS = "_PV_itar_docs"; + /** + * The Teamcenter type IMAN Relation: Definition Documents. + */ + public static final String FOLDER_PV_DEFINITION_DOCS = "_PV_definition_docs"; + /** + * The Teamcenter type IMAN Relation: Reference Documents. + */ + public static final String FOLDER_REFERENCED_DOCS = "_PV_reference_docs"; + public static final Pattern PART_REVISION_PATTERN = Pattern.compile("^((" + Joiner.on(")|(").join(PART_AERO_REVISION, PART_ASSEMB_REVISION, + PART_NO_AERO_REVISION, ALTERNATE_REVISION, DET_REVISION, PART_MAT_REVISION, STANDARD_REVISION) + "))$"); + public static final Pattern ALT_OR_DET_PATTERN = Pattern.compile("^((" + ALTERNATE_REVISION + ")|(" + DET_REVISION + "))$"); + public static final Pattern PART_PATTERN = Pattern.compile("^((" + Joiner.on(")|(").join(PART_AERO, PART_ASSEMB, + PART_NO_AERO, ALTERNATE, DET, PART_MAT, STANDARD) + "))$"); + public static final Pattern GENERIC_PATTERN = Pattern.compile("^((" + Joiner.on(")|(").join(GENERIC_REVISION, + GENERIC_ASSEMB_REVISION) + "))$"); + public static final Pattern SUPERMODEL_PATTERN = Pattern.compile("^((" + Joiner.on(")|(").join(SUPERMODEL, + SUPERMODEL_REVISION) + "))$"); + public static final Pattern PRODUCT_REV_PATTERN = Pattern.compile("^((" + PRODUCT_REVISION + "))$"); + public static final Pattern RF_REV_PATTERN = Pattern.compile("^((" + Joiner.on(")|(").join(RF_PART_ASSEMB_REVISION, + RF_PART_REVISION) + "))$"); + + private SnecmaObjectTypes() { + super(); + // Move along, nothing to see + } + + public static boolean isAltOrDet(final String objectType) { + return isAlt(objectType) || isDet(objectType); + } + + public static boolean isDet(final String objectType) { + return DET_REVISION.equals(objectType); + } + + public static boolean isAlt(final String objectType) { + return ALTERNATE_REVISION.equals(objectType); + } + + /** + * Returns true if the provided object type String matches a Part Revision.
    + * Any of the following will be a match: + *
      + *
    • Part Aero Revision
    • + *
    • Part No Aero Revision
    • + *
    • Part Assemb Revision
    • + *
    • Part Mat Revision
    • + *
    • Alternate Revision
    • + *
    • Standard Revision
    • + *
    • DET Revision
    • + *
    + * + * @param objectType the String describing the object type to be tested + * @return true if the object type matches a Part, false otherwise + */ + public static boolean isPartRevision(final String objectType) { + return PART_REVISION_PATTERN.matcher(objectType).matches(); + } + + /** + * Returns true if the provided object type String matches a Part.
    + * Any of the following will be a match: + *
      + *
    • Part Aero
    • + *
    • Part No Aero
    • + *
    • Part Assemb
    • + *
    • Part Mat
    • + *
    • Alternate
    • + *
    • Standard
    • + *
    • DET
    • + *
    + * + * @param objectType the String describing the object type to be tested + * @return true if the object type matches a Part, false otherwise + */ + public static boolean isPart(final String objectType) { + return PART_PATTERN.matcher(objectType).matches(); + } + + /** + * Returns true if the provided object type String matches a Generic.
    + * Any of the following will be a match: + *
      + *
    • Generic Revision
    • + *
    • Generic Assemb Revision
    • + *
    + * + * @param objectType the String describing the object type to be tested + * @return true if the object type matches a Generic, false otherwise + */ + public static boolean isGenericRevision(final String objectType) { + return GENERIC_PATTERN.matcher(objectType).matches(); + } + + /** + * Returns true if the provided object type String matches a SuperModel.
    + * Any of the following will be a match: + *
      + *
    • SuperModel Revision
    • + *
    + * + * @param objectType the String describing the object type to be tested + * @return true if the object type matches a Generic, false otherwise + */ + public static boolean isSuperModelRevision(final String objectType) { + return SUPERMODEL_PATTERN.matcher(objectType).matches(); + } + + /** + * Returns true if the provided object type String matches a Product.
    + * Any of the following will be a match: + *
      + *
    • Product Revision
    • + *
    + * + * @param objectType the String describing the object type to be tested + * @return true if the object type matches a Product Revision, false otherwise + */ + public static boolean isProductRevision(final String objectType) { + return PRODUCT_REV_PATTERN.matcher(objectType).matches(); + } + + /** + * Returns true if the provided object type String matches a Product.
    + * Any of the following will be a match: + *
      + *
    • Product Revision
    • + *
    + * + * @param objectType the String describing the object type to be tested + * @return true if the object type matches a Product Revision, false otherwise + */ + public static boolean isRFRevision(final String objectType) { + return RF_REV_PATTERN.matcher(objectType).matches(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/policies/PolicyLocation.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/policies/PolicyLocation.java new file mode 100644 index 0000000..c88dac8 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/policies/PolicyLocation.java @@ -0,0 +1,53 @@ +package com.capgemini.framework.teamcenter.policies; + +import lombok.Getter; + +/** + * Simple storage class to represent a policy.
    + * Contains: + *
      + *
    • A policy IDENTIFIER (to tell Teamcenter which file to load)
    • + *
    • A file PATH to a policy file for the xmlDomParser
    • + *
    + */ +public final class PolicyLocation { + + /** The identifier of the policy as it exists on the TC servers. */ + @Getter + private final String identifier; + /** The file path to the policy within the "src/main/resources" folder. */ + @Getter + private final String location; + + /** + * Makes a policyLocation object. + * + * @param identifier the Id of the policy as it exists on the TC servers + * @param location the file path to the policy within the "src/main/resources" folder + * @return the PolicyLocation created. + */ + public static PolicyLocation make(final String identifier, final String location) { + return new PolicyLocation(identifier, location); + } + + private PolicyLocation(final String identifier, final String location) { + this.identifier = identifier == null ? "" : identifier; + this.location = location == null ? "" : location; + } + + @Override + public boolean equals(final Object obj) { + if (obj == null || getClass() != obj.getClass()) { + return false; + } + PolicyLocation other = (PolicyLocation) obj; + return identifier.equals(other.identifier) && location.equals(other.location); + } + + @Override + public int hashCode() { + return identifier.hashCode() ^ location.hashCode(); + + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/queries/saved/AbstractReplicatedQuery.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/queries/saved/AbstractReplicatedQuery.java new file mode 100644 index 0000000..327b5e7 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/queries/saved/AbstractReplicatedQuery.java @@ -0,0 +1,157 @@ +package com.capgemini.framework.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; + +/** + * This class is able to look for some objects in Teamcenter using replicated queries with custom name that CANNOT be translated by Teamcenter before evaluation. + * + * @param the expected type of the Object: either {@link Item} or {@link ItemRevision} + * @param The type of the actual daughter class. Provided to chain requests. + */ +@Slf4j +public abstract class AbstractReplicatedQuery> + extends AbstractSavedQuery { + + // Reporting prefix convention + /** + * Common prefix for all columns used by replicated queries for reports. + **/ + protected static final String REPCOL_PREFIX = "report_"; + /** + * Keyword for query parameter: Item ID. + */ + protected static final String PARAM_ITEM_ID = REPCOL_PREFIX + "item_id"; + + // Parameter name suffixes + /** + * Keyword for query parameter: object name. + */ + protected static final String PARAM_OBJECT_NAME = REPCOL_PREFIX + "Name"; + /** + * Keyword for query parameter: Product type name. + */ + protected static final String PARAM_NOM_TYPE_PRODUIT = REPCOL_PREFIX + "pv_nom_type_produit"; + /** + * Common prefix for all replicated queries used by reports. + **/ + private static final String REPQUERY_PREFIX = "__Report_"; + /** + * Keyword for query parameter: Revision. + */ + private static final String PARAM_ITEM_REVISION_ID = REPCOL_PREFIX + "Revision"; + /** + * Keyword for query parameter: object ID. + */ + private static final String PARAM_END_ITEM_ID = REPCOL_PREFIX + "end_item_id"; + /** + * Keyword for query parameter: Effectivity Unit of introduction. + */ + private static final String PARAM_EFFECTIVITY_UNITS_INTRO = REPCOL_PREFIX + "effectivity_units_intro"; + /** + * Keyword for query parameter: Creation Date before. + */ + private static final String PARAM_DATE_AVANT = REPCOL_PREFIX + "cree_avant"; + /** + * Keyword for query parameter: Creation Date after. + */ + private static final String PARAM_DATE_APRES = REPCOL_PREFIX + "cree_apres"; + + protected AbstractReplicatedQuery(final TcSession session, final String queryNameSuffix, final int maxQueries, final int paging) { + super(session, REPQUERY_PREFIX + queryNameSuffix, maxQueries, paging); + } + + protected AbstractReplicatedQuery(final TcSession session, final String queryNameSuffix) { + super(session, REPQUERY_PREFIX + queryNameSuffix); + } + + @Override + public QUERY searchID(final String itemID) { + return this.addParam(PARAM_ITEM_ID, itemID); + } + + @Override + public QUERY searchRevision(final String revision) { + return this.addParam(PARAM_ITEM_REVISION_ID, revision); + } + + @Override + public QUERY searchName(final String itemName) { + return this.addParam(PARAM_OBJECT_NAME, itemName); + } + + /** + * Search all the possible objects within limitation of number of retrieved elements (no return limit). + * + * @return this QUERY, updated to return the list of all the OBJECT elements + */ + public QUERY searchAllObjects() { + this.searchID("*"); + this.changeMaxNumberValues(-1); + return selfCast(); + } + + /** + * Specify an end item Identifier. The returned objects will be below this end item. + * + * @param endItemID the end item identifier (a {@link String}) + * @return the same query + */ + public AbstractReplicatedQuery addEndItemID(final String endItemID) { + parameters.put(PARAM_END_ITEM_ID, endItemID); + return this; + } + + /** + * Specify an Unit of introduction. + * + * @param effectivityUnit the unit (a {@link String}) + * @return the same query + */ + public AbstractReplicatedQuery addEffectivityUnitIntro(final String effectivityUnit) { + parameters.put(PARAM_EFFECTIVITY_UNITS_INTRO, effectivityUnit); + return this; + } + + /** + * Specify a before date.
    + * The objects should be create BEFORE this date. + * + * @param date the date (a {@link String}) + * @return the same query + */ + public AbstractReplicatedQuery addBeforeDate(final String date) { + parameters.put(PARAM_DATE_AVANT, date); + return this; + } + + /** + * Specify an after date.
    + * The objects should be create AFTER this date. + * + * @param date the date (a {@link String}) + * @return the same query + */ + public AbstractReplicatedQuery addAfterDate(final String date) { + parameters.put(PARAM_DATE_APRES, date); + return this; + } + + @Override + public QUERY addParam(final String aParamName, final String aParamValue) { + // Check if current query is specific for reports + // For these queries, all columns should begin by the "report_" prefix + if (!savedQueryName.startsWith(REPQUERY_PREFIX) || !aParamName.startsWith(REPCOL_PREFIX)) { + log.error("The current parameter is not compliant with report queries structure: " + aParamName); + } else { + parameters.put(aParamName, aParamValue); + } + return selfCast(); + } + + protected abstract QUERY selfCast(); + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/queries/saved/AbstractSavedQuery.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/queries/saved/AbstractSavedQuery.java new file mode 100644 index 0000000..fa61070 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/queries/saved/AbstractSavedQuery.java @@ -0,0 +1,249 @@ +package com.capgemini.framework.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.ServiceDataHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.QueryDoesNotExist; +import com.teamcenter.schemas.soa._2006_03.exceptions.ServiceException; +import com.teamcenter.services.strong.query.SavedQueryService; +import com.teamcenter.services.strong.query._2006_03.SavedQuery.GetSavedQueriesResponse; +import com.teamcenter.services.strong.query._2006_03.SavedQuery.SavedQueryObject; +import com.teamcenter.services.strong.query._2007_09.SavedQuery.QueryResults; +import com.teamcenter.services.strong.query._2007_09.SavedQuery.SavedQueriesResponse; +import com.teamcenter.services.strong.query._2008_06.SavedQuery.QueryInput; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.ImanQuery; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; +import java.util.Map.Entry; + +/** + * Setup Teamcenter Search objects, using names, IdDs atc. as parameters.
    + * Additional search parameters are available. Uses Teamcenter SavedQueries. + * + * @param The type of TC objets request (generally {@link Item} or {@link ItemRevision}). Must be a sub-type of {@link ModelObject}. + * @param The type of the actual daughter class. Provided to chain requests. + */ +public abstract class AbstractSavedQuery> { + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSavedQuery.class); + + private static final int DEFAULT_QUERY_RESULT_PAGING = 1000; + private static final int DEFAULT_MAX_QUERY_RESULTS = -1; // NO limit! + private static final String UNABLE_TO_FIND_THE_ITEM = "Unable to find the Item: "; + protected final Map parameters; + protected final TcSession session; + final String savedQueryName; + private final SavedQueryService savedQueryService; + private final int paging; + /** + * Maximum number of results for this query. + */ + private int maxQueries; + + /** + * Basic constructor. Caps the number of results. + * + * @param session Required to setup the search services. + * @param savedQueryName the name of the request to obtain from Tc. + * @param maxQueries the cap on maximum number of results + * @param paging stepping through the result list + */ + protected AbstractSavedQuery(final TcSession session, final String savedQueryName, final int maxQueries, final int paging) { + this.session = session; + this.savedQueryService = session.getSavedQueryService(); + this.parameters = new HashMap<>(); + this.savedQueryName = savedQueryName; + this.maxQueries = maxQueries; + this.paging = paging; + } + + /** + * Basic constructor. + * + * @param session Required to setup the search services. + * @param savedQueryName the name of the request to obtain from Tc. + */ + protected AbstractSavedQuery(final TcSession session, final String savedQueryName) { + this.session = session; + this.savedQueryService = session.getSavedQueryService(); + this.parameters = new HashMap<>(); + this.savedQueryName = savedQueryName; + this.maxQueries = DEFAULT_MAX_QUERY_RESULTS; + this.paging = DEFAULT_QUERY_RESULT_PAGING; + } + + /** + * Adds some search parameter (Revision, unit, date, owner...). + * + * @param aParamName Le type de parametre a utiliser + * @param aParamValue La valeur que le parametre impose doit respecter. + * @return This same request, to chain the requests + */ + protected abstract QUERY addParam(final String aParamName, final String aParamValue); + + /** + * Request that the objects match the specified Identifier. + * + * @param itemID The requested identifier (ex: "ND0000") + * @return This same request, to chain the requests. + */ + public abstract QUERY searchID(final String itemID); + + /** + * Request that the objects match the specified revision. + * + * @param revisionID the requested revision. (ex: "B") + * @return This same request, to chain the requests. + */ + public abstract QUERY searchRevision(final String revisionID); + + /** + * Request that the objects match both the specified Identifier and revision. + * + * @param itemID the requested identifier. (ex: "ND0000") + * @param revisionID the requested revision. (ex: "B") + * @return This same request, to chain the requests. + */ + public QUERY searchIDAndRevision(final String itemID, final String revisionID) { + return this.searchID(itemID).searchRevision(revisionID); + } + + /** + * Request that the objects match the specified object name. + * + * @param itemName the requested object name. (ex: "GE90 M10 MOTEUR ASSEMBLE") + * @return This same request, to chain the requests. + */ + public abstract QUERY searchName(final String itemName); + + /** + * Impose a maximum number of returned values. + * + * @param maxValues the maximum number of results + */ + public void changeMaxNumberValues(final int maxValues) { + maxQueries = maxValues; + } + + /** + * Returns the result of the query. + * + * @return the matching element. + */ + public OBJ find() throws KurtException { + List list = findAll(); + if (!list.isEmpty()) { + OBJ obj = list.get(0); + if (obj != null) { + return obj; + } + } + throw new KurtException(UNABLE_TO_FIND_THE_ITEM); + } + + /** + * Returns the result of the query. + * + * @return a list containing all matching elements. This list may not be {@code null}, but it may be empty. + */ + public List findAll() { + ImanQuery query; + // Get the service stub. + try { + query = getSavedQuery(); + } catch (QueryDoesNotExist e) { + LOGGER.error("Query does not exist", e); + return new ArrayList<>(); + } catch (ServiceException e) { + LOGGER.error("Unable to contact the servers to perform the query", e); + return new ArrayList<>(); + } + List foundObjs; + if (query == null) { + LOGGER.warn("No query named \"{}\" were found.", savedQueryName); + foundObjs = new ArrayList<>(); + } else { + QueryInput[] savedQueryInput = setQueryParameters(query); + + // ***************************** + // Execute the service operation + // ***************************** + SavedQueriesResponse savedQueryResult = savedQueryService.executeSavedQueries(savedQueryInput); + if (ServiceDataHelper.hasErrors(savedQueryResult.serviceData)) { + ServiceDataHelper.displayErrors(savedQueryResult.serviceData); + LOGGER.warn("The following query has failed: {} with arguments:\n{}", savedQueryName, parameters.toString()); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Accepted properties: {}", Arrays.toString(query.getPropertyNames())); + LOGGER.debug("Query clauses: {}", Arrays.toString(query.get_query_clauses())); + } + } + + QueryResults found = savedQueryResult.arrayOfResults[0]; + + foundObjs = parseResults(found); + } + return foundObjs; + } + + private List parseResults(final QueryResults found) { + List foundObjs = new ArrayList<>(); + LOGGER.debug("Loading {} UIDs", found.objectUIDS.length); + + for (int pageStart = 0; pageStart < found.objectUIDS.length; pageStart = pageStart + paging) { + int pageSize = (pageStart + paging < found.objectUIDS.length) ? paging : found.objectUIDS.length - pageStart; + String[] uidsOnPage = new String[pageSize]; + System.arraycopy(found.objectUIDS, pageStart, uidsOnPage, 0, pageSize); + if (LOGGER.isTraceEnabled()) { + int pageEnd = pageStart + pageSize; + LOGGER.trace("-Loading UID page [{}-{}[\t: {}", pageStart, pageEnd, Arrays.toString(uidsOnPage)); + } + foundObjs.addAll(session.loadObjects(uidsOnPage)); + } + return foundObjs; + } + + /** + * Obtain the TC Query Object. + */ + private ImanQuery getSavedQuery() throws QueryDoesNotExist, ServiceException { + GetSavedQueriesResponse savedQueries; + savedQueries = savedQueryService.getSavedQueries(); + if (ServiceDataHelper.hasErrors(savedQueries.serviceData)) { + ServiceDataHelper.displayErrors(savedQueries.serviceData); + } + if (savedQueries.queries.length == 0) { + throw new QueryDoesNotExist("There are no saved queries in the system."); + } + for (SavedQueryObject query : savedQueries.queries) { + if (savedQueryName.equals(query.name)) { + return query.query; + } + } + throw new QueryDoesNotExist("No saved queries found with name \"" + savedQueryName + "\""); + } + + private QueryInput[] setQueryParameters(final ImanQuery query) { + QueryInput[] savedQueryInput = new QueryInput[1]; + savedQueryInput[0] = new QueryInput(); + savedQueryInput[0].query = query; + savedQueryInput[0].maxNumToReturn = maxQueries; // -1 for ALL + savedQueryInput[0].limitList = new ModelObject[0]; + int nbParam = parameters.size(); + String[] paramTypes = new String[nbParam]; + String[] paramValues = new String[nbParam]; + int num = 0; + for (Entry param : parameters.entrySet()) { + paramTypes[num] = param.getKey(); + paramValues[num] = param.getValue(); + num++; + } + savedQueryInput[0].entries = paramTypes; + savedQueryInput[0].values = paramValues; + return savedQueryInput; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/queries/saved/modelobject/AbstractModelObjectQuery.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/queries/saved/modelobject/AbstractModelObjectQuery.java new file mode 100644 index 0000000..1ed89f6 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/queries/saved/modelobject/AbstractModelObjectQuery.java @@ -0,0 +1,80 @@ +package com.capgemini.framework.teamcenter.queries.saved.modelobject; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +/** + * Looks for a ModelObject in Teamcenter. + * + * @param the type of the actual daughter class. Provided to chain requests. + * @param the expected type of the Object: either {@link Item} or {@link ItemRevision} + */ +public abstract class AbstractModelObjectQuery> + extends AbstractReplicatedQuery { + private static final String PARAM_OBJECT_TYPE = "Type"; + private static final String VALUE_OBJECT_TYPE_PRODUCT = "Product"; + private static final String VALUE_OBJECT_TYPE_GENERIC = "Generic"; + private static final String VALUE_OBJECT_TYPE_GENERIC_ASSEMB = "Generic Assemb"; + + protected AbstractModelObjectQuery(final TcSession session, final String queryNameSuffix) { + super(session, queryNameSuffix); + } + + /** + * Demande a cette requete de rechercher un objet d'un certain type. + * + * @param requestedType the constraint on object type + * @return Cette meme requete, pour chainer les parametres. + */ + public QUERY searchType(final String requestedType) { + return this.addParam(PARAM_OBJECT_TYPE, requestedType); + } + + /** + * Demande a cette requete de rechercher un Generic. + * + * @return Cette meme requete, pour chainer les parametres. + */ + public QUERY searchGeneric() { + return this.addParam(PARAM_OBJECT_TYPE, VALUE_OBJECT_TYPE_GENERIC); + } + + /** + * Demande a cette requete de rechercher un Generic Assemb. + * + * @return Cette meme requete, pour chainer les parametres. + */ + public QUERY searchGenericAssemb() { + return this.addParam(PARAM_OBJECT_TYPE, VALUE_OBJECT_TYPE_GENERIC_ASSEMB); + } + + /** + * Demande a cette requete de rechercher un Product. + * + * @return Cette meme requete, pour chainer les parametres. + */ + public QUERY searchProduct() { + return this.addParam(PARAM_OBJECT_TYPE, VALUE_OBJECT_TYPE_PRODUCT); + } + + /** + * Demande a cette requete de rechercher le nom d'objet fourni.. + * + * @param itemName Le nom a rechercher. (exemple: "M88 MOTEUR ASSEMBLE") + * @return Cette meme requete, pour chainer les parametres. + */ + @Override + public QUERY searchName(final String itemName) { + return this.addParam(PARAM_OBJECT_NAME, itemName); + } + + @Override + public QUERY addParam(final String aParamName, final String aParamValue) { + super.parameters.put(aParamName, aParamValue); + return selfCast(); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/queries/saved/modelobject/IMANRelationQuery.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/queries/saved/modelobject/IMANRelationQuery.java new file mode 100644 index 0000000..0d921fc --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/queries/saved/modelobject/IMANRelationQuery.java @@ -0,0 +1,69 @@ +package com.capgemini.framework.teamcenter.queries.saved.modelobject; + +import com.capgemini.framework.teamcenter.TeamcenterObjectTypes; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.teamcenter.soa.client.model.strong.ImanRelation; + +import java.util.List; + +/** + * A Tc Query that can be used to search exisitng relations between a primary and a secondary object. + */ +public class IMANRelationQuery { + private final TcSession session; + + /** + * Creates an instance that is able to perform queries. + * + * @param session an active session + */ + public IMANRelationQuery(final TcSession session) { + this.session = session; + } + + /** + * Returns all {@link ImanRelation} referenced datasets (in a {@link List}) of an item. + * + * @param itemId the Item's ID + * @param datasetName the dataset name + * @return a List of ImanRelation + */ + public List find(final String itemId, final String datasetName) { + TheInternalRelationQuery query = new TheInternalRelationQuery(session); + return query.find(itemId, datasetName); + } + + private static final class TheInternalRelationQuery extends AbstractReplicatedQuery { + private static final String QUERY_SUFFIX = "Relationship"; + + private static final String KEY_DATASET_NAME = REPCOL_PREFIX + "dataset_name"; + private static final String KEY_ITEM_ID = REPCOL_PREFIX + "item_id"; + private static final String KEY_RELATIONSHIP = REPCOL_PREFIX + "relationship"; + + protected TheInternalRelationQuery(final TcSession session) { + super(session, QUERY_SUFFIX); + } + + /** + * Finds an {@link ImanRelation} between an item and a dataset. + * + * @param itemId the ID of the Item + * @param datasetName the name of the dataset + * @return a {@link List} of all the {@link ImanRelation}s found + */ + public List find(final String itemId, final String datasetName) { + addParam(KEY_RELATIONSHIP, TeamcenterObjectTypes.IMAN_REFERENCE); + addParam(KEY_ITEM_ID, itemId); + addParam(KEY_DATASET_NAME, datasetName); + return this.findAll(); + } + + @Override + protected TheInternalRelationQuery selfCast() { + return this; + } + + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/queries/saved/modelobject/ItemQuery.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/queries/saved/modelobject/ItemQuery.java new file mode 100644 index 0000000..c61a6ce --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/queries/saved/modelobject/ItemQuery.java @@ -0,0 +1,25 @@ +package com.capgemini.framework.teamcenter.queries.saved.modelobject; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.teamcenter.soa.client.model.strong.Item; + +/** Searches an Item. */ +public class ItemQuery extends AbstractModelObjectQuery { + + private static final String QUERY_NAME_SUFFIX = "Item"; + + /** + * Creates a request for Tc to return an Item. + * + * @param session an active session + */ + public ItemQuery(final TcSession session) { + super(session, QUERY_NAME_SUFFIX); + } + + @Override + protected ItemQuery selfCast() { + return this; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/queries/saved/modelobject/ItemRevisionQuery.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/queries/saved/modelobject/ItemRevisionQuery.java new file mode 100644 index 0000000..00df621 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/queries/saved/modelobject/ItemRevisionQuery.java @@ -0,0 +1,26 @@ +package com.capgemini.framework.teamcenter.queries.saved.modelobject; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +/** Searches an ItemRevision. */ +public class ItemRevisionQuery extends AbstractModelObjectQuery { + + private static final String QUERY_NAME_SUFFIX = "ItemRevision"; + + /** + * Creates a request for Tc to return an ItemRevision. + * + * @param session an active session + */ + public ItemRevisionQuery(final TcSession session) { + super(session, QUERY_NAME_SUFFIX); + } + + + @Override + protected ItemRevisionQuery selfCast() { + return this; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/filtering/AllFilter.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/filtering/AllFilter.java new file mode 100644 index 0000000..8584be3 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/filtering/AllFilter.java @@ -0,0 +1,33 @@ +package com.capgemini.framework.teamcenter.resolution.filtering; + +/** + * Filter that accepts everything. obtain an instance through {@link AllFilter#getInstance()}. + */ +public final class AllFilter implements ITcTypeFilter { + + private static final AllFilter INSTANCE = new AllFilter(); + + private AllFilter() { + // Just making it singleton + } + + /** + * Returns the (unique) instance of this filter, which accepts everything. + * + * @return the instance of {@link AllFilter}. + */ + public static AllFilter getInstance() { + return INSTANCE; + } + + @Override + public boolean isExcluded(final String type) { + return false; + } + + @Override + public boolean isIncluded(final String type) { + return true; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/filtering/AndFilter.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/filtering/AndFilter.java new file mode 100644 index 0000000..490883b --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/filtering/AndFilter.java @@ -0,0 +1,22 @@ +package com.capgemini.framework.teamcenter.resolution.filtering; + +import lombok.AllArgsConstructor; + +/** {@link ITcTypeFilter} class that combines two sub-{@link ITcTypeFilter} into a logical AND. */ +@AllArgsConstructor +public class AndFilter implements ITcTypeFilter { + + private final ITcTypeFilter filter1; + private final ITcTypeFilter filter2; + + @Override + public boolean isExcluded(final String type) { + return filter1.isExcluded(type) || filter2.isExcluded(type); + } + + @Override + public boolean isIncluded(final String type) { + return filter1.isIncluded(type) && filter2.isIncluded(type); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/filtering/ITcTypeFilter.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/filtering/ITcTypeFilter.java new file mode 100644 index 0000000..e82ad3d --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/filtering/ITcTypeFilter.java @@ -0,0 +1,22 @@ +package com.capgemini.framework.teamcenter.resolution.filtering; + +/** Interface for a filter that act on an item's type. */ +public interface ITcTypeFilter { + + /** + * Returns true if the type provided should be excluded by this filter. + * + * @param type the type to assess + * @return true if the type is to be excluded, false otherwise. + */ + boolean isExcluded(final String type); + + /** + * Returns true if the type provided should be included by this filter. + * + * @param type the type to assess + * @return true if the type is to be included, false if it is to be excluded. + */ + boolean isIncluded(final String type); + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/filtering/OrFilter.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/filtering/OrFilter.java new file mode 100644 index 0000000..a3d34f0 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/filtering/OrFilter.java @@ -0,0 +1,21 @@ +package com.capgemini.framework.teamcenter.resolution.filtering; + +import lombok.AllArgsConstructor; + +/** {@link ITcTypeFilter} class that combines two sub-{@link ITcTypeFilter} into a logical OR. */ +@AllArgsConstructor +public class OrFilter implements ITcTypeFilter { + + private final ITcTypeFilter filter1; + private final ITcTypeFilter filter2; + + @Override + public boolean isExcluded(final String type) { + return filter1.isExcluded(type) && filter2.isExcluded(type); + } + + @Override + public boolean isIncluded(final String type) { + return filter1.isIncluded(type) || filter2.isIncluded(type); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/filtering/TcTypeExclusionFilter.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/filtering/TcTypeExclusionFilter.java new file mode 100644 index 0000000..72fda71 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/filtering/TcTypeExclusionFilter.java @@ -0,0 +1,30 @@ +package com.capgemini.framework.teamcenter.resolution.filtering; + +import java.util.Arrays; + +/** Exclude objects according to their type. */ +public class TcTypeExclusionFilter implements ITcTypeFilter { + + private final String[] forbidden; + + /** + * Builds a {@link ITcTypeFilter} that will exclude any object of the provided type. + * + * @param forbidden the object types to be excluded + */ + public TcTypeExclusionFilter(final String... forbidden) { + this.forbidden = forbidden; + Arrays.sort(forbidden); + } + + @Override + public boolean isExcluded(final String type) { + return Arrays.binarySearch(forbidden, type) >= 0; + } + + @Override + public boolean isIncluded(final String type) { + return !isExcluded(type); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/filtering/TcTypeInclusionFilter.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/filtering/TcTypeInclusionFilter.java new file mode 100644 index 0000000..189bbb1 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/filtering/TcTypeInclusionFilter.java @@ -0,0 +1,30 @@ +package com.capgemini.framework.teamcenter.resolution.filtering; + +import java.util.Arrays; + +/** Include objects according to their type. */ +public class TcTypeInclusionFilter implements ITcTypeFilter { + + private final String[] allowedObjects; + + /** + * Builds a {@link ITcTypeFilter} that will ALLOW any object of the provided type. + * + * @param allowedObjects the object types to be included + */ + public TcTypeInclusionFilter(final String... allowedObjects) { + this.allowedObjects = allowedObjects; + Arrays.sort(allowedObjects); + } + + @Override + public boolean isExcluded(final String type) { + return !isIncluded(type); + } + + @Override + public boolean isIncluded(final String type) { + return Arrays.binarySearch(allowedObjects, type) >= 0; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/structureservice/AbstractStructureServiceRaw.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/structureservice/AbstractStructureServiceRaw.java new file mode 100644 index 0000000..174c6a6 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/structureservice/AbstractStructureServiceRaw.java @@ -0,0 +1,29 @@ +package com.capgemini.framework.teamcenter.resolution.structureservice; + +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.resolution.filtering.ITcTypeFilter; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.BOMLine; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +interface StructureServiceRaw { + + /** + * Run a resolution from a configuration.
    + * The top {@link ModelObject} should be an {@link Item} or an {@link ItemRevision}.
    + *

    + * There may be several outcomes, depending on the Resolution Mode: + *

      + *
    • SINGLE:In this mode, the explosion is performed throughout only 1 link.
      + * It returns a {@link BOMLine} containing the top item (the one provided for the explosion)
    • + *
    • MONO:In this mode, the explosion is performed throughout 3 consecutive links, usually as part of the Receptor-Repere-Component relationship
      + * It returns a {@link BOMLine} containing the top item (the one provided for the explosion)
    • + *
    • MULTI:In this mode, the explosion is performed throughout all the links, and all the children and grand-children are revealed.
      + * It returns a {@link BOMLine} containing the top item (the one provided for the explosion)
    • + *
    + */ + BOMLineHolder resolve(final BOMLine topBomLine, final ITcTypeFilter filter) throws EmptyNomenclatureException; +} + diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/structureservice/MultiStructureServiceCallerRaw.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/structureservice/MultiStructureServiceCallerRaw.java new file mode 100644 index 0000000..e40e67a --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/structureservice/MultiStructureServiceCallerRaw.java @@ -0,0 +1,85 @@ +package com.capgemini.framework.teamcenter.resolution.structureservice; + +import com.capgemini.framework.teamcenter.ServiceDataHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.resolution.filtering.ITcTypeFilter; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.teamcenter.services.strong.cad._2008_06.StructureManagement.*; +import com.teamcenter.soa.client.model.strong.BOMLine; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * Helper dedicated to multi levels resolution of configurations. + **/ +public class MultiStructureServiceCallerRaw implements StructureServiceRaw { + private static final Logger LOGGER = LoggerFactory.getLogger(MultiStructureServiceCallerRaw.class); + private static final String NO_FILTER = "None2"; + + private final TcSession session; + + public MultiStructureServiceCallerRaw(final TcSession session) { + this.session = session; + } + + @Override + public BOMLineHolder resolve(final BOMLine topBomLine, final ITcTypeFilter filter) throws EmptyNomenclatureException { + LOGGER.debug("Top line: {}", topBomLine.getUid()); + LOGGER.debug("Start Multi-level BOMLine expansion"); + ExpandPSAllLevelsResponse2 response = session.getStructureManagementService().expandPSAllLevels(expandInfo(topBomLine), expandPref()); + LOGGER.debug("End expand all levels"); + if (ServiceDataHelper.hasErrors(response.serviceData)) { + ServiceDataHelper.displayErrors(response.serviceData); + } + + Map dataByBomLine = new HashMap<>(); + for (ExpandPSAllLevelsOutput output : response.output) { + BOMLine parentBomLine = output.parent.bomLine; + if (parentBomLine != null && output.parent.objectOfBOMLine != null) { + dataByBomLine.put(parentBomLine, output); + } + } + + return toTreeBom(dataByBomLine, topBomLine, filter); + } + + private ExpandPSAllLevelsInfo expandInfo(BOMLine topBomLine) { + ExpandPSAllLevelsInfo info = new ExpandPSAllLevelsInfo(); + info.parentBomLines = new BOMLine[]{topBomLine}; + info.excludeFilter = NO_FILTER; + return info; + } + + private ExpandPSAllLevelsPref expandPref() { + ExpandPSAllLevelsPref pref = new ExpandPSAllLevelsPref(); + pref.expItemRev = false; + return pref; + } + + private BOMLineHolder toTreeBom(final Map dataByBomLine, final BOMLine parentBomLine, final ITcTypeFilter filter) { + ExpandPSAllLevelsOutput parentOutput = dataByBomLine.get(parentBomLine); + List childs = new ArrayList<>(); + for (ExpandPSData currentChildData : parentOutput.children) { + if (currentChildData.objectOfBOMLine != null && filter.isIncluded(currentChildData.objectOfBOMLine.getTypeObject().getName())) { + if (hasChilds(dataByBomLine, currentChildData)) { + childs.add(toTreeBom(dataByBomLine, currentChildData.bomLine, filter)); + } else { + childs.add(new BOMLineHolder(session, currentChildData.bomLine, (ItemRevision) currentChildData.objectOfBOMLine, new ArrayList())); + } + } + } + return new BOMLineHolder(session, parentOutput.parent.bomLine, (ItemRevision) parentOutput.parent.objectOfBOMLine, childs); + } + + private boolean hasChilds(Map dataByBomLine, ExpandPSData currentChildData) { + return dataByBomLine.get(currentChildData.bomLine) != null; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/structureservice/SingleStructureServiceCallerRaw.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/structureservice/SingleStructureServiceCallerRaw.java new file mode 100644 index 0000000..00f2aba --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/resolution/structureservice/SingleStructureServiceCallerRaw.java @@ -0,0 +1,136 @@ +package com.capgemini.framework.teamcenter.resolution.structureservice; + +import com.capgemini.framework.teamcenter.ServiceDataHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.resolution.filtering.ITcTypeFilter; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.teamcenter.services.strong.cad._2008_06.StructureManagement.*; +import com.teamcenter.soa.client.model.strong.BOMLine; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Helper dedicated to single level resolution of configurations. + **/ +@Slf4j +public class SingleStructureServiceCallerRaw implements StructureServiceRaw { + private static final String NO_FILTER = "None2"; + private static final String ERROR_MSG_NULL_BOM_LINE_PROVIDED = "Unable to resolve from a null BOMLine."; + private static final String ERROR_MSG_NO_RESULT_FOR_EXPLOSION = "No result for explosion"; + private final TcSession session; + + /** + * Constructor for single level resolution. + */ + public SingleStructureServiceCallerRaw(final TcSession session) { + this.session = session; + } + + + /** + * Run a resolution from a {@link BOMLine}.
    + * In this SINGLE mode, the explosion is performed only 1 link.
    + * The entry {@link BOMLine} cannot have a null TC {@link BOMLine}. + */ + @Override + public BOMLineHolder resolve(final BOMLine aTopBom, final ITcTypeFilter filter) + throws EmptyNomenclatureException { + if (aTopBom != null) { + return expandBom(aTopBom, filter); + } else { + throw new EmptyNomenclatureException(ERROR_MSG_NULL_BOM_LINE_PROVIDED); + } + } + + /** + * Expands a {@link BOMLine} object, by exactly one BOM link.
    + */ + private BOMLineHolder expandBom(final BOMLine topObject, final ITcTypeFilter filter) + throws EmptyNomenclatureException { + // Expand one level + List topObjectList = new ArrayList<>(); + topObjectList.add(topObject); + ExpandPSOneLevelOutput[] expand = expandOneLevel(topObjectList); + + // Expecting only one response because only one BOMLine was provided + if (expand == null || expand.length == 0) { + throw new EmptyNomenclatureException(ERROR_MSG_NO_RESULT_FOR_EXPLOSION); + } + ExpandPSOneLevelOutput output = expand[0]; + + // Browse this BOMLine's children + return extractAllChildren(output, filter); + } + + /** + * Expand ONE level of configuration.
    + * + * @param allTopBomLine Top item {@link BOMLine} + * @return a table of raw {@link ExpandPSOneLevelOutput} each containing parent and its children + */ + private ExpandPSOneLevelOutput[] expandOneLevel(final Collection allTopBomLine) { + if (allTopBomLine == null || allTopBomLine.isEmpty()) { + // Early return + return new ExpandPSOneLevelOutput[0]; + } + log.debug("Start expand one level..."); + BOMLine[] bomLines = allTopBomLine.toArray(new BOMLine[allTopBomLine.size()]); + + ExpandPSOneLevelInfo expandInfo = new ExpandPSOneLevelInfo(); + expandInfo.parentBomLines = bomLines; + expandInfo.excludeFilter = NO_FILTER; + + ExpandPSOneLevelPref expandPref = new ExpandPSOneLevelPref(); + expandPref.expItemRev = false; + + ExpandPSOneLevelResponse2 response = session.getStructureManagementService().expandPSOneLevel(expandInfo, expandPref); + ServiceDataHelper.displayErrors(response.serviceData); + log.debug("End expand one level"); + + return response.output; + } + + /** + * Expands all the topObjects provided, using the {@link ITcTypeFilter}. + */ + public final List expandEach(final Collection topObjects, final ITcTypeFilter filter) + throws EmptyNomenclatureException { + if (topObjects.isEmpty()) { + return new ArrayList<>(); + } + // Expand one level + ExpandPSOneLevelOutput[] expand = expandOneLevel(topObjects); + + if (expand == null || expand.length == 0) { + throw new EmptyNomenclatureException(ERROR_MSG_NO_RESULT_FOR_EXPLOSION); + } + + List result = new ArrayList<>(); + // Browse each BOMLine's children + for (ExpandPSOneLevelOutput output : expand) { + result.add(extractAllChildren(output, filter)); + } + return result; + } + + + private BOMLineHolder extractAllChildren(final ExpandPSOneLevelOutput output, final ITcTypeFilter filter) { + List childList = new ArrayList<>(); + for (ExpandPSData currentChildData : output.children) { + BOMLine bomLine = currentChildData.bomLine; + ItemRevision theObject = (ItemRevision) currentChildData.objectOfBOMLine; + if (bomLine == null || theObject == null) { + continue; + } + if (filter.isIncluded(theObject.getTypeObject().getName())) { + childList.add(new BOMLineHolder(session, bomLine, theObject, new ArrayList())); + } + } + return new BOMLineHolder(session, output.parent.bomLine, (ItemRevision) output.parent.objectOfBOMLine, childList); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/framework/teamcenter/statuating/StatusSetter.java b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/statuating/StatusSetter.java new file mode 100644 index 0000000..2b2a63c --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/framework/teamcenter/statuating/StatusSetter.java @@ -0,0 +1,74 @@ +package com.capgemini.framework.teamcenter.statuating; + +import com.capgemini.framework.teamcenter.ServiceDataHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.UnableToCreateStatusException; +import com.teamcenter.schemas.soa._2006_03.exceptions.ServiceException; +import com.teamcenter.services.strong.workflow.WorkflowService; +import com.teamcenter.services.strong.workflow._2007_06.Workflow.ReleaseStatusInput; +import com.teamcenter.services.strong.workflow._2007_06.Workflow.ReleaseStatusOption; +import com.teamcenter.services.strong.workflow._2007_06.Workflow.SetReleaseStatusResponse; +import com.teamcenter.soa.client.model.strong.ReleaseStatus; +import com.teamcenter.soa.client.model.strong.WorkspaceObject; + +import java.util.Arrays; + +/** This class can place a Status on a {@link WorkspaceObject}. */ +public class StatusSetter { + private final TcSession session; + + /** + * Creates a instance that is able to create statuses. + * + * @param session an active teamcenter session. + */ + public StatusSetter(final TcSession session) { + this.session = session; + } + + /** + * Creates a status and places it on a {@link WorkspaceObject}. + * @param target the target {@link WorkspaceObject} + * @param statusName the name of the status + * @return the created Tc {@link ReleaseStatus} + * @throws UnableToCreateStatusException if no Status was created + */ + public ReleaseStatus putStatus(WorkspaceObject target, String statusName) throws UnableToCreateStatusException { + WorkspaceObject[] objects = new WorkspaceObject[] {target}; + ReleaseStatusOption[] options = new ReleaseStatusOption[] {makeReleaseStatusOption(statusName)}; + + // Prepare ReleaseStatusInput + ReleaseStatusInput[] inputArray = new ReleaseStatusInput[] {makeReleaseStatusInput(objects, options)}; + + // Execute + WorkflowService wkfService = session.getWorkflowService(); + SetReleaseStatusResponse response; + try { + response = wkfService.setReleaseStatus(inputArray); + } catch (ServiceException e) { + throw new UnableToCreateStatusException("No status has been created on target object " + target.getUid(), e); + } + if (ServiceDataHelper.hasErrors(response.serviceData)) { + ServiceDataHelper.displayErrors(response.serviceData); + } + if (response.serviceData.sizeOfCreatedObjects() <= 0) { + throw new UnableToCreateStatusException("No status has been created on target object " + target.getUid()); + } + return (ReleaseStatus) response.serviceData.getCreatedObject(0); + } + + private ReleaseStatusInput makeReleaseStatusInput(WorkspaceObject[] objects, ReleaseStatusOption[] options) { + ReleaseStatusInput input = new ReleaseStatusInput(); + input.objects = objects == null ? new WorkspaceObject[0] : Arrays.copyOf(objects, objects.length); + input.operations = options == null ? new ReleaseStatusOption[0] : Arrays.copyOf(options, options.length); + return input; + } + + private ReleaseStatusOption makeReleaseStatusOption(String statusName) { + ReleaseStatusOption option = new ReleaseStatusOption(); + option.existingreleaseStatusTypeName = ""; + option.newReleaseStatusTypeName = statusName; + option.operation = "Append"; // The only supported operation :'( + return option; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/ItemRevisionComparator.java b/teamcenter/src/main/java/com/capgemini/reports/ItemRevisionComparator.java new file mode 100644 index 0000000..533477b --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/ItemRevisionComparator.java @@ -0,0 +1,21 @@ +package com.capgemini.reports; + +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import java.io.Serializable; +import java.util.Comparator; + +/** + * Helper class to compare compares two itemRevision by concatenating their properties item_id, item_revision_id,sequence_id, ex: 002605B1. * + */ +public class ItemRevisionComparator implements Comparator, Serializable { + private static final long serialVersionUID = -1094043465048885249L; + + @Override + public int compare(ItemRevision obj1, ItemRevision obj2) { + String itemRevision1 = obj1.get_item_id() + obj1.get_item_revision_id() + obj1.get_sequence_id(); + String itemRevision2 = obj2.get_item_id() + obj2.get_item_revision_id() + obj2.get_sequence_id(); + return itemRevision1.compareTo(itemRevision2); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/BOMLineHolder.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/BOMLineHolder.java new file mode 100644 index 0000000..25b2ae3 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/BOMLineHolder.java @@ -0,0 +1,422 @@ +package com.capgemini.reports.bomlineholder; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.bomlineholder.processor.IBOMLineHolderProcessor; +import com.capgemini.reports.bomlineholder.visitor.IBOMLineHolderExtractor; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.part.AbstractAltOrDetRevision; +import com.capgemini.reports.teamcenter.ObjectInfoHelper; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.BOMLine; +import com.teamcenter.soa.client.model.strong.Form; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.ArrayList; +import java.util.List; + +/** + * Container for BOM line and their BOM line children.
    + * The BOM line holder also contains the corresponding ModelObject and/or the corresponding ISnecmaObject. + *

    + *

    + * Note:To save memory space, the BOMLineHolder will go through th following life phases:
    + *

      + *
    1. {@link BOMLineHolderState#RAW} mode
      + * The BOMLineHolder only contains raw Teamcenter data, namely: + *
        + *
      • A {@link BOMLine} called {@code BOMLineObject}
      • + *
      • A {@link List} of {@link ModelObject}s containing all {@link Item}s found in an eventual pseudo-folder.
      • + *
      • A {@link List} of children {@link BOMLineHolder}s called {@code bomChilds}, all of which are in the same state ({@link BOMLineHolderState#RAW})
      • + *
      + *

      + *

    2. {@link BOMLineHolderState#PROCESSING} mode
      + * The BOMLineHolder contains both the RAW Teamcenter data, and their {@link ISnecmaObject} representation.
      + * In this state, some processing can be performed to extract data from the TC object and dump it into an ISnecmaObject as appropriate: + *
        + *
      • A {@link BOMLine} called {@code BOMLineObject}
      • + *
      • A {@link List} of {@link ModelObject}s containing all {@link Item}s found in an eventua pseudo-folder.
      • + *
      • A {@link List} of children {@link BOMLineHolder}s called {@code bomChilds}, all of which are in the same state ({@link BOMLineHolderState#PROCESSING})
      • + *
      • A {@link ISnecmaObject} containing a representation of data from the ItemRevision held by the BomLine
      • + *
      + *

      + *

      + *

    3. {@link BOMLineHolderState#FROZEN}
      + * The BOMLineHolder contains no more Teamcenter objects (they are null) but instead contains some strongly-typed {@link ISnecmaObject}s holding all the relevant data: + *
        + *
      • A {@link ISnecmaObject} containing a representation of data from the ItemRevision held by the BomLine
      • + *
      • A {@link List} of children {@link BOMLineHolder}s called {@code bomChilds}, all of which are in the same state ({@link BOMLineHolderState#FROZEN})
      • + *
      + *
    + *

    + *

    + * To findAll into PROCESSING mode, use the {@link BOMLineHolderFactory} + */ +@Slf4j +@EqualsAndHashCode(exclude = {"parentBomLine"}) +public class BOMLineHolder implements IBOMTree, Comparable { + private static final long serialVersionUID = 5317661727930642676L; + + private TcSession session; + /** + * Current line in the BOM. + **/ + private transient BOMLine bomLineObject; + /** + * Item Revision of the current {@link BOMLine}. + */ + private transient ItemRevision itemRevision; + /** + * Wrapper for Model object (set as null by default). + **/ + private ISnecmaObject snecmaObject; + /** + * Map of BOMLine IDs to the children BOM lines for the current BOM line. + **/ + private List bomChilds = new ArrayList<>(); + private IBOMTree parentBomLine; + + /** + * State of the BOMLIneHolder. + */ + @Setter(value = AccessLevel.NONE) + private BOMLineHolderState state = BOMLineHolderState.RAW; + + /** + * Constructor using a simple BOM line.
    + * If you also have the ItemRevision already, use the other constructor: {@link BOMLineHolder#BOMLineHolder(BOMLine, ItemRevision)}. This should ONLY be used for the top BomLine. + * + * @param bomLine the BOMLine represented by this {@link BOMLineHolder} + */ + public BOMLineHolder(final BOMLine bomLine) { + this.bomLineObject = bomLine; + + // Get the TC ModelObject + ModelObject theTopMo = bomLine.get_bl_line_object(); + // Build the embedded SnecmaObject + if (theTopMo != null) { + if (theTopMo instanceof ItemRevision) { + this.itemRevision = (ItemRevision) theTopMo; + return; + } + else { + log.error("No ItemRevision found in the ModelObject"); + } + } + else { + log.debug("BOMlineHolder built from a BomLine which does not have a ModelObjec: BomLine UID=" + bomLine.getUid()); + } + + // If not available, try to use the BomLine's UID (wich may change from one execution to the next + this.itemRevision = null; + } + + /** + * Constructor using a simple BOM line. + * + * @param bomLine the BOMLine represented by this {@link BOMLineHolder} + * @param itemRev the ItemRevision managed by this holder + */ + public BOMLineHolder(final BOMLine bomLine, final ItemRevision itemRev) { + this.bomLineObject = bomLine; + this.itemRevision = itemRev; + } + + + /** + * Constructor building a BOMLineHolder from another BOMLineHolder. Exact same copy, same UID. + * + * @param aBom BOMLineHolder + */ + public BOMLineHolder(final IBOMTree aBom) { + this.bomLineObject = aBom.getBomLineObject(); + this.itemRevision = aBom.getItemRevision(); + this.snecmaObject = aBom.getSnecmaObject(); + this.parentBomLine = aBom.getParentBomLine(); + this.bomChilds = aBom.getBomChilds(); + } + + /** + * Constructor for {@link ItemRevision}s obtained without a {@link BOMLine} like extracted from a pseudo-folder. + **/ + protected BOMLineHolder(final ItemRevision itemRevision) { + this.bomLineObject = null; + this.itemRevision = itemRevision; + } + + public BOMLineHolder(final TcSession session, final BOMLine bomLine, final ItemRevision itemRevision, final List bomChilds) { + this.session = session; + this.bomLineObject = bomLine; + this.itemRevision = itemRevision; + this.bomChilds = bomChilds; + } + + /** + * This methods "freezes" the BOMLineholder by removing all its references to Teamcenter data.
    + * Should be called after it was fully built. + */ + public void freeze() { + this.state = BOMLineHolderState.FROZEN; + } + + @Override + public void process(final IBOMLineHolderProcessor aBOMLineHolderProcessor) { + switch (this.state) { + case RAW: + log.warn("Skipping processing of a RAW BomLineHolder"); + break; + case PROCESSING: + aBOMLineHolderProcessor.process(this); // Perform the unit work + for (BOMLineHolder child : bomChilds) { + child.process(aBOMLineHolderProcessor); // Browse children recursively + } + break; + case FROZEN: + throw new IllegalStateException("Processing a BOMLineHolder which has been FROZEN is not allowed."); + default: + break; + } + } + + @Override + public T accept(final IBOMLineHolderExtractor aBOMLineHolderExtractor) { + if (this.state != BOMLineHolderState.FROZEN) { + throw new IllegalStateException("Visiting a BOMLineHolder which has not been FROZEN is not allowed. Use the BOMLineHolderFactory on it first."); + } + return aBOMLineHolderExtractor.visitTopReceptorBom(this); + } + + @Override + public IBOMTree getParentBomLine() { + return parentBomLine; + } + + @Override + public List getBomChilds() { + return bomChilds; + } + + @Override + public void setParent(final BOMLineHolder aParentBomLine) { + this.parentBomLine = aParentBomLine; + } + + @Override + public BOMLine getBomLineObject() { + return bomLineObject; + } + + /** + * Assign a child BOM line to the current line and create a reference to its parent. A null child will not be added. + */ + @Override + public void addChild(final BOMLineHolder aChildBomLine) { + if (aChildBomLine != null) { + this.bomChilds.add(aChildBomLine); + aChildBomLine.setParent(this); + } + } + + /** + * Return the type of the object carried. + * + * @return a String containing the Type. + */ + @Override + public String getObjectType() { + String type; + switch (state) { + case RAW: + type = getRawType(); + break; + case PROCESSING: + case FROZEN: + type = snecmaObject.getType(); + break; + default: + type = "Unknown State: " + state.toString(); + break; + } + return type; + } + + private String getRawType() { + return itemRevision.getTypeObject().getName(); + } + + /** + * Generate unique key for BOM line using item_id + item_revision_id.
    + * This is used by the child tree map for sorting purpose. + * + * @return Unique key + */ + @Override + public String getKey() { + return getUid(); + } + + @Override + public ISnecmaObject getSnecmaObject() { + return snecmaObject; + } + + /** + * This methods sets the SnecmaObject of this BomLineHolder. It also makes it processable if it was {@link BOMLineHolderState#RAW}. + * + * @param obj the {@link ISnecmaObject} + */ + void setSnecmaObject(final ISnecmaObject obj) { + this.snecmaObject = obj; + if (state == BOMLineHolderState.RAW) { + this.state = BOMLineHolderState.PROCESSING; + } + } + + @Override + public String getUid() { + return bomLineObject.getUid(); + } + + @Override + public int compareTo(final BOMLineHolder other) { + return getUid().compareTo(other.getUid()); + } + + private void readObject(final ObjectInputStream stream) throws IOException, ClassNotFoundException { + stream.defaultReadObject(); // Deserialize the non-transient data + } + + @Override + public String toString() { + switch (state) { + case RAW: + return toStringRaw(); + case PROCESSING: + return toStringProcessing(); + case FROZEN: + return toStringFrozen(); + default: + return toStringDefault(); + } + } + + private String toStringProcessing() { + return String.format("BOMLineHolder %s (PROCESSING) with a %s whose ID=\"%s\"", getUid(), snecmaObject.getType(), snecmaObject.getItemId()); + } + + private String toStringDefault() { + return String.format("BOMLineHolder %s in unknown state: \"%s\"", getUid(), state.toString()); + } + + private String toStringFrozen() { + return String.format("BOMLineHolder %s (FROZEN) with a %s whose ID=\"%s\"", getUid(), snecmaObject.getType(), snecmaObject.getItemId()); + } + + private String toStringRaw() { + StringBuilder builder = new StringBuilder("BOMLineHolder "); + builder.append(getUid()).append(" (RAW) with a "); + if (itemRevision == null) { + builder.append("null object inside its BOMLine"); + } + else { + String itemId = itemRevision.get_item_id(); + String itemType = itemRevision.getTypeObject().getName(); + builder.append(itemType).append(" whose ID=\"").append(itemId).append("\""); + } + return builder.toString(); + } + + public ItemRevision getItemRevision() { + return itemRevision; + } + + public BOMLineHolderState getState() { + return state; + } + + public String getBomAlt() { + return bomLineObject.getPropertyObject("ALT").getStringValue(); + } + + public String getBomSb() { + return bomLineObject.getPropertyObject("SB").getStringValue(); + } + + public String getBomQty() { + return bomLineObject.getPropertyObject("bl_quantity").getStringValue(); + } + + public String getBomQtyCumul() { + return bomLineObject.getPropertyObject("Qte cumulee").getStringValue(); + } + + public String getBomPanache() { + return bomLineObject.getPropertyObject("Panachage").getStringValue(); + } + + public String getUin() { + return bomLineObject.getPropertyObject("UIN").getStringValue(); + } + + public String getBomConfig() { + return bomLineObject.get_bl_config_string(); + } + + public List getPseudoFolder() { + // Now this BomLineHolder may be a Alt or Det, which may require to have its pseudo-Folder setup. + log.debug(" - Alt or DET found: investigating its pseudo-folder..."); + return ObjectInfoHelper.getPartsInPseudoFolderOfAltOrDetRevision(session, itemRevision); + + } + + public List

    getAllItemRevMasters() { + List bomObjects = new ArrayList<>(); + bomObjects.add(itemRevision.get_item_master_tag()); + for (BOMLineHolder bomChild : bomChilds) { + bomObjects.addAll(bomChild.getAllItemRevMasters()); + } + return bomObjects; + } + + + /** + * Represents the lifecycle of a {@link BOMLineHolder}.
    + * This cycle is the following sequence: {@link BOMLineHolderState #RAW RAW} --> {@link BOMLineHolderState #PROCESSING PROCESSED} --> {@link BOMLineHolderState #FROZEN FROZEN} + */ + public enum BOMLineHolderState { + /** + * In this state the BOMLineHolder contains raw Teamcenter data. + *
      + *
    • A {@link BOMLine} called {@code BOMLineObject}
    • + *
    • A {@link List} of children {@link BOMLineHolder}s called {@code bomChilds}, all of which are in the same state (RAW)
    • + *
    • A pseudo-folder (a {@link List} of {@link ModelObject}s) containing some {@link Item}s
    • + *
    + */ + RAW, + + /** + * In this state the BOMLineHolder contains processed Teamcenter data. + *
      + *
    • A {@link BOMLine} called {@code BOMLineObject}
    • + *
    • A {@link List} of children {@link BOMLineHolder}s called {@code bomChilds}, all of which are in the same state (PROCESSED)
    • + *
    • A pseudo-folder (a {@link List} of {@link ModelObject}s) containing all the correct {@link ItemRevision}s, obtained from their {@link Item}s earlier
    • + *
    + */ + PROCESSING, + + /** + * In this state the BOMLineHolder contains no more Teamcenter objects (they are null) but instead contains some strongly-typed {@link ISnecmaObject}s. + *
      + *
    • A {@link List} of children {@link BOMLineHolder}s called {@code bomChilds}, all of which are in the same state (FROZEN)
    • + *
    + * Note : any {@link ISnecmaObject} of type {@link AbstractAltOrDetRevision} will have a pseudo-folder loaded with children {@link ISnecmaObject}s. + */ + FROZEN + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/BOMLineHolderFactory.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/BOMLineHolderFactory.java new file mode 100644 index 0000000..1c2cae6 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/BOMLineHolderFactory.java @@ -0,0 +1,114 @@ +package com.capgemini.reports.bomlineholder; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.reports.bomlineholder.BOMLineHolder.BOMLineHolderState; +import com.capgemini.reports.exceptions.NotSupportedException; +import com.capgemini.reports.filter.IFilterExplosionNomenclature; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.SnecmaObjectFactory; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.Type; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * Build a BOMLineHolder. + */ +@Slf4j +public final class BOMLineHolderFactory { + + private BOMLineHolderFactory() { + // Hiding this constructor to make the class static. + } + + /** + * Build an expansion of BOM. + */ + public static BOMLineHolder buildTopBom(final TcSession session, final BOMLineHolder aTopBomLine, + final IFilterExplosionNomenclature filter) throws EmptyNomenclatureException { + // Map containing all the SnecmaObject ever built (starting empty) + Map snecmaObjectMap = new HashMap<>(); + log.debug("Starting to build top Item."); + try { + buildExpansionBomChildRec(session, aTopBomLine, snecmaObjectMap, filter); + } catch (NotSupportedException e) { + log.error("Unable to build the topLine of the expansion BOM", e); + } + return aTopBomLine; + } + + /** + * Builds a {@link BOMLineHolder}. Its {@link ISnecmaObject} will be created using the provided {@link ItemRevision}. + */ + public static BOMLineHolder buildTopBom(final TcSession session, final BOMLineHolder aTopBomLine) { + try { + loadItemProperties(session, aTopBomLine, new HashMap()); + } catch (NotSupportedException e) { + log.error("Unable to build the Snecmaobject: Type Not Supported", e); + } + return aTopBomLine; + } + + /** + * Build recursively an expansion of BOM. + */ + private static void buildExpansionBomChildRec(final TcSession session, final BOMLineHolder aBomLineHolder, final Map snecmaObjectMap, final IFilterExplosionNomenclature filter) throws NotSupportedException { + buildThisBOMLineHolder(session, aBomLineHolder, snecmaObjectMap); + // Build the children + for (Iterator bomIterator = aBomLineHolder.getBomChilds().iterator(); bomIterator.hasNext(); ) { + BOMLineHolder child = bomIterator.next(); + ItemRevision childItemRev = child.getItemRevision(); + if (childItemRev == null) { + continue; + } + Type objectType = childItemRev.getTypeObject(); + if (objectType != null && !filter.isExcluded(session, child)) { + try { + buildExpansionBomChildRec(session, child, snecmaObjectMap, filter); + child.setParent(aBomLineHolder); + } catch (NotSupportedException e) { + log.error("Unable to build the Snecmaobject: Type Not Supported. Removing the object from the BOM...", e); + bomIterator.remove(); + } + } else { + bomIterator.remove(); // remove unwanted objects or objects which are null (no access rights etc.) + } + } + } + + /** + * Builds a BOMLineHolder by creating a {@link ISnecmaObject} for every TC {@link ModelObject} found in this {@link } and its children.
    + * The BOMLineHolder will therefore be {@link BOMLineHolderState#PROCESSING}. + */ + private static void buildThisBOMLineHolder(final TcSession session, final BOMLineHolder aTopBomLine, + final Map snecmaObjectMap) throws NotSupportedException { + loadItemProperties(session, aTopBomLine, snecmaObjectMap); + //aTopBomLine.retrieveAltOrDetPseudoFolder(session, aTopBomLine.getItemRevision()); + } + + + /** + * Loads properties that are specific to the {@link ItemRevision} carried by the bomLine.
    + * Will attach a {@link ISnecmaObject} to the {@link BOMLineHolder} and make its state {@link BOMLineHolderState#PROCESSING}. + */ + private static void loadItemProperties(final TcSession session, final BOMLineHolder aTopBomLine, + final Map snecmaObjectMap) throws NotSupportedException { + ItemRevision theTopItemRev = aTopBomLine.getItemRevision(); + // Try to retrieve an already built SnecmaObject in the cache + ISnecmaObject theSnecmaObject = snecmaObjectMap.get(theTopItemRev.getUid()); + + if (theSnecmaObject == null) { + // The object did not exist in the cache, now build it and update the cache + theSnecmaObject = SnecmaObjectFactory.build(session, theTopItemRev); + snecmaObjectMap.put(theTopItemRev.getUid(), theSnecmaObject); + } + + // The object has been obtained (either with the cache or from scratch), now put it in its BOMLineHolder + aTopBomLine.setSnecmaObject(theSnecmaObject); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/BOMLineHolderHelper.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/BOMLineHolderHelper.java new file mode 100644 index 0000000..91fb7ec --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/BOMLineHolderHelper.java @@ -0,0 +1,138 @@ +package com.capgemini.reports.bomlineholder; + +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder.BOMLineHolderState; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.MalformedNomenclatureException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; + +import java.util.ArrayList; +import java.util.List; + +/** + * Helps find data inside a {@link BOMLineHolder}. + */ +public final class BOMLineHolderHelper { + + private BOMLineHolderHelper() { + // Nothing + } + + /** + * Finds the first instance of the requested type, amongst a {@link BOMLineHolder}'s children. + * + * @param bomLineHolder the BOMLineHolder. If null an {@link InvalidInputException} will be raised + * @param requestedType the requested Child Type + * @return the first child matching the requested type + * @throws NotFoundException when no child of the type could be found + * @throws InvalidInputException if the input BOMLineHolder was null + */ + public static BOMLineHolder findFirst(final BOMLineHolder bomLineHolder, final String requestedType) throws NotFoundException, + InvalidInputException { + if (bomLineHolder == null) { + throw nullBomLineProvided(requestedType); + } + if (bomLineHolder.getState() == BOMLineHolderState.RAW) { + for (BOMLineHolder child : bomLineHolder.getBomChilds()) { + if (requestedType.equals(child.getItemRevision().getTypeObject().getName())) { + return child; + } + } + // If we findAll here, no object was found, so we'll raise an exception + String fatherType = bomLineHolder.getObjectType(); + String fatherID = bomLineHolder.getItemRevision().get_item_id(); + throw new NotFoundException("No " + requestedType + " found below RAW BOMLineHolder: " + fatherType + " (" + fatherID + ")"); + } else { + for (BOMLineHolder child : bomLineHolder.getBomChilds()) { + if (requestedType.equals(child.getSnecmaObject().getType())) { + return child; + } + } + throw new NotFoundException("No " + requestedType + " found below : " + bomLineHolder.getSnecmaObject().getItemId()); + } + } + + /** + * Finds the all the instances of the requested type, amongst a {@link BOMLineHolder}'s children. + * + * @param bomLineHolder the BOMLineHolder. If null an {@link InvalidInputException} will be raised + * @param requestedType the requested Child Type + * @return a {@link List} containing every Child whose type is the one searched for + * @throws InvalidInputException if the input BOMLineHolder was null + */ + public static List findAll(final BOMLineHolder bomLineHolder, final String requestedType) throws InvalidInputException { + if (bomLineHolder == null) { + throw nullBomLineProvided(requestedType); + } + List list = new ArrayList<>(); + for (BOMLineHolder child : bomLineHolder.getBomChilds()) { + if (requestedType.equals(child.getSnecmaObject().getType())) { + list.add(child); + } + } + return list; + } + + /** + * Finds and returns the first child which is a 'RF Admin A', amongst a RF's children. + * + * @param aRF the RF + * @return the first child which is a 'RF Admin A' + * @throws NotFoundException when no child of the type could be found + * @throws InvalidInputException if the input BOMLineHolder was null + */ + public static RFAdminARevision findRfAdminA(final BOMLineHolder aRF) throws NotFoundException, InvalidInputException { + return (RFAdminARevision) findFirst(aRF, SnecmaObjectTypes.RF_ADMIN_A_REVISION).getSnecmaObject(); + } + + /** + * Finds and returns the first child which is a 'RF Admin AP', amongst a RF's children. + * + * @param aRF the RF + * @return the first child which is a 'RF Admin AP' + * @throws NotFoundException when no child of the type could be found + * @throws InvalidInputException if the input BOMLineHolder was null + */ + public static RFAdminAPRevision findRfAdminAP(final BOMLineHolder aRF) throws NotFoundException, InvalidInputException { + return (RFAdminAPRevision) findFirst(aRF, SnecmaObjectTypes.RF_ADMIN_AP_REVISION).getSnecmaObject(); + } + + /** + * Finds and returns the first child which is a 'RF Admin', amongst a RF's children. + * + * @param aRF the RF + * @return the first child which is a 'RF Admin' + * @throws NotFoundException when no child of the type could be found + * @throws InvalidInputException if the input BOMLineHolder was null + */ + public static RFAdminRevision findRfAdmin(final BOMLineHolder aRF) throws NotFoundException, InvalidInputException { + return (RFAdminRevision) findFirst(aRF, SnecmaObjectTypes.RF_ADMIN_REVISION).getSnecmaObject(); + } + + /** + * Finds and returns the 'RF Generic', of a Generic. + * + * @param aGeneric the Generic + * @return the first child which is a 'RF Generic' + * @throws MalformedNomenclatureException when no child of the type could be found (there SHOULD be one) + * @throws InvalidInputException if the input BOMLineHolder was null + */ + public static BOMLineHolder findRfGenericBL(final BOMLineHolder aGeneric) throws InvalidInputException, MalformedNomenclatureException { + try { + return findFirst(aGeneric, SnecmaObjectTypes.RF_GENERIC_REVISION); + } catch (NotFoundException e) { + if (aGeneric.getState() == BOMLineHolderState.RAW) { + throw new MalformedNomenclatureException("No RF Generic found below RAW Generic: " + aGeneric.getBomLineObject().getUid(), e); + } else { + throw new MalformedNomenclatureException("No RF Generic found below Generic: " + aGeneric.getSnecmaObject().getItemId(), e); + } + } + } + + private static InvalidInputException nullBomLineProvided(final String requestedType) { + return new InvalidInputException("Unable to find a '" + requestedType + "' because the BomLineHolder was null"); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/IBOMTree.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/IBOMTree.java new file mode 100644 index 0000000..311244f --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/IBOMTree.java @@ -0,0 +1,92 @@ +package com.capgemini.reports.bomlineholder; + +import com.capgemini.reports.bomlineholder.processor.IBOMLineHolderProcessor; +import com.capgemini.reports.bomlineholder.visitor.IBOMLineHolderExtractor; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.teamcenter.soa.client.model.strong.BOMLine; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import java.io.Serializable; +import java.util.List; + +/** + * Common interface for tree structure like BOM lines. + **/ +public interface IBOMTree extends Serializable { + + /** + * All the BOMLineHolder must accept a Processor which may alter its content (i.e. load extra data, or remove some branches, etc). + * + * @param aBOMLineHolderProcessor aBOMLineHolderProcessor + */ + void process(final IBOMLineHolderProcessor aBOMLineHolderProcessor); + + /** + * All the BOMLineHolder must accept an Extractor object to make the different reports. + * + * @param any kind of output expected from the extractor + * @param aBOMLineHolderExtractor aBOMLineHolderExtractor + * @return an object of type T + */ + T accept(final IBOMLineHolderExtractor aBOMLineHolderExtractor); + + /** + * Getter for the parent BOM line of the current BOM node. + * + * @return The parent BOM line + */ + IBOMTree getParentBomLine(); + + /** + * Getter for the list of children BOM lines. + * + * @return {@link List} of children BOM lines + */ + List getBomChilds(); + + /** + * Assign a child BOM line to the current line and create a reference to its parent. + * + * @param aChild New child BOM line. + */ + void addChild(final BOMLineHolder aChild); + + /** + * Assign a parent BOM line to the current line. + * + * @param aParentBomLine New parent BOM line. + */ + void setParent(final BOMLineHolder aParentBomLine); + + /** + * Getter for the managed BOM Model object of the current BOM line. + * + * @return BOM Model Object + */ + BOMLine getBomLineObject(); + + /** + * Generate unique key using item_id + item_revision_id for children BOM lines. + * + * @return Unique key for sorting purpose + */ + String getKey(); + + /** + * Getter for the SnecmaObject. + * + * @return the SnecmaObject + */ + ISnecmaObject getSnecmaObject(); + + /** + * Getter for the unique identifier. + * + * @return the uid + */ + String getUid(); + + String getObjectType(); + + ItemRevision getItemRevision(); +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/ISnecmaLineProcessor.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/ISnecmaLineProcessor.java new file mode 100644 index 0000000..a998cb0 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/ISnecmaLineProcessor.java @@ -0,0 +1,106 @@ +package com.capgemini.reports.bomlineholder; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; + +/** + * Interface for objects who can perform an action on a Snecma Bom.
    + * Provides special methods that act on every possible representation of a Snecma Bom Line, usually comprised of at least a Receptor and a Component. + */ +public interface ISnecmaLineProcessor { + /** + * Behaviour to be defined for the very first element of the nomenclature, which usually doen't have a Repere, etc. + * + * @param aTopBom the {@link BOMLineHolder} holding the top Object (usually a Generic, or a Product, sometimes a Part. + */ + void visitTopBom(final BOMLineHolder aTopBom); + + /** + * Behaviour to be defined when a 'full' line of objects is found.
    + * A 'full' line consists of: + *
      + *
    1. a Receptor like a Part, a Generic or a Product + *
    2. a Repere Fonctionnel associated with the receptor + *
    3. a Component like a Generic or a Part + *
    4. a Repere Fonctionnel associated with the component + *
    + * + * @param receptor the Receptor inside its {@link BOMLineHolder} + * @param rfReceptor the Receptor's repere inside its {@link BOMLineHolder} + * @param component the Component inside its {@link BOMLineHolder} + * @param rfComponent the Component's repere inside its {@link BOMLineHolder} + */ + void visitQuad(final BOMLineHolder receptor, final BOMLineHolder rfReceptor, final BOMLineHolder component, final BOMLineHolder rfComponent); + + + /** + * Behaviour to be defined when a Product-Generic-RF Generic line is found.
    + * + * @param productReceptor the Receptor inside its {@link BOMLineHolder} + * @param genericComponent the Component inside its {@link BOMLineHolder} + * @param rfGenericComponent the Component's repere inside its {@link BOMLineHolder} + */ + void visitProductGeneric(final BOMLineHolder productReceptor, final BOMLineHolder genericComponent, final BOMLineHolder rfGenericComponent); + + /** + * Behaviour to be defined when a PartNumber is encountered.
    + * A Part Number if always found in this structure (and only in this structure): + *
      + *
    1. a GenericReceptor + *
    2. an only RF Generic below the Generic + *
    3. an only PartAero below the RF Generic + *
    + * Note the Generic may have other children than the RF Generic, like some RF Parts..
    + * Also not the RF Generic should have other children than the PrtAero, like RF Admins (who own additional data on the RF Generic), etc. + * + * @param genericReceptor + * @param rfGeneric + * @param child + */ + void visitPartNumber(final BOMLineHolder genericReceptor, final BOMLineHolder rfGeneric, final BOMLineHolder child); + + /** + * Behaviour to be defined when the top object is a Part (therefore without an RF Part) points to an RF Part which owns a Part.
    + * This method is only encountered (once) when the nomenclature explosion begins on as Part. + * + * @param part the father Part + * @param rfPart a RF Part below the father Part + * @param child a Part below the RF Part + */ + void visitPartAsComponent(final BOMLineHolder part, final BOMLineHolder rfPart, final BOMLineHolder child); + + /** + * Behaviour to be defined a Part poitns to an other Part in the nomenclature.
    + * At the lower levels of nomenclature, Parts can have Parts as their direct children, whith neither having a RF Part. + * + * @param fatherPart the father Part + * @param childPart the child Part + */ + void visitPartPart(final BOMLineHolder fatherPart, final BOMLineHolder childPart); + + /** + * Behaviour to be defined when encountering an Alt or a DET, which contain a Part in its pseudo-folders.
    + * This method is invoked only when visitPartsInPseudoFolderw is set to true. + * + * @param aPart the Alt or DET part + * @param child a child Part found in the pseudo-folder + */ + void visitPartsInPseudoFolder(final BOMLineHolder aPart, final AbstractPart child); + + /** + * Behaviour to be defined when encountering a Receptor which has a Rf, but this Rf links to no component. + * + * @param part the part receptor + * @param rfPart the RfPart + */ + void visitReceptorWithoutComponent(final BOMLineHolder part, final BOMLineHolder rfPart); + + /** + * Behaviour to be defined when we need only a Receptor and a repere. + * + * @param session + * @param anObject anObject can be a part or generic or a product + * @param aRf can be any kind of repair + */ + void visitReceptorRepere(TcSession session, final BOMLineHolder anObject, final BOMLineHolder aRf); +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/comparison/AbstractDualBomLineFlattener.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/comparison/AbstractDualBomLineFlattener.java new file mode 100644 index 0000000..2d1d721 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/comparison/AbstractDualBomLineFlattener.java @@ -0,0 +1,214 @@ +package com.capgemini.reports.bomlineholder.comparison; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.flattener.line.*; +import com.capgemini.reports.releasestatus.EffectivityBehaviourHelper; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; + +/** + * This class analyses two {@link BOMLineHolder} and recursively flattens their tree structure into a {@link List} of Receptor-component links.
    + * Each Receptor-component relationship can be expressed with a {@link SnecmaLine} object like {@link AbstractQuad}, {@link AbstractTopLine}, {@link AbstractPartNumber}, {@link AbstractPartRfPart}, {@link AbstractPartPart}, {@link AbstractReceptorLine}, {@link AbstractProductGeneric}.
    + * These {@link SnecmaLine}s are all able to receive a transformer object of type U, and produce a result of type T.
    + * The result is two {@link List}s of {@link SnecmaLine}s which can be obtained with {@link AbstractDualBomLineFlattener#getConfig1()} and {@link AbstractDualBomLineFlattener#getConfig2()}. + * + * @param a Transformer object for transforming each {@link SnecmaLine} and producing results of type U. + * @param the type of results, as an outcome of a transformation by object of type T. + */ +@Getter +public abstract class AbstractDualBomLineFlattener extends DualBomLineBrowser implements IDualSnecmaLineProcessor { + + private final List> config1 = new ArrayList<>(); + private final List> config2 = new ArrayList<>(); + @Setter(value = AccessLevel.PROTECTED) + private DealWithAltOrDetPseudoFolder pseudoFolderBehaviour; + + /** + * Constructs a BomLineFlattener with the specified behaviour regarding effectivity, parts in pseudo-folders, part numbers, etc. + * + * @param effectivityBehaviour the behaviour to be had when having to resolve the effectivity of a Part (i.e. should a part that is managed by date visited?) + * @param visitPartsInPseudoFolder the behaviour to be had when encountering a pseudo-folder: should it be looked at, or not at all? + * @param retrievePartNumberUnderRfGeneric the behaviour to be had when encountering a Generic/RF Generic/Part: should it be looked at, or not at all? + * @param visitPartBelowPart the behaviour to be had when encountering a Part right below an other (without RF in-between): should it be looked at, or not at all? + * @param pseudoFolderBehaviour the behaviour to be had when encountering a psuedo-folder. Can produce useful objects when invoked on one + * @param bomComparator {@link Comparator} for {@link BOMLineHolder}s, to know which bomlines are matching accross configurations + * @param itemComparator {@link Comparator} for {@link ISnecmaObject}s, to know which items are matching in pseudo-folders accross configurations + * @param generateBrotherLinesBeforeRecursion if true, then all brother lines of a parent object will be generated before recursing through the brothers' children + */ + public AbstractDualBomLineFlattener(final EffectivityBehaviourHelper effectivityBehaviour, final boolean visitPartsInPseudoFolder, + final boolean retrievePartNumberUnderRfGeneric, final boolean visitPartBelowPart, + final DealWithAltOrDetPseudoFolder pseudoFolderBehaviour, final Comparator bomComparator, + final Comparator itemComparator, final boolean generateBrotherLinesBeforeRecursion) { + super(effectivityBehaviour, visitPartsInPseudoFolder, retrievePartNumberUnderRfGeneric, visitPartBelowPart, bomComparator, itemComparator); + this.pseudoFolderBehaviour = pseudoFolderBehaviour; + if (generateBrotherLinesBeforeRecursion) { + this.setPreProcessor(this); + } else { + this.setProcessor(this); + } + } + + @Override + public void visitPartsInPseudoFolder(final OptionalBomPair aPart, final OptionalPartPair child) { + if (aPart.firstExists() && child.firstExists()) { + Collection> setFromPseudoFolder = pseudoFolderBehaviour.dealWithIt(aPart.getFirst(), child.getFirst()); + config1.addAll(setFromPseudoFolder); + } + if (aPart.secondExists() && child.secondExists()) { + Collection> setFromPseudoFolder = pseudoFolderBehaviour.dealWithIt(aPart.getSecond(), child.getSecond()); + config2.addAll(setFromPseudoFolder); + } + } + + @Override + public void visitQuad(final TcSession session, final OptionalBomPair receptor, final OptionalBomPair rfReceptor, final OptionalBomPair component, + final OptionalBomPair rfComponent) { + if (receptor.firstExists() && rfReceptor.firstExists() && component.firstExists() && rfComponent.firstExists()) { + config1.add(makeQuad(session, receptor.getFirst(), rfReceptor.getFirst(), component.getFirst(), rfComponent.getFirst())); + } + if (receptor.secondExists() && rfReceptor.secondExists() && component.secondExists() && rfComponent.secondExists()) { + config2.add(makeQuad(session, receptor.getSecond(), rfReceptor.getSecond(), component.getSecond(), rfComponent.getSecond())); + } + } + + @Override + public void visitTopBom(final OptionalBomPair aTopBomLine) { + AbstractTopLine topLine1 = maketopline(aTopBomLine.getFirst()); + AbstractTopLine topLine2 = maketopline(aTopBomLine.getSecond()); + if (topLine1 != null && topLine2 != null) { + config1.add(topLine1); + config2.add(topLine2); + } + } + + @Override + public void visitProductGeneric(final TcSession session, final OptionalBomPair productReceptor, final OptionalBomPair genericComponent, + final OptionalBomPair rfGenericComponent) { + if (productReceptor.firstExists() && genericComponent.firstExists() && rfGenericComponent.firstExists()) { + AbstractProductGeneric productGeneric1 = + makeProductGeneric(session, productReceptor.getFirst(), genericComponent.getFirst(), rfGenericComponent.getFirst()); + if (productGeneric1 != null) { + config1.add(productGeneric1); + } + } + if (productReceptor.secondExists() && genericComponent.secondExists() && rfGenericComponent.secondExists()) { + AbstractProductGeneric productGeneric2 = + makeProductGeneric(session, productReceptor.getSecond(), genericComponent.getSecond(), rfGenericComponent.getSecond()); + if (productGeneric2 != null) { + config2.add(productGeneric2); + } + } + } + + @Override + public void visitPartNumber(final OptionalBomPair genericReceptor, final OptionalBomPair rfGeneric, final OptionalBomPair partNumber) { + if (genericReceptor.firstExists() && rfGeneric.firstExists() && partNumber.firstExists()) { + AbstractPartNumber partNumberLine1 = makePartNumber(genericReceptor.getFirst(), rfGeneric.getFirst(), partNumber.getFirst()); + if (partNumberLine1 != null) { + config1.add(partNumberLine1); + } + } + if (genericReceptor.secondExists() && rfGeneric.secondExists() && partNumber.secondExists()) { + AbstractPartNumber partNumberLine2 = makePartNumber(genericReceptor.getSecond(), rfGeneric.getSecond(), partNumber.getSecond()); + if (partNumberLine2 != null) { + config2.add(partNumberLine2); + } + } + } + + @Override + public void visitPartAsComponent(final TcSession session, final OptionalBomPair partReceptor, final OptionalBomPair rfPartComponent, final OptionalBomPair partComponent) { + if (partReceptor.firstExists() && rfPartComponent.firstExists() && partComponent.firstExists()) { + AbstractPartRfPart partRfPart1 = makePartRfPart(session, partReceptor.getFirst(), rfPartComponent.getFirst(), partComponent.getFirst()); + if (partRfPart1 != null) { + config1.add(partRfPart1); + } + } + if (partReceptor.secondExists() && rfPartComponent.secondExists() && partComponent.secondExists()) { + AbstractPartRfPart partRfPart2 = makePartRfPart(session, partReceptor.getSecond(), rfPartComponent.getSecond(), partComponent.getSecond()); + if (partRfPart2 != null) { + config2.add(partRfPart2); + } + } + } + + @Override + public void visitPartPart(final OptionalBomPair partReceptor, final OptionalBomPair partComponent) { + if (partReceptor.firstExists() && partComponent.firstExists()) { + AbstractPartPart partPart1 = makePartPart(partReceptor.getFirst(), partComponent.getFirst()); + if (partPart1 != null) { + config1.add(partPart1); + } + } + if (partReceptor.secondExists() && partComponent.secondExists()) { + AbstractPartPart partPart2 = makePartPart(partReceptor.getSecond(), partComponent.getSecond()); + if (partPart2 != null) { + config2.add(partPart2); + } + } + } + + @Override + public void visitReceptorWithoutComponent(final TcSession session, final OptionalBomPair part, final OptionalBomPair rfPart) { + if (part.firstExists() && rfPart.firstExists()) { + AbstractReceptorLine receptorLine = makeReceptorLine(session, part.getFirst(), rfPart.getFirst()); + if (receptorLine != null) { + config1.add(receptorLine); + } + } + if (part.secondExists() && rfPart.secondExists()) { + AbstractReceptorLine receptorLine = makeReceptorLine(session, part.getSecond(), rfPart.getSecond()); + if (receptorLine != null) { + config2.add(receptorLine); + } + } + } + + protected abstract AbstractQuad makeQuad(TcSession session, final BOMLineHolder receptor, final BOMLineHolder rfReceptor, final BOMLineHolder component, + final BOMLineHolder rfComponent); + + protected abstract AbstractTopLine maketopline(final BOMLineHolder aTopBomLine); + + protected abstract AbstractPartNumber makePartNumber(final BOMLineHolder genericReceptor, final BOMLineHolder rfGeneric, + final BOMLineHolder partAero); + + protected abstract AbstractPartRfPart makePartRfPart(TcSession session, final BOMLineHolder partReceptor, final BOMLineHolder rfPartComponent, + final BOMLineHolder partComponent); + + protected abstract AbstractPartPart makePartPart(final BOMLineHolder partReceptor, final BOMLineHolder partComponent); + + protected abstract AbstractReceptorLine makeReceptorLine(TcSession session, final BOMLineHolder part, final BOMLineHolder rfPart); + + protected abstract AbstractProductGeneric makeProductGeneric(TcSession session, final BOMLineHolder productReceptor, final BOMLineHolder genericComponent, + final BOMLineHolder rfGenericComponent); + + /** + * Behaviour to be had when encountering a pseudoFolder.
    + * The objective of the behaviour is to produce a set of objects representing the contents of the pseudofolder, as a {@link Collection} of {@link SnecmaLine}.
    + * A {@link SnecmaLine} can produce an object of type T when submitted to a transformaer object of Type U. + * + * @param the type of object the {@link SnecmaLine}s can produce + * @param the type of Transformer that can be applied to the SnecmaLine + */ + public interface DealWithAltOrDetPseudoFolder { + + /** + * Deals with a {@link BOMLineHolder} holding reference to an Alt or a DET. + * + * @param bomLineHolder + * @param iSnecmaObject + * @return a collections of return objects. + */ + Collection> dealWithIt(final BOMLineHolder bomLineHolder, final AbstractPart iSnecmaObject); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/comparison/DualBomLineBrowser.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/comparison/DualBomLineBrowser.java new file mode 100644 index 0000000..c6a2b79 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/comparison/DualBomLineBrowser.java @@ -0,0 +1,588 @@ +package com.capgemini.reports.bomlineholder.comparison; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderHelper; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.MalformedNomenclatureException; +import com.capgemini.reports.releasestatus.EffectivityBehaviourHelper; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.part.AbstractAltOrDetRevision; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import com.capgemini.reports.snecmaobjects.part.AlternateRevision; +import com.capgemini.reports.snecmaobjects.part.DETRevision; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +import java.util.*; + +/** + * Browse a {@link BOMLineHolder} tree, and presents methods for dealing with a coherent set of objects + * having a strong relationship in the Bom, like Generic-RfGeneric-PartAero.
    + * The various abstract methods each expose such coherent sets of objects, and are called in the browsing order. + */ +@Slf4j +@Getter +public class DualBomLineBrowser { + + // Sub-components that define the behaviour of this Visitor + private final EffectivityBehaviourHelper effectivityBehaviour; + private final boolean doRetrievePartNumberUnderRfGeneric; + private final boolean doVisitPartBelowPart; + private final boolean doVisitPartsInPseudoFolder; + private final Comparator bomComparator; + private final Comparator itemComparator; + + @Setter(value = AccessLevel.PROTECTED) + private IDualSnecmaLineProcessor preProcessor; + @Setter(value = AccessLevel.PROTECTED) + private IDualSnecmaLineProcessor processor; + + /** + * Constructor. + * + * @param effectivityBehaviour : the behaviour regarding Effectivities + * @param visitPartsInPseudoFolder : the behaviour regarding pseudofolders of {@link AlternateRevision} or {@link DETRevision} parts. + * @param retrievePartNumberUnderRfGeneric boolean Take true if we retrieve the Part number under the RF Generic. Take false else. + * @param visitPartBelowPart tells the Visitor weather it should visit a Part that is below another Part + * @param bomComparator {@link Comparator} for {@link BOMLineHolder}s, to know which bomlines are matching accross configurations + * @param itemComparator {@link Comparator} for {@link ISnecmaObject}s, to know which items are matching in pseudo-folders accross configurations + */ + public DualBomLineBrowser(final EffectivityBehaviourHelper effectivityBehaviour, final boolean visitPartsInPseudoFolder, + final boolean retrievePartNumberUnderRfGeneric, final boolean visitPartBelowPart, final Comparator bomComparator, + final Comparator itemComparator) { + this.effectivityBehaviour = effectivityBehaviour; + this.doVisitPartsInPseudoFolder = visitPartsInPseudoFolder; + this.doRetrievePartNumberUnderRfGeneric = retrievePartNumberUnderRfGeneric; + this.doVisitPartBelowPart = visitPartBelowPart; + this.bomComparator = bomComparator; + this.itemComparator = itemComparator; + this.processor = new PassiveProcessor(); + } + + private static AbstractPart nextPartOrNull(final Iterator iterator) { + if (!iterator.hasNext()) { + return null; + } else { + return iterator.next(); + } + } + + private static List getCommonChildren(final List conf1, final List conf2, + final Comparator itemComparator) { + List pairs = new ArrayList<>(); + Iterator iterator1 = conf1.iterator(); + Iterator iterator2 = conf2.iterator(); + AbstractPart child1 = nextPartOrNull(iterator1); + AbstractPart child2 = nextPartOrNull(iterator2); + while (child1 != null || child2 != null) { + if (child1 != null && child2 != null) { + int cmp = itemComparator.compare(child1, child2); + if (cmp == 0) { + pairs.add(new OptionalPartPair(child1, child2)); + child1 = nextPartOrNull(iterator1); + child2 = nextPartOrNull(iterator2); + } else if (cmp > 0) { + pairs.add(new OptionalPartPair(child1, null)); + child1 = nextPartOrNull(iterator1); + } else { + pairs.add(new OptionalPartPair(null, child2)); + child2 = nextPartOrNull(iterator2); + } + } else if (child1 != null) { + pairs.add(new OptionalPartPair(child1, null)); + child1 = nextPartOrNull(iterator1); + } else { + pairs.add(new OptionalPartPair(null, child2)); + child2 = nextPartOrNull(iterator2); + } + } + return pairs; + } + + /** + * Visit a Top BOMLineHolder and expand all the children to retrieve the properties. + */ + public void visitTopReceptorBom(final TcSession session, final BOMLineHolder aTopBomLineConf1, final BOMLineHolder aTopBomLineConf2) + throws MalformedNomenclatureException { + // Create a Specific first line + OptionalBomPair topPair = new OptionalBomPair(aTopBomLineConf1, aTopBomLineConf2); + preProcessor.visitTopBom(topPair); + + // Analyze the type of the SnecmaObject and visit it according to this type + ISnecmaObject theSnecmaObject1 = aTopBomLineConf1.getSnecmaObject(); + ISnecmaObject theSnecmaObject2 = aTopBomLineConf2.getSnecmaObject(); + if (theSnecmaObject1 != null && theSnecmaObject2 != null) { + if (theSnecmaObject1.getType().compareTo(theSnecmaObject2.getType()) != 0) { + throw new MalformedNomenclatureException("Top BomLines have differing types"); + } + if (theSnecmaObject1.isProduct()) { + visitProductAsReceptor(session, topPair); + } else if (theSnecmaObject1.isGeneric()) { + visitGenericAsReceptor(session, topPair); + } else if (theSnecmaObject1.isPart()) { + visitPartAsReceptor(session, topPair); + } else { + throw new MalformedNomenclatureException("Unupported bom: topLine " + aTopBomLineConf1.getSnecmaObject().getItemId() + + " is not a Generic, a Product, or a Part. It is a " + aTopBomLineConf1.getSnecmaObject().getType()); + } + } else { + throw new MalformedNomenclatureException("Empty top BomLine"); + } + } + + private void visitPartAsReceptor(final TcSession session, final OptionalBomPair aPart) { + List commonChildren = getCommonChildren(aPart, bomComparator); + // Pre - processing + if (preProcessor != null) { + + for (OptionalBomPair child : commonChildren) { + if (doVisitPartBelowPart && child.isPart()) { + preProcessor.visitPartPart(aPart, child); // Non-recursive + } + if (child.isRFPartOrPartAssemb()) { + preProcessRfPart(session, aPart, child); + } + } + if (SnecmaObjectTypes.isAltOrDet(aPart.getType()) && doVisitPartsInPseudoFolder) { // Specific treatment of Alt or Det Receptor + List pseudoFolder1; + if (aPart.firstExists()) { + pseudoFolder1 = ((AbstractAltOrDetRevision) aPart.getFirst().getSnecmaObject()).getPseudoFolder(); + } else { + pseudoFolder1 = new ArrayList<>(); + } + List pseudoFolder2; + if (aPart.secondExists()) { + pseudoFolder2 = ((AbstractAltOrDetRevision) aPart.getSecond().getSnecmaObject()).getPseudoFolder(); + } else { + pseudoFolder2 = new ArrayList<>(); + } + for (OptionalPartPair child : getCommonChildren(pseudoFolder1, pseudoFolder2, itemComparator)) { + // Visit the pseudo-folder + preProcessor.visitPartsInPseudoFolder(aPart, child); + } + } + } + + + // There may be other children, like some Parts, RF Parts + for (OptionalBomPair child : commonChildren) { + if (doVisitPartBelowPart && child.isPart()) { + processor.visitPartPart(aPart, child); + visitPartAsReceptor(session, child); // Recursive + } + if (child.isRFPartOrPartAssemb()) { + visitRfPart(session, aPart, child); + } + } + if (SnecmaObjectTypes.isAltOrDet(aPart.getType()) && doVisitPartsInPseudoFolder) { // Specific treatment of Alt or Det Receptor + List pseudoFolder1; + if (aPart.firstExists()) { + pseudoFolder1 = ((AbstractAltOrDetRevision) aPart.getFirst().getSnecmaObject()).getPseudoFolder(); + } else { + pseudoFolder1 = new ArrayList<>(); + } + List pseudoFolder2; + if (aPart.secondExists()) { + pseudoFolder2 = ((AbstractAltOrDetRevision) aPart.getSecond().getSnecmaObject()).getPseudoFolder(); + } else { + pseudoFolder2 = new ArrayList<>(); + } + for (OptionalPartPair child : getCommonChildren(pseudoFolder1, pseudoFolder2, itemComparator)) { + // Visit the pseudo-folder + processor.visitPartsInPseudoFolder(aPart, child); + } + } + } + + private void preProcessRfPart(final TcSession session, final OptionalBomPair aPart, final OptionalBomPair rfPart) { + boolean partFound = false; + for (OptionalBomPair child : getCommonChildren(rfPart, bomComparator)) { + if (child.isPart()) { + preProcessor.visitPartAsComponent(session, aPart, rfPart, child); + partFound = true; + } + } + if (!partFound) { + preProcessor.visitReceptorWithoutComponent(session, aPart, rfPart); + } + } + + private void visitRfPart(final TcSession session, final OptionalBomPair aPart, final OptionalBomPair rfPart) { + boolean partFound = false; + for (OptionalBomPair child : getCommonChildren(rfPart, bomComparator)) { + if (child.isPart()) { + processor.visitPartAsComponent(session, aPart, rfPart, child); + visitPartAsReceptor(session, child); + partFound = true; + } + } + if (!partFound) { + processor.visitReceptorWithoutComponent(session, aPart, rfPart); + } + } + + private void visitProductAsReceptor(final TcSession session, final OptionalBomPair productReceptors) throws MalformedNomenclatureException { + // Pre - processing : fetch all PRoduct - Gen - RF Gen + List commonChildren = getCommonChildren(productReceptors, bomComparator); + if (preProcessor != null) { + for (OptionalBomPair child : commonChildren) { + if (child.isGeneric()) { + OptionalBomPair rfGenericComponent = extractRfGeneric(child); + preProcessor.visitProductGeneric(session, productReceptors, child, rfGenericComponent); + } + } + } + + // Recursive processing + for (OptionalBomPair child : commonChildren) { + if (child.isGeneric()) { + // According to the MDD, there is one and only one RF Generic below any Generic. + OptionalBomPair rfGenericComponent = extractRfGeneric(child); + processor.visitProductGeneric(session, productReceptors, child, rfGenericComponent); + + // Now the component becomes receptor + visitGenericAsReceptor(session, child); + } + } + } + + private void visitGenericAsReceptor(final TcSession session, final OptionalBomPair genericReceptor) throws MalformedNomenclatureException { + // According to the MDD, there is one and only one RF Generic below any Generic. + OptionalBomPair rfGeneric = extractRfGeneric(genericReceptor); + List commonChildren = getCommonChildren(genericReceptor, bomComparator); + + if (preProcessor != null) { + // Pre-processing + if (doRetrievePartNumberUnderRfGeneric) { + // Go ahead and extract the generic / Rf Generic / Part + visitRfGeneric(genericReceptor, rfGeneric, preProcessor); + } + // There may be other children, like some RF parts + for (OptionalBomPair child : commonChildren) { + if (child.isRFPartOrPartAssemb()) { + visitRfPartAsComponentNoRec(session, genericReceptor, rfGeneric, child); + } else if (child.isGeneric()) { + visitGenericAsComponentNoRec(session, genericReceptor, rfGeneric, child); + } + } + } + + // Recursive treatment now + if (doRetrievePartNumberUnderRfGeneric) { + // Go ahead and extract the generic / Rf Generic / Part + visitRfGeneric(genericReceptor, rfGeneric, processor); + } + // There may be other children, like some RF parts + for (OptionalBomPair child : commonChildren) { + if (child.isRFPartOrPartAssemb()) { + visitRfPartAsComponentRec(session, genericReceptor, rfGeneric, child); + } else if (child.isGeneric()) { + processor.visitQuad(session, genericReceptor, rfGeneric, child, extractRfGeneric(child)); + visitGenericAsReceptor(session, child); + } + } + } + + private void visitGenericAsComponentNoRec(final TcSession session, final OptionalBomPair genericReceptor, final OptionalBomPair rfGenericReceptor, + final OptionalBomPair genericComponent) throws MalformedNomenclatureException { + // According to the MDD, there is one and only one RF Generic below any Generic. + OptionalBomPair rfGenericComponent = extractRfGeneric(genericComponent); + preProcessor.visitQuad(session, genericReceptor, rfGenericReceptor, genericComponent, rfGenericComponent); + } + + private void visitRfPartAsComponentNoRec(final TcSession session, final OptionalBomPair receptor, final OptionalBomPair rfReceptor, final OptionalBomPair rfPart) { + boolean partFound = false; + for (OptionalBomPair child : getCommonChildren(rfPart, bomComparator)) { + if (child.isPart()) { + preProcessor.visitQuad(session, receptor, rfReceptor, child, rfPart); + partFound = true; + } + } + if (!partFound) { + preProcessor.visitReceptorWithoutComponent(session, receptor, rfPart); + } + } + + private void visitRfPartAsComponentRec(final TcSession session, final OptionalBomPair receptor, final OptionalBomPair rfReceptor, final OptionalBomPair rfPart) { + // Recursivity + boolean partFound = false; + for (OptionalBomPair child : getCommonChildren(rfPart, bomComparator)) { + if (child.isPart()) { + processor.visitQuad(session, receptor, rfReceptor, child, rfPart); + visitPartAsReceptor(session, child); + partFound = true; + } + } + if (!partFound) { + processor.visitReceptorWithoutComponent(session, receptor, rfPart); + } + } + + // RF Generics have a single PartAero below them. Also below , RF Admin(s) carry data about this RfGeneric + private void visitRfGeneric(final OptionalBomPair genericReceptor, final OptionalBomPair rfGeneric, final IDualSnecmaLineProcessor proc) + throws MalformedNomenclatureException { + for (OptionalBomPair child : getCommonChildren(rfGeneric, bomComparator)) { + if (child.isPart()) { + proc.visitPartNumber(genericReceptor, rfGeneric, child); + return; + } + } + throw new MalformedNomenclatureException("No part aero found below RfGeneric"); + } + + private OptionalBomPair extractRfGeneric(final OptionalBomPair aGeneric) throws MalformedNomenclatureException { + BOMLineHolder rfGeneric1; + try { + rfGeneric1 = BOMLineHolderHelper.findRfGenericBL(aGeneric.first); + } catch (InvalidInputException e) { + log.trace("null Generic in conf 1 ", e); // This is OK, it is exclusive to conf2 + rfGeneric1 = null; + } + BOMLineHolder rfGeneric2; + try { + rfGeneric2 = BOMLineHolderHelper.findRfGenericBL(aGeneric.second); + } catch (InvalidInputException e) { + log.trace("null Generic in conf 2 ", e); // This is OK, it is exclusive to conf1 + rfGeneric2 = null; + } + return new OptionalBomPair(rfGeneric1, rfGeneric2); + } + + /** + * Sort the children of a BomLineHolder. + * + * @param bomHolder IBOMTree + * @param comparator the comparator to be used for sorting. The comparator must be resilient to null. Any two elements deemed equal according to this comparator will be kept in the same order as they are found. + */ + private List sortBomChildren(final BOMLineHolder bomHolder, final Comparator comparator) { + if (bomHolder == null) { + return Collections.emptyList(); + } + List copy = new ArrayList<>(bomHolder.getBomChilds()); + removeIllConditioned(copy); // Remove all null elements for safety + Collections.sort(copy, comparator); + return copy; + } + + private void removeIllConditioned(final List list) { + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + BOMLineHolder blh = iterator.next(); + if (blh == null || blh.getSnecmaObject() == null) { + iterator.remove(); + } + } + } + + /** + * Returns a List of comparison pairs from both configurations. All RF that have the wrong effectivity are ignored in the ouput.
    + * A resulting child pair can be: + *
      + *
    • one-sided: item is found only in one of the two configurations, no object from the other conf is equal according to the provided {@link Comparator} or maybe the other item is a RF with wrong effectivity (date etc.)
    • + *
    • Two-sided: an item from either configuration is found, and the provided {@link Comparator} finds them equal.
    • + *
    + * + * @param pair pair the original pair of objects to be compared. + * @param dualComparator the comparator to be used for sorting. The comparator must be resilient to null. Any two elements deemed equal according to this comparator will be kept in the same order as they are found. + */ + private List getCommonChildren(final OptionalBomPair pair, final Comparator dualComparator) { + List pairs = new ArrayList<>(); + Iterator iterator1 = sortBomChildren(pair.getFirst(), dualComparator).iterator(); // Sort both boms according to the comparator's sense of order + Iterator iterator2 = sortBomChildren(pair.getSecond(), dualComparator).iterator(); // Sort both boms according to the comparator's sense of order + BOMLineHolder child1 = nextOrNull(iterator1); + BOMLineHolder child2 = nextOrNull(iterator2); + while (child1 != null || child2 != null) { + if (child1 != null && child2 != null) { + // Both lists are not empty... + int cmp = dualComparator.compare(child1, child2); + if (cmp == 0) { + pairs.add(new OptionalBomPair(child1, child2)); + child1 = nextOrNull(iterator1); + child2 = nextOrNull(iterator2); + } else if (cmp < 0) { + pairs.add(new OptionalBomPair(child1, null)); + child1 = nextOrNull(iterator1); + } else { + pairs.add(new OptionalBomPair(null, child2)); + child2 = nextOrNull(iterator2); + } + } else if (child1 != null) { + pairs.add(new OptionalBomPair(child1, null)); + child1 = nextOrNull(iterator1); + } else { + pairs.add(new OptionalBomPair(null, child2)); + child2 = nextOrNull(iterator2); + } + } + return pairs; + } + + private BOMLineHolder nextOrNull(final Iterator iterator) { + if (!iterator.hasNext()) { + return null; // No more elements in this iterator + } + BOMLineHolder next = iterator.next(); + if (next.getSnecmaObject().isRF() && !effectivityBehaviour.shouldVisit(next)) { + next = nextOrNull(iterator); // Next element is a RF, wich should not be visited, so we'll jump it + } + return next; + } + + private static class PassiveProcessor implements IDualSnecmaLineProcessor { + + @Override + public void visitTopBom(final OptionalBomPair aTopBom) { + // Nothing to do + } + + @Override + public void visitReceptorWithoutComponent(TcSession session, final OptionalBomPair part, final OptionalBomPair rfPart) { + // Nothing to do + } + + @Override + public void visitQuad(TcSession session, final OptionalBomPair receptor, final OptionalBomPair rfReceptor, final OptionalBomPair component, + final OptionalBomPair rfComponent) { + // Nothing to do + } + + @Override + public void visitProductGeneric(TcSession session, final OptionalBomPair productReceptor, final OptionalBomPair genericComponent, + final OptionalBomPair rfGenericComponent) { + // Nothing to do + } + + @Override + public void visitPartsInPseudoFolder(final OptionalBomPair aPart, final OptionalPartPair child) { + // Nothing to do + } + + @Override + public void visitPartPart(final OptionalBomPair fatherPart, final OptionalBomPair childPart) { + // Nothing to do + } + + @Override + public void visitPartNumber(final OptionalBomPair genericReceptor, final OptionalBomPair rfGeneric, final OptionalBomPair child) { + // Nothing to do + } + + @Override + public void visitPartAsComponent(TcSession session, final OptionalBomPair part, final OptionalBomPair rfPart, final OptionalBomPair child) { + // Nothing to do + } + } + + /** + * Can hold a pair of snecma {@link ISnecmaObject} from either conf, which are deemed similar to each other. Either one may be null, or none. + */ + @Getter + @AllArgsConstructor + public static class OptionalPartPair { + + private final AbstractPart first; + private final AbstractPart second; + + /** + * True if the object of the 1st conf is undefined. + * + * @return True if the bomLineHolder of the 1st conf is undefined + */ + public boolean firstExists() { + return first != null; + } + + /** + * True if the object of the 2nd conf is undefined. + * + * @return True if the bomLineHolder of the 2nd conf is undefined + */ + public boolean secondExists() { + return second != null; + } + } + + /** + * Can hold a pair of {@link BOMLineHolder}s from either conf, which are deemed similar to each other. Either one may be null, or none. + */ + @Getter + @AllArgsConstructor + public static class OptionalBomPair { + private final BOMLineHolder first; + private final BOMLineHolder second; + + /** + * Returns the common type of both held objects. + * + * @return a String containing the object type. + */ + public String getType() { + return first == null ? second.getSnecmaObject().getType() : first.getSnecmaObject().getType(); + } + + /** + * Return true if it is a RF Generic. + * + * @return the boolean + */ + public boolean isRFGeneric() { + return first == null ? second.getSnecmaObject().isRFGeneric() : first.getSnecmaObject().isRFGeneric(); + } + + /** + * Return true if it is a RF Part or a RF PArt Assemb. + * + * @return the boolean + */ + public boolean isRFPartOrPartAssemb() { + return first == null ? second.getSnecmaObject().isRFPartOrPartAssemb() : first.getSnecmaObject().isRFPartOrPartAssemb(); + } + + /** + * Return true if it is a Part. + * + * @return the boolean + */ + public boolean isPart() { + return first == null ? second.getSnecmaObject().isPart() : first.getSnecmaObject().isPart(); + } + + /** + * Return true if it is a Generic. + * + * @return the boolean + */ + public boolean isGeneric() { + return first == null ? second.getSnecmaObject().isGeneric() : first.getSnecmaObject().isGeneric(); + } + + /** + * True if the bomLineHolder of the 1st conf is undefined. + * + * @return True if the bomLineHolder of the 1st conf is undefined + */ + public boolean firstExists() { + return first != null; + } + + /** + * True if the bomLineHolder of the 2nd conf is undefined. + * + * @return True if the bomLineHolder of the 2nd conf is undefined + */ + public boolean secondExists() { + return second != null; + } + + @Override + public String toString() { + return "Pair: " + (firstExists() ? first.toString() : "") + " <-> " + (secondExists() ? second.toString() : ""); + } + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/comparison/IDualSnecmaLineProcessor.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/comparison/IDualSnecmaLineProcessor.java new file mode 100644 index 0000000..0510157 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/comparison/IDualSnecmaLineProcessor.java @@ -0,0 +1,105 @@ +package com.capgemini.reports.bomlineholder.comparison; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.comparison.DualBomLineBrowser.OptionalBomPair; +import com.capgemini.reports.bomlineholder.comparison.DualBomLineBrowser.OptionalPartPair; + +/** + * Interface for objects who can process an {@link OptionalBomPair} from a Bom comparison. + */ +public interface IDualSnecmaLineProcessor { + + /** + * Behaviour to be defined for the very first element of the nomenclature, which usually doen't have a Repere, etc. + * + * @param aTopBom the {@link BOMLineHolder} holding the top Object (usually a Generic, or a Product, sometimes a Part. + */ + void visitTopBom(final OptionalBomPair aTopBom); + + /** + * Behaviour to be defined when a 'full' line of objects is found.
    + * A 'full' line consists of: + *
      + *
    1. a Receptor like a Part, a Generic or a Product + *
    2. a Repere Fonctionnel associated with the receptor + *
    3. a Component like a Generic or a Part + *
    4. a Repere Fonctionnel associated with the component + *
    + * + * @param session + * @param receptor the Receptor inside its {@link BOMLineHolder} + * @param rfReceptor the Receptor's repere inside its {@link BOMLineHolder} + * @param component the Component inside its {@link BOMLineHolder} + * @param rfComponent the Component's repere inside its {@link BOMLineHolder} + */ + void visitQuad(TcSession session, final OptionalBomPair receptor, final OptionalBomPair rfReceptor, final OptionalBomPair component, + final OptionalBomPair rfComponent); + + + /** + * Behaviour to be defined when a Product-Generic-RF Generic line is found.
    + * + * @param session + * @param productReceptor the Receptor inside its {@link BOMLineHolder} + * @param genericComponent the Component inside its {@link BOMLineHolder} + * @param rfGenericComponent the Component's repere inside its {@link BOMLineHolder} + */ + void visitProductGeneric(TcSession session, final OptionalBomPair productReceptor, final OptionalBomPair genericComponent, final OptionalBomPair rfGenericComponent); + + /** + * Behaviour to be defined when a PartNumber is encountered.
    + * A Part Number if always found in this structure (and only in this structure): + *
      + *
    1. a GenericReceptor + *
    2. an only RF Generic below the Generic + *
    3. an only PartAero below the RF Generic + *
    + * Note the Generic may have other children than the RF Generic, like some RF Parts..
    + * Also not the RF Generic should have other children than the PrtAero, like RF Admins (who own additional data on the RF Generic), etc. + * + * @param genericReceptor + * @param rfGeneric + * @param child + */ + void visitPartNumber(final OptionalBomPair genericReceptor, final OptionalBomPair rfGeneric, final OptionalBomPair child); + + /** + * Behaviour to be defined when the top object is a Part (therefore without an RF Part) points to an RF Part which owns a Part.
    + * This method is only encountered (once) when the nomenclature explosion begins on as Part. + * + * @param session + * @param part the father Part + * @param rfPart a RF Part below the father Part + * @param child a Part below the RF Part + */ + void visitPartAsComponent(TcSession session, final OptionalBomPair part, final OptionalBomPair rfPart, final OptionalBomPair child); + + /** + * Behaviour to be defined a Part poitns to an other Part in the nomenclature.
    + * At the lower levels of nomenclature, Parts can have Parts as their direct children, whith neither having a RF Part. + * + * @param fatherPart the father Part + * @param childPart the child Part + */ + void visitPartPart(final OptionalBomPair fatherPart, final OptionalBomPair childPart); + + /** + * Behviour to be defined when encountering an Alt or a DET, which contain a Part in its pseudo-folders.
    + * This method is invoked only when visitPartsInPseudoFolderw is set to true. + * + * @param aPart the Alt or DET part + * @param child a child Part found in the pseudo-folder + */ + void visitPartsInPseudoFolder(final OptionalBomPair aPart, final OptionalPartPair child); + + /** + * Behviour to be defined when encountering a Receptor which has a Rf, but this Rf links to no component. + * + * @param session + * @param part the part receptor + * @param rfPart the RfPart + */ + void visitReceptorWithoutComponent(TcSession session, final OptionalBomPair part, final OptionalBomPair rfPart); + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/AbstractBomLineFlattener.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/AbstractBomLineFlattener.java new file mode 100644 index 0000000..0c9ab1d --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/AbstractBomLineFlattener.java @@ -0,0 +1,158 @@ +package com.capgemini.reports.bomlineholder.flattener; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.ISnecmaLineProcessor; +import com.capgemini.reports.bomlineholder.flattener.line.*; +import com.capgemini.reports.bomlineholder.visitor.BomLineBrowser; +import com.capgemini.reports.releasestatus.EffectivityBehaviourHelper; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * This class analyses a {@link BOMLineHolder} and flattens its tree structure into a {@link List} of Receptor-component links.
    + * Each Receptor-component relationship can be expressed with a {@link SnecmaLine} object like {@link AbstractQuad}, {@link AbstractTopLine}, {@link AbstractPartNumber}, {@link AbstractPartRfPart}, {@link AbstractPartPart}, {@link AbstractReceptorLine}, {@link AbstractProductGeneric}.
    + * These {@link SnecmaLine}s are all able to receive a transformer object of type U, and procude a result of type T. + * + * @param a Transformer object for transforming each line and producing results of type U. + * @param the type of results, as an outcome of a transformation by object of type T. + */ +@Getter +public abstract class AbstractBomLineFlattener extends BomLineBrowser implements ISnecmaLineProcessor { + + private final List> config = new ArrayList<>(); + @Setter(value = AccessLevel.PROTECTED) + private DealWithAltOrDetPseudoFolder pseudoFolderBehaviour; + + /** + * Constructs a BomLineFlattener with the specified behaviour regarding effectivity, parts in psuedo-folders, part numbers, etc. + * + * @param effectivityBehaviour the behaviour to be had when having to resolve the effectivity of a Part (i.e. should a part that is managed by date visited?) + * @param visitPartsInPseudoFolder the behaviour to be had when encountering a pseudo-folder: should it be looked at, or not at all? + * @param retrievePartNumberUnderRfGeneric the behaviour to be had when encountering a Generic/RF Generic/Part: should it be looked at, or not at all? + * @param visitPartBelowPart the behaviour to be had when encountering a Part right below an other (without RF in-between): should it be looked at, or not at all? + * @param pseudoFolderBehaviour the behaviour to be had when encountering a pseudo-folder. Can produce useful objects when invoked on an Alternate/DET + * @param generateBrotherLinesBeforeRecursion if true, then all the children will be visited without recursion first, then again with recursion. + */ + public AbstractBomLineFlattener(final EffectivityBehaviourHelper effectivityBehaviour, final boolean visitPartsInPseudoFolder, + final boolean retrievePartNumberUnderRfGeneric, final boolean visitPartBelowPart, + final DealWithAltOrDetPseudoFolder pseudoFolderBehaviour, final boolean generateBrotherLinesBeforeRecursion) { + super(effectivityBehaviour, visitPartsInPseudoFolder, retrievePartNumberUnderRfGeneric, visitPartBelowPart); + this.pseudoFolderBehaviour = pseudoFolderBehaviour; + if (generateBrotherLinesBeforeRecursion) { + this.setPreProcessor(this); + } else { + this.setProcessor(this); + } + } + + @Override + public void visitPartsInPseudoFolder(final BOMLineHolder aPart, final AbstractPart child) { + Collection> setFromPseudoFolder = pseudoFolderBehaviour.dealWithIt(aPart, child); + config.addAll(setFromPseudoFolder); + } + + @Override + public void visitQuad(final BOMLineHolder receptor, final BOMLineHolder rfReceptor, final BOMLineHolder component, + final BOMLineHolder rfComponent) { + config.add(makeQuad(receptor, rfReceptor, component, rfComponent)); + } + + @Override + public void visitTopBom(final BOMLineHolder aTopBomLine) { + AbstractTopLine topLine = makeTopline(aTopBomLine); + if (topLine != null) { + config.add(makeTopline(aTopBomLine)); + } + } + + @Override + public void visitProductGeneric(final BOMLineHolder productReceptor, final BOMLineHolder genericComponent, + final BOMLineHolder rfGenericComponent) { + AbstractProductGeneric productGeneric = makeProductGeneric(productReceptor, genericComponent, rfGenericComponent); + if (productGeneric != null) { + config.add(productGeneric); + } + } + + @Override + public void visitPartNumber(final BOMLineHolder genericReceptor, final BOMLineHolder rfGeneric, final BOMLineHolder child) { + AbstractPartNumber partNumber = makePartNumber(genericReceptor, rfGeneric, child); + if (partNumber != null) { + config.add(partNumber); + } + } + + @Override + public void visitPartAsComponent(final BOMLineHolder partReceptor, final BOMLineHolder rfPartComponent, final BOMLineHolder partComponent) { + AbstractPartRfPart partRfPart = makePartRfPart(partReceptor, rfPartComponent, partComponent); + if (partRfPart != null) { + config.add(partRfPart); + } + } + + @Override + public void visitPartPart(final BOMLineHolder partReceptor, final BOMLineHolder partComponent) { + AbstractPartPart partPart = makePartPart(partReceptor, partComponent); + if (partPart != null) { + config.add(partPart); + } + } + + @Override + public void visitReceptorWithoutComponent(final BOMLineHolder part, final BOMLineHolder rfPart) { + AbstractReceptorLine receptorLine = makeReceptorLine(part, rfPart); + if (receptorLine != null) { + config.add(receptorLine); + } + } + + @Override + public final void visitReceptorRepere(TcSession session, final BOMLineHolder anObject, final BOMLineHolder aRF) { + // Nothing to do here! If you want a Receptor-Repere, use the AbstractRepereFlattener + } + + protected abstract AbstractQuad makeQuad(final BOMLineHolder receptor, final BOMLineHolder rfReceptor, final BOMLineHolder component, + final BOMLineHolder rfComponent); + + protected abstract AbstractTopLine makeTopline(final BOMLineHolder aTopBomLine); + + protected abstract AbstractPartNumber makePartNumber(final BOMLineHolder genericReceptor, final BOMLineHolder rfGeneric, + final BOMLineHolder partAero); + + protected abstract AbstractPartRfPart makePartRfPart(final BOMLineHolder partReceptor, final BOMLineHolder rfPartComponent, + final BOMLineHolder partComponent); + + protected abstract AbstractPartPart makePartPart(final BOMLineHolder partReceptor, final BOMLineHolder partComponent); + + protected abstract AbstractReceptorLine makeReceptorLine(final BOMLineHolder part, final BOMLineHolder rfPart); + + protected abstract AbstractProductGeneric makeProductGeneric(final BOMLineHolder productReceptor, final BOMLineHolder genericComponent, + final BOMLineHolder rfGenericComponent); + + /** + * Behaviour to be had when encountering a pseudoFolder.
    + * The objective of the behaviour is to produce a set of objects representing the contents of the pseudofolder, as a {@link Collection} of {@link SnecmaLine}.
    + * A {@link SnecmaLine} can produce an object of type T when submitted to a transformaer object of Type U. + * + * @param the type of object the {@link SnecmaLine}s can produce + * @param the type of Transformer that can be applied to the snecmaLine + */ + public interface DealWithAltOrDetPseudoFolder { + /** + * Deals with a {@link BOMLineHolder} holding reference to an Alt or a DET. + * + * @param alt a Alt {@link BOMLineHolder} + * @param partInPseudoFolder a Part in the pseudo folder of the Alt + * @return a collections of return objects. + */ + Collection> dealWithIt(final BOMLineHolder alt, final AbstractPart partInPseudoFolder); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/AbstractRepereFlattener.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/AbstractRepereFlattener.java new file mode 100644 index 0000000..d06a7c4 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/AbstractRepereFlattener.java @@ -0,0 +1,104 @@ +package com.capgemini.reports.bomlineholder.flattener; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.ISnecmaLineProcessor; +import com.capgemini.reports.bomlineholder.flattener.line.AbstractReceptorRepere; +import com.capgemini.reports.bomlineholder.flattener.line.SnecmaLine; +import com.capgemini.reports.bomlineholder.visitor.BomLineBrowser; +import com.capgemini.reports.releasestatus.EffectivityBehaviourHelper; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class implements the interface {@link ISnecmaLineProcessor} and inherits of {@link BomLineBrowser}. It defines what kind of behavior it will adopt during the exploration of data. + * + * @param a class representing a, {@link AbstractReceptorRepere} + */ +@Getter +public abstract class AbstractRepereFlattener> extends BomLineBrowser implements ISnecmaLineProcessor { + + private final List config = new ArrayList<>(); + + /** + * Constructor. + * + * @param effectivityBehaviour + * @param visitPartsInPseudoFolder + * @param retrievePartNumberUnderRfGeneric + * @param visitPartBelowPart + * @param deeplyExplosion + */ + public AbstractRepereFlattener(final EffectivityBehaviourHelper effectivityBehaviour, final boolean visitPartsInPseudoFolder, + final boolean retrievePartNumberUnderRfGeneric, final boolean visitPartBelowPart, final boolean deeplyExplosion) { + super(effectivityBehaviour, visitPartsInPseudoFolder, retrievePartNumberUnderRfGeneric, visitPartBelowPart); + if (deeplyExplosion) { + this.setProcessor(this); + } else { + this.setPreProcessor(this); + } + } + + @Override + public final void visitTopBom(final BOMLineHolder aTopBom) { + // Nothing to do + } + + @Override + public final void visitQuad(final BOMLineHolder receptor, final BOMLineHolder rfReceptor, final BOMLineHolder component, + final BOMLineHolder rfComponent) { + // Nothing to do + } + + @Override + public final void visitProductGeneric(final BOMLineHolder productReceptor, final BOMLineHolder genericComponent, + final BOMLineHolder rfGenericComponent) { + // Nothing to do + } + + @Override + public final void visitPartNumber(final BOMLineHolder genericReceptor, final BOMLineHolder rfGeneric, final BOMLineHolder child) { + // Nothing to do + } + + @Override + public final void visitPartAsComponent(final BOMLineHolder part, final BOMLineHolder rfPart, final BOMLineHolder child) { + // Nothing to do + } + + @Override + public final void visitPartPart(final BOMLineHolder fatherPart, final BOMLineHolder childPart) { + // Nothing to do + } + + @Override + public final void visitPartsInPseudoFolder(final BOMLineHolder aPart, final AbstractPart child) { + // Nothing to do + } + + @Override + public final void visitReceptorWithoutComponent(final BOMLineHolder part, final BOMLineHolder rfPart) { + // Nothing to do + } + + @Override + public void visitReceptorRepere(final TcSession session, final BOMLineHolder anObject, final BOMLineHolder aRF) { + RR receptorRepere = makeRepairReceptorLine(session, anObject, aRF); + if (receptorRepere != null) { + config.add(receptorRepere); + } + } + + /** + * Method which allow to make a receptor-repere {@link SnecmaLine}. + * + * @param session + * @param anObject an object + * @param functionnalRepere its RF + * @return the {@link AbstractReceptorRepere} + */ + public abstract RR makeRepairReceptorLine(final TcSession session, final BOMLineHolder anObject, final BOMLineHolder functionnalRepere); +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractAltPart.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractAltPart.java new file mode 100644 index 0000000..7177d93 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractAltPart.java @@ -0,0 +1,254 @@ +package com.capgemini.reports.bomlineholder.flattener.line; + +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.snecmaobjects.part.*; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * Represents a direct Part/Part link. No RFs in-between. + * + * @param a Transformer object producing results of type T + * @param the result of a transformation by object of type U + */ +@AllArgsConstructor +@Getter +public abstract class AbstractAltPart implements SnecmaLine { + + private static final String NON = "Non"; + private static final String OUI = "Oui"; + private static final String EMPTY = ""; + + private final BOMLineHolder altBL; + private final AbstractPart child; + private final int lineNumber; + + @Override + public int compareTo(final SnecmaLine other) { + if (this.getClass().isAssignableFrom(other.getClass())) { + return compareTo((AbstractAltPart) other); + } else { + return getLineId().compareTo(other.getLineId()); + } + } + + /** + * Compares this {@link AbstractPartPart} to an other one. + * + * @param other the other {@link AbstractPartPart} + * @return a difference number. 0 if equal. + */ + public int compareTo(final AbstractAltPart other) { + int cmp = altBL.getSnecmaObject().getItemId().compareTo(other.altBL.getSnecmaObject().getItemId()); + if (cmp != 0) { + return cmp; + } else { + return child.getItemId().compareTo(other.child.getItemId()); + } + } + + @Override + public String toString() { + return "AltPart(" + getLineId() + ")"; + } + + @Override + public String getLineId() { + return altBL.getSnecmaObject().getItemId() + "/" + child.getItemId(); + } + + @Override + public String getIDReceptor() { + return altBL.getSnecmaObject().getItemId(); + } + + @Override + public String getNameReceptor() { + return altBL.getSnecmaObject().getName(); + } + + @Override + public String getRevisionReceptor() { + return altBL.getSnecmaObject().getRevisionId(); + } + + @Override + public String getRepereName() { + return EMPTY; + } + + @Override + public String getRepereRevision() { + return EMPTY; + } + + @Override + public String getResponsableRepere() { + return EMPTY; + } + + @Override + public String getSuiviMontage() { + return EMPTY; + } + + @Override + public String getIDComponent() { + return this.getChild().getItemId(); + } + + @Override + public String getIDRevisionComponent() { + return this.getChild().getRevisionId(); + } + + @Override + public String getTypeReference() { + return PartTypeExtractorHelper.extractType(this.getChild()); + } + + @Override + public String getNameReference() { + return this.getChild().getName(); + } + + @Override + public String getReferenceConceptor() { + if (this.getChild().isPart()) { + return this.getChild().getRefCompleteConcepteur(); + } + return EMPTY; + } + + @Override + public String getReferenceTransposed() { + if (this.getChild().isPart()) { + return this.getChild().getRefTransposeeSnecma(); + } + return EMPTY; + } + + @Override + public String getReferenceAssociated() { + if (this.getChild().isPart()) { + return this.getChild().getRefAssociee(); + } + return EMPTY; + } + + @Override + public String getResponsableConception() { + if (this.getChild().isPart()) { + return this.getChild().getResponsableConception(); + } + return EMPTY; + } + + @Override + public String getArticleGestion() { + if (SnecmaObjectTypes.isA(this.getChild().getType(), SnecmaObjectTypes.DET_REVISION, SnecmaObjectTypes.ALTERNATE_REVISION, + SnecmaObjectTypes.PART_ASSEMB_REVISION)) { + return OUI; + } + return EMPTY; + } + + @Override + public String getClassement() { + if (this.getChild().isPart()) { + if ("Part Mat Revision".equals(this.getChild().getType())) { + return ((PartMatRevision) this.getChild()).getClassementMat(); + } else { + return this.getChild().getClassement(); + } + + } + return EMPTY; + } + + @Override + public String getSuiviUtilisation() { + if (this.getChild().isPart()) { + return this.getChild().getSuiviUtilisation(); + } + return OUI; + } + + @Override + public String getSuiviDureeVie() { + if (this.getChild().isPart()) { + return this.getChild().getSuiviDureeVie(); + } + return NON; + } + + @Override + public String[] getSuppliersList() { + String type = this.getChild().getType(); + if (this.getChild().isPart() && !SnecmaObjectTypes.PART_NO_AERO_REVISION.equals(type)) { + String[] lst; + if (SnecmaObjectTypes.PART_AERO_REVISION.equals(type)) { + lst = ((PartAeroRevision) this.getChild()).getLstFournisseurs(); + } else if (SnecmaObjectTypes.PART_MAT_REVISION.equals(type)) { + lst = ((PartMatRevision) this.getChild()).getLstFournisseurs(); + } else if (SnecmaObjectTypes.STANDARD_REVISION.equals(type)) { + lst = ((StandardRevision) this.getChild()).getLstFournisseurs(); + } else if (SnecmaObjectTypes.DET_REVISION.equals(type)) { + lst = ((DETRevision) this.getChild()).getLstFournisseurs(); + } else if (SnecmaObjectTypes.ALTERNATE_REVISION.equals(type)) { + lst = ((AlternateRevision) this.getChild()).getLstFournisseurs(); + } else { + lst = new String[0]; + } + return lst; + } + return new String[0]; + } + + @Override + public String getALT() { + return EMPTY; + } + + @Override + public String getSB() { + return EMPTY; + } + + @Override + public String getQuantiteCumulee() { + return EMPTY; + } + + @Override + public String getPanachage() { + return EMPTY; + } + + @Override + public String getQuantite() { + return EMPTY; + } + + @Override + public String getMaquetteInterneExterne() { + return EMPTY; + } + + @Override + public Double getMass() { + return child.getMass(); + } + + @Override + public String getMassUnit() { + return child.getMassUnit(); + } + + @Override + public String getDesignationENG() { + return child.getDesignationEN(); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractPartNumber.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractPartNumber.java new file mode 100644 index 0000000..f875883 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractPartNumber.java @@ -0,0 +1,80 @@ +package com.capgemini.reports.bomlineholder.flattener.line; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * Represents a Generic/RF Generic/Part Number structure. + * + * @param a Transformer object producing results of type T + * @param the result of a transformation by object of type U + */ +@AllArgsConstructor +@Getter +public abstract class AbstractPartNumber implements SnecmaLine { + + private final BOMLineHolder generic; + private final BOMLineHolder rfGeneric; + private final BOMLineHolder partAero; + private final int lineNumber; + + @Override + public int compareTo(final SnecmaLine other) { + if (this.getClass().isAssignableFrom(other.getClass())) { + return compareTo((AbstractPartNumber) other); + } else { + return getLineId().compareTo(other.getLineId()); + } + } + + /** + * Compares this {@link AbstractPartNumber} to an other one. + * + * @param other the other {@link AbstractPartNumber} + * @return a difference number. 0 if equal. + */ + public int compareTo(final AbstractPartNumber other) { + int cmp = generic.getSnecmaObject().getItemId().compareTo(other.generic.getSnecmaObject().getItemId()); + if (cmp == 0) { + cmp = rfGeneric.getSnecmaObject().getName().compareTo(other.rfGeneric.getSnecmaObject().getName()); + if (cmp == 0) { + if (partAero == null) { + return other.partAero == null ? 0 : 1; + } else { + return partAero.getSnecmaObject().getItemId().compareTo(other.partAero.getSnecmaObject().getItemId()); + } + } + } + return cmp; + } + + @Override + public String toString() { + return "PartNumber(" + getLineId() + ")"; + } + + @Override + public String getLineId() { + return generic.getSnecmaObject().getItemId() + "/" + rfGeneric.getSnecmaObject().getName() + "/" + partAero.getSnecmaObject().getItemId(); + } + + @Override + public Double getMass() { + if (partAero.getSnecmaObject().isPart()) { + return ((AbstractPart) partAero.getSnecmaObject()).getMass(); + } + return null; + } + + @Override + public String getMassUnit() { + if (partAero.getSnecmaObject().isPart()) { + return ((AbstractPart) partAero.getSnecmaObject()).getMassUnit(); + } + return StringHelper.EMPTY; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractPartPart.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractPartPart.java new file mode 100644 index 0000000..4365afa --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractPartPart.java @@ -0,0 +1,73 @@ +package com.capgemini.reports.bomlineholder.flattener.line; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * Represents a direct Part/Part link. No RFs in-between. + * + * @param a Transformer object producing results of type T + * @param the result of a transformation by object of type U + */ +@AllArgsConstructor +@Getter +public abstract class AbstractPartPart implements SnecmaLine { + + private final BOMLineHolder partReceptor; + private final BOMLineHolder partComponent; + private final int lineNumber; + + @Override + public int compareTo(final SnecmaLine other) { + if (this.getClass().isAssignableFrom(other.getClass())) { + return compareTo((AbstractPartPart) other); + } else { + return getLineId().compareTo(other.getLineId()); + } + } + + /** + * Compares this {@link AbstractPartPart} to an other one. + * + * @param other the other {@link AbstractPartPart} + * @return a difference number. 0 if equal. + */ + public int compareTo(final AbstractPartPart other) { + int cmp = partReceptor.getSnecmaObject().getItemId().compareTo(other.partReceptor.getSnecmaObject().getItemId()); + if (cmp != 0) { + return cmp; + } else { + return partComponent.getSnecmaObject().getItemId().compareTo(other.partComponent.getSnecmaObject().getItemId()); + } + } + + @Override + public String toString() { + return "PartPart(" + getLineId() + ")"; + } + + @Override + public String getLineId() { + return partReceptor.getSnecmaObject().getItemId() + "/" + partComponent.getSnecmaObject().getItemId(); + } + + @Override + public Double getMass() { + if (partComponent.getSnecmaObject().isPart()) { + return ((AbstractPart) partComponent.getSnecmaObject()).getMass(); + } + return null; + } + + @Override + public String getMassUnit() { + if (partComponent.getSnecmaObject().isPart()) { + return ((AbstractPart) partComponent.getSnecmaObject()).getMassUnit(); + } + return StringHelper.EMPTY; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractPartRfPart.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractPartRfPart.java new file mode 100644 index 0000000..3238d9c --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractPartRfPart.java @@ -0,0 +1,293 @@ +package com.capgemini.reports.bomlineholder.flattener.line; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderHelper; +import com.capgemini.reports.snecmaobjects.part.*; +import com.capgemini.reports.snecmaobjects.rf.AbstractRF; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +/** + * Represents a Part/RF Part/Part. + * + * @param the result of a transformation by object of type U + * @param a Transformer object producing results of type T + */ +@Getter +@Slf4j +public abstract class AbstractPartRfPart implements SnecmaLine { + + private static final String NON = "Non"; + private static final String OUI = "Oui"; + private static final String EMPTY = ""; + + private final BOMLineHolder partReceptorBL; + private final BOMLineHolder rfPartComponentBL; + private final BOMLineHolder partComponentBL; + private final int lineNumber; + + private final AbstractPart partReceptor; + private final AbstractRF rfPartComponent; + private final AbstractPart partComponent; + protected final TcSession session; + + /** + * Constructor using a Part receptor, a RF Part component , and a Part component (all bomLineHolders). + * + * @param session + * @param partReceptor the receptor Part + * @param rfPartComponent the RF Part + * @param partComponent the Component Part + * @param lineNumber a line number, identifying uniquely and orderly this triplet in the configuration. + */ + public AbstractPartRfPart(final TcSession session, final BOMLineHolder partReceptor, final BOMLineHolder rfPartComponent, final BOMLineHolder partComponent, + final int lineNumber) { + this.session = session; + this.partReceptorBL = partReceptor; + this.rfPartComponentBL = rfPartComponent; + this.partComponentBL = partComponent; + this.lineNumber = lineNumber; + this.partReceptor = (AbstractPart) partReceptorBL.getSnecmaObject(); + this.rfPartComponent = (AbstractRF) rfPartComponentBL.getSnecmaObject(); + this.partComponent = (AbstractPart) partComponentBL.getSnecmaObject(); + } + + @Override + public int compareTo(final SnecmaLine other) { + if (this.getClass().isAssignableFrom(other.getClass())) { + return compareTo((AbstractPartRfPart) other); + } else { + return getLineId().compareTo(other.getLineId()); + } + } + + /** + * Compares this {@link AbstractPartRfPart} to an other one. + * + * @param other the other {@link AbstractPartRfPart} + * @return a difference number. 0 if equal. + */ + public int compareTo(final AbstractPartRfPart other) { + int cmp = partReceptor.getItemId().compareTo(other.partReceptor.getItemId()); + if (cmp == 0) { + cmp = rfPartComponent.getName().compareTo(other.rfPartComponent.getName()); + if (cmp == 0) { + if (partComponentBL == null) { + return other.partComponentBL == null ? 0 : 1; + } + return partComponent.getItemId().compareTo(other.partComponent.getItemId()); + } + } + return cmp; + } + + @Override + public String toString() { + return "PartRfPart(" + getLineId() + ")"; + } + + @Override + public String getLineId() { + return partReceptor.getItemId() + "/" + rfPartComponent.getName() + "/" + partComponent.getItemId(); + } + + @Override + public String getIDReceptor() { + return partReceptor.getItemId(); + } + + @Override + public String getNameReceptor() { + return partReceptor.getName(); + } + + @Override + public String getRevisionReceptor() { + return partReceptor.getRevisionId(); + } + + @Override + public String getRepereName() { + return rfPartComponent.getName(); + } + + @Override + public String getRepereRevision() { + return rfPartComponent.getRevisionId(); + } + + @Override + public String getResponsableRepere() { + try { + String resp; + if (SnecmaObjectTypes.RF_PART_ASSEMB_REVISION.equals(rfPartComponent.getType())) { + resp = BOMLineHolderHelper.findRfAdminA(this.getRfPartComponentBL()).getResponsableRepere(); + } else { + resp = BOMLineHolderHelper.findRfAdmin(this.getRfPartComponentBL()).getResponsableRepere(); + } + return resp; + } catch (KurtException e) { + log.warn("Unable to find the correct RF Admins below Rf: " + rfPartComponent.getName(), e); + return EMPTY; + } + } + + @Override + public String getSuiviMontage() { + try { + String suiviMontage; + if (rfPartComponent.isRFGeneric()) { + suiviMontage = NON; + } else if (rfPartComponent.isRFPartOrPartAssemb()) { + if (SnecmaObjectTypes.RF_PART_ASSEMB_REVISION.equals(rfPartComponent.getType())) { + suiviMontage = BOMLineHolderHelper.findRfAdminA(rfPartComponentBL).getSuiviMontage(); + } else { + suiviMontage = BOMLineHolderHelper.findRfAdminAP(rfPartComponentBL).getSuiviMontage(); + } + } else { + suiviMontage = EMPTY; + } + return suiviMontage; + } catch (KurtException e) { + log.warn("Unable to find the correct RF Admins A/AP below Rf Part / RF Part Assemb: " + rfPartComponent.getName(), e); + return EMPTY; + } + } + + @Override + public String getIDComponent() { + return partComponent.getItemId(); + } + + @Override + public String getIDRevisionComponent() { + return partComponent.getRevisionId(); + } + + @Override + public String getTypeReference() { + return PartTypeExtractorHelper.extractType(partComponent); + } + + @Override + public String getNameReference() { + return partComponent.getName(); + } + + @Override + public String getReferenceConceptor() { + return partComponent.getRefCompleteConcepteur(); + } + + @Override + public String getReferenceTransposed() { + return partComponent.getRefTransposeeSnecma(); + } + + @Override + public String getReferenceAssociated() { + return partComponent.getRefAssociee(); + } + + @Override + public String getResponsableConception() { + return partComponent.getResponsableConception(); + } + + @Override + public String getArticleGestion() { + if (SnecmaObjectTypes.isA(partComponent.getType(), SnecmaObjectTypes.DET_REVISION, SnecmaObjectTypes.ALTERNATE_REVISION, + SnecmaObjectTypes.PART_ASSEMB_REVISION)) { + return OUI; + } + return EMPTY; + } + + @Override + public String getClassement() { + if (SnecmaObjectTypes.PART_MAT_REVISION.equals(partComponent.getType())) { + return ((PartMatRevision) partComponent).getClassementMat(); + } else { + return partComponent.getClassement(); + } + } + + @Override + public String getSuiviUtilisation() { + return partComponent.getSuiviUtilisation(); + } + + @Override + public String getSuiviDureeVie() { + return partComponent.getSuiviDureeVie(); + } + + @Override + public String[] getSuppliersList() { + String type = partComponent.getType(); + String[] lst; + if (SnecmaObjectTypes.PART_AERO_REVISION.equals(type)) { + lst = ((PartAeroRevision) partComponent).getLstFournisseurs(); + } else if (SnecmaObjectTypes.PART_MAT_REVISION.equals(type)) { + lst = ((PartMatRevision) partComponent).getLstFournisseurs(); + } else if (SnecmaObjectTypes.STANDARD_REVISION.equals(type)) { + lst = ((StandardRevision) partComponent).getLstFournisseurs(); + } else if (SnecmaObjectTypes.DET_REVISION.equals(type)) { + lst = ((DETRevision) partComponent).getLstFournisseurs(); + } else if (SnecmaObjectTypes.ALTERNATE_REVISION.equals(type)) { + lst = ((AlternateRevision) partComponent).getLstFournisseurs(); + } else { + lst = new String[0]; + } + return lst; + } + + @Override + public String getALT() { + return partComponentBL.getBomAlt(); + } + + @Override + public String getSB() { + return partComponentBL.getBomSb(); + } + + @Override + public String getQuantiteCumulee() { + return partComponentBL.getBomQtyCumul(); + } + + @Override + public String getPanachage() { + return partComponentBL.getBomPanache(); + } + + @Override + public String getQuantite() { + return partComponentBL.getBomQty(); + } + + @Override + public String getMaquetteInterneExterne() { + return EMPTY; + } + + @Override + public Double getMass() { + return partComponent.getMass(); + } + + @Override + public String getMassUnit() { + return partComponent.getMassUnit(); + } + + @Override + public String getDesignationENG() { + return partComponent.getDesignationEN(); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractProductGeneric.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractProductGeneric.java new file mode 100644 index 0000000..ab5731d --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractProductGeneric.java @@ -0,0 +1,283 @@ +package com.capgemini.reports.bomlineholder.flattener.line; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderHelper; +import com.capgemini.reports.snecmaobjects.generic.AbstractGenericRevision; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +/** + * Represents a Product/Generic/RfGeneric. + * + * @param a Transformer object producing results of type T + * @param the result of a transformation by object of type U + */ +@Getter +@Slf4j +public abstract class AbstractProductGeneric implements SnecmaLine { + + private static final String NON = "Non"; + private static final String OUI = "Oui"; + private static final String EMPTY = ""; + + private final BOMLineHolder productReceptorBL; + private final BOMLineHolder genericComponentBL; + private final BOMLineHolder rfGenericComponentBL; + private final int lineNumber; + private final ProductRevision productReceptor; + private final AbstractGenericRevision genericComponent; + private final RFGenericRevision rfGenericComponent; + protected final TcSession session; + + /** + * Constructor for a link Product-->Generic-->RF Generic. + * + * @param session + * @param productReceptorBL the product + * @param genericComponentBL the generic + * @param rfGenericComponentBL the RF Generic of the Generic + * @param lineNumber a line number, identifying uniquely and orderly this triplet in the configuration. + */ + public AbstractProductGeneric(TcSession session, final BOMLineHolder productReceptorBL, final BOMLineHolder genericComponentBL, + final BOMLineHolder rfGenericComponentBL, final int lineNumber) { + this.session = session; + this.productReceptorBL = productReceptorBL; + this.genericComponentBL = genericComponentBL; + this.rfGenericComponentBL = rfGenericComponentBL; + this.lineNumber = lineNumber; + this.productReceptor = (ProductRevision) productReceptorBL.getSnecmaObject(); + this.genericComponent = (AbstractGenericRevision) genericComponentBL.getSnecmaObject(); + this.rfGenericComponent = (RFGenericRevision) rfGenericComponentBL.getSnecmaObject(); + } + + @Override + public int compareTo(final SnecmaLine other) { + if (this.getClass().isAssignableFrom(other.getClass())) { + return compareTo((AbstractProductGeneric) other); + } else { + return getLineId().compareTo(other.getLineId()); + } + } + + /** + * Compares this {@link AbstractProductGeneric} to an other one. + * + * @param other the other {@link AbstractProductGeneric} + * @return a difference number. 0 if equal. + */ + public int compareTo(final AbstractProductGeneric other) { + int cmp = productReceptorBL.getSnecmaObject().getItemId().compareTo(other.productReceptorBL.getSnecmaObject().getItemId()); + if (cmp != 0) { + return cmp; + } else { + cmp = rfGenericComponent.getName().compareTo(other.rfGenericComponent.getName()); + if (cmp != 0) { + return cmp; + } else { + return genericComponent.getItemId().compareTo(other.genericComponent.getItemId()); + } + } + } + + @Override + public String toString() { + return "ProductGeneric(" + getLineId() + ")"; + } + + @Override + public String getLineId() { + return productReceptorBL.getSnecmaObject().getItemId() + "/" + rfGenericComponent.getName() + "/" + genericComponent.getItemId(); + } + + @Override + public String getIDReceptor() { + return productReceptorBL.getSnecmaObject().getItemId(); + } + + @Override + public String getNameReceptor() { + return productReceptorBL.getSnecmaObject().getName(); + } + + @Override + public String getRevisionReceptor() { + return productReceptorBL.getSnecmaObject().getRevisionId(); + } + + @Override + public String getRepereName() { + return rfGenericComponent.getName(); + } + + @Override + public String getRepereRevision() { + return rfGenericComponent.getRevisionId(); + } + + @Override + public String getResponsableRepere() { + try { + if (rfGenericComponent.isRFGeneric()) { + return BOMLineHolderHelper.findRfAdmin(rfGenericComponentBL).getResponsableRepere(); + } else if (rfGenericComponent.isRFPartOrPartAssemb()) { + if (SnecmaObjectTypes.RF_PART_ASSEMB_REVISION.equals(rfGenericComponent.getType())) { + return BOMLineHolderHelper.findRfAdminA(rfGenericComponentBL).getResponsableRepere(); + } else { + return BOMLineHolderHelper.findRfAdmin(rfGenericComponentBL).getResponsableRepere(); + } + } + } catch (KurtException e) { + log.warn("Unable to find a RF Admin below Rf " + rfGenericComponent.getName(), e); + return EMPTY; + } + return EMPTY; + } + + @Override + public String getSuiviMontage() { + String suiviMontage; + if (rfGenericComponent.isRFGeneric()) { + suiviMontage = NON; + } else if (rfGenericComponent.isRFPartOrPartAssemb()) { + try { + if (SnecmaObjectTypes.RF_PART_ASSEMB_REVISION.equals(rfGenericComponent.getType())) { + suiviMontage = BOMLineHolderHelper.findRfAdminA(rfGenericComponentBL).getSuiviMontage(); + } else { + suiviMontage = BOMLineHolderHelper.findRfAdminAP(rfGenericComponentBL).getSuiviMontage(); + } + } catch (KurtException e) { + log.warn("Unable to find a RF Admin A/AP below Rf Part / RF Part Assemb: " + rfGenericComponent.getName(), e); + return EMPTY; + } + } else { + suiviMontage = EMPTY; + } + return suiviMontage; + } + + @Override + public String getIDComponent() { + return genericComponent.getItemId(); + } + + @Override + public String getIDRevisionComponent() { + return genericComponent.getRevisionId(); + } + + @Override + public String getTypeReference() { + String type = genericComponent.getType(); + if (SnecmaObjectTypes.GENERIC_REVISION.equals(type)) { + return "Générique"; + } else if (SnecmaObjectTypes.GENERIC_ASSEMB_REVISION.equals(type)) { + return "Générique Montage"; + } + return ""; + } + + @Override + public String getNameReference() { + return genericComponent.getName(); + } + + @Override + public String getReferenceConceptor() { + return EMPTY; + } + + @Override + public String getReferenceTransposed() { + return EMPTY; + } + + @Override + public String getReferenceAssociated() { + return EMPTY; + } + + @Override + public String getResponsableConception() { + if (genericComponent.isGeneric()) { + return genericComponent.getResponsableConception(); + } + return EMPTY; + } + + @Override + public String getArticleGestion() { + return EMPTY; + } + + @Override + public String getClassement() { + return "-"; + } + + @Override + public String getSuiviUtilisation() { + return OUI; + } + + @Override + public String getSuiviDureeVie() { + return NON; + } + + @Override + public String[] getSuppliersList() { + return new String[0]; + } + + @Override + public String getALT() { + return genericComponentBL.getBomAlt(); + } + + @Override + public String getSB() { + return genericComponentBL.getBomSb(); + } + + @Override + public String getQuantiteCumulee() { + return genericComponentBL.getBomQtyCumul(); + } + + @Override + public String getPanachage() { + return genericComponentBL.getBomPanache(); + } + + @Override + public String getQuantite() { + return genericComponentBL.getBomQty(); + } + + @Override + public String getMaquetteInterneExterne() { + return EMPTY; + } + + @Override + public Double getMass() { + return null; + } + + @Override + public String getMassUnit() { + return StringHelper.EMPTY; + } + + @Override + public String getDesignationENG() { + return genericComponent.getDesignationEN(); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractQuad.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractQuad.java new file mode 100644 index 0000000..6fd45eb --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractQuad.java @@ -0,0 +1,386 @@ +package com.capgemini.reports.bomlineholder.flattener.line; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderHelper; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.generic.AbstractGenericRevision; +import com.capgemini.reports.snecmaobjects.part.*; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.snecmaobjects.rf.AbstractRF; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +/** + * Represents a Receptor/RF receptor/Component/Rf Component. + * + * @param a Transformer object producing results of type T + * @param the result of a transformation by object of type U + */ +@Getter +@Slf4j +public abstract class AbstractQuad implements SnecmaLine { + + private static final String MSG_NO_RF_ADMIN_A_FOUND = "No RF Admin A Found"; + private static final String MSG_NO_RF_ADMIN_FOUND = "No RF Admin Found"; + private static final String NON = "Non"; + private static final String OUI = "Oui"; + private static final String EMPTY = ""; + + private final BOMLineHolder recepteurBL; + private final BOMLineHolder repereBL; + private final BOMLineHolder composantBL; + private final BOMLineHolder repereComposantBL; + private final int lineNumber; + + private final ISnecmaObject recepteur; + private final AbstractRF repereRecepteur; + private final ISnecmaObject composant; + private final AbstractRF repereComposant; + protected final TcSession session; + + /** + * builds a {@link AbstractQuad} object out of its four constituent {@link BOMLineHolder}s. + * + * @param session + * @param recepteurBL the receptor + * @param repereRecepteurBL the repere of the receptor + * @param composantBL the component + * @param repereComposantBL the repere of the component + * @param lineNum a line number, identifying uniquely and orderly this triplet in the configuration. + */ + public AbstractQuad(final TcSession session, final BOMLineHolder recepteurBL, final BOMLineHolder repereRecepteurBL, final BOMLineHolder composantBL, + final BOMLineHolder repereComposantBL, final int lineNum) { + this.session = session; + this.recepteurBL = recepteurBL; + this.repereBL = repereRecepteurBL; + this.composantBL = composantBL; + this.repereComposantBL = repereComposantBL; + this.lineNumber = lineNum; + this.recepteur = recepteurBL.getSnecmaObject(); + this.repereRecepteur = (AbstractRF) repereRecepteurBL.getSnecmaObject(); + this.composant = composantBL.getSnecmaObject(); + this.repereComposant = (AbstractRF) repereComposantBL.getSnecmaObject(); + } + + @Override + public int compareTo(final SnecmaLine other) { + if (this.getClass().isAssignableFrom(other.getClass())) { + return compareTo((AbstractQuad) other); + } else { + return getLineId().compareTo(other.getLineId()); + } + } + + /** + * Compares this {@link AbstractQuad} to an other one. + * + * @param other the other {@link AbstractQuad} + * @return a difference number. 0 if equal. + */ + public int compareTo(final AbstractQuad other) { + int cmp = recepteur.getItemId().compareTo(other.recepteur.getItemId()); + if (cmp == 0) { + cmp = repereRecepteur.getName().compareTo(other.repereRecepteur.getName()); + if (cmp == 0) { + if (composant == null) { + return other.composant == null ? 0 : 1; + } + return composant.getItemId().compareTo(other.composant.getItemId()); + } + } + return cmp; + } + + @Override + public String toString() { + return "Quad(" + getLineId() + ")"; + } + + @Override + public String getLineId() { + return recepteur.getItemId() + "/" + repereRecepteur.getName() + "/" + + (composant == null ? "null" : composant.getItemId()) + "/" + + (repereComposant == null ? "null" : repereComposant.getName()); + } + + @Override + public String getIDReceptor() { + return recepteur.getItemId(); + } + + @Override + public String getNameReceptor() { + return recepteur.getName(); + } + + @Override + public String getRevisionReceptor() { + return recepteur.getRevisionId(); + } + + @Override + public String getRepereName() { + return repereComposant.getName(); + } + + @Override + public String getRepereRevision() { + return repereComposant.getRevisionId(); + } + + @Override + public String getResponsableRepere() { + String responsableRepere; + try { + if (repereComposant.isRFGeneric()) { + RFAdminRevision rfAdmin = BOMLineHolderHelper.findRfAdmin(repereComposantBL); + responsableRepere = rfAdmin.getResponsableRepere(); + } else if (repereComposantBL.getSnecmaObject().isRFPartOrPartAssemb()) { + if (SnecmaObjectTypes.RF_PART_ASSEMB_REVISION.equals(repereComposantBL.getSnecmaObject().getType())) { + RFAdminARevision rfAdminA = BOMLineHolderHelper.findRfAdminA(repereComposantBL); + responsableRepere = rfAdminA == null ? MSG_NO_RF_ADMIN_A_FOUND : rfAdminA.getResponsableRepere(); + } else { + RFAdminRevision rfAdmin = BOMLineHolderHelper.findRfAdmin(repereComposantBL); + responsableRepere = rfAdmin == null ? MSG_NO_RF_ADMIN_FOUND : rfAdmin.getResponsableRepere(); + } + } else { + responsableRepere = EMPTY; + } + return responsableRepere; + } catch (KurtException e) { + log.warn("Unable to find the correct RF Admins below Rf: " + repereComposantBL.getSnecmaObject().getName(), e); + return EMPTY; + } + } + + @Override + public String getSuiviMontage() { + String suiviMontage; + if (repereComposant.isRFGeneric()) { + suiviMontage = NON; + } else if (repereComposantBL.getSnecmaObject().isRFPartOrPartAssemb()) { + try { + if (SnecmaObjectTypes.RF_PART_ASSEMB_REVISION.equals(repereComposantBL.getSnecmaObject().getType())) { + RFAdminARevision rfAdminA = BOMLineHolderHelper.findRfAdminA(repereComposantBL); + suiviMontage = rfAdminA == null ? MSG_NO_RF_ADMIN_A_FOUND : rfAdminA.getSuiviMontage(); + } else { + RFAdminAPRevision rfAdminAP = BOMLineHolderHelper.findRfAdminAP(repereComposantBL); + suiviMontage = rfAdminAP == null ? MSG_NO_RF_ADMIN_FOUND : rfAdminAP.getSuiviMontage(); + } + } catch (KurtException e) { + log.warn("Unable to find the correct RF Admin A/AP below RF Part / RF PArt Assemb: " + repereComposantBL.getSnecmaObject().getName(), + e); + return EMPTY; + } + } else { + suiviMontage = EMPTY; + } + return suiviMontage; + } + + @Override + public String getIDComponent() { + return composant.getItemId(); + } + + @Override + public String getIDRevisionComponent() { + return composant.getRevisionId(); + } + + @Override + public String getTypeReference() { + String typeReference; + if (composant.isPart()) { + typeReference = PartTypeExtractorHelper.extractType(composant); + } else if (composant.isGeneric()) { + String type = composant.getType(); + if (SnecmaObjectTypes.GENERIC_REVISION.equals(type)) { + typeReference = "Générique"; + } else if (SnecmaObjectTypes.GENERIC_ASSEMB_REVISION.equals(type)) { + typeReference = "Générique Montage"; + } else { + typeReference = EMPTY; + } + } else { + typeReference = EMPTY; + } + return typeReference; + } + + @Override + public String getNameReference() { + return composant.getName(); + } + + @Override + public String getReferenceConceptor() { + if (composant.isPart()) { + return ((AbstractPart) composant).getRefCompleteConcepteur(); + } else { + return EMPTY; + } + } + + @Override + public String getReferenceTransposed() { + if (composant.isPart()) { + return ((AbstractPart) composant).getRefTransposeeSnecma(); + } else { + return EMPTY; + } + } + + @Override + public String getReferenceAssociated() { + if (composant.isPart()) { + return ((AbstractPart) composant).getRefAssociee(); + } else { + return EMPTY; + } + } + + @Override + public String getResponsableConception() { + if (composant.isPart()) { + return ((AbstractPart) composant).getResponsableConception(); + } else if (composant.isGeneric()) { + return ((AbstractGenericRevision) composant).getResponsableConception(); + } else { + return EMPTY; + } + } + + @Override + public String getArticleGestion() { + if (SnecmaObjectTypes.isAltOrDet(composant.getType()) || SnecmaObjectTypes.PART_ASSEMB_REVISION.equals(composant.getType())) { + return OUI; + } + return EMPTY; + } + + @Override + public String getClassement() { + if (composant.isPart()) { + if (SnecmaObjectTypes.PART_MAT_REVISION.equals(composant.getType())) { + return ((PartMatRevision) composant).getClassementMat(); + } else { + return ((AbstractPart) composant).getClassement(); + } + } else { + return EMPTY; + } + } + + @Override + public String getSuiviUtilisation() { + if (composant.isPart()) { + return ((AbstractPart) composant).getSuiviUtilisation(); + } else { + return OUI; + } + } + + @Override + public String getSuiviDureeVie() { + if (composant.isPart()) { + return ((AbstractPart) composant).getSuiviDureeVie(); + } else { + return NON; + } + } + + @Override + public String[] getSuppliersList() { + String[] lst; + if (composant.isPart() && !SnecmaObjectTypes.PART_NO_AERO_REVISION.equals(composant.getType())) { + if (SnecmaObjectTypes.PART_AERO_REVISION.equals(composant.getType())) { + lst = ((PartAeroRevision) composant).getLstFournisseurs(); + } else if (SnecmaObjectTypes.PART_MAT_REVISION.equals(composant.getType())) { + lst = ((PartMatRevision) composant).getLstFournisseurs(); + } else if (SnecmaObjectTypes.STANDARD_REVISION.equals(composant.getType())) { + lst = ((StandardRevision) composant).getLstFournisseurs(); + } else if (SnecmaObjectTypes.DET_REVISION.equals(composant.getType())) { + lst = ((DETRevision) composant).getLstFournisseurs(); + } else if (SnecmaObjectTypes.ALTERNATE_REVISION.equals(composant.getType())) { + lst = ((AlternateRevision) composant).getLstFournisseurs(); + } else { + lst = new String[0]; + } + } else { + lst = new String[0]; + } + return lst; + } + + @Override + public String getALT() { + return composantBL.getBomAlt(); + } + + @Override + public String getSB() { + return composantBL.getBomSb(); + } + + @Override + public String getQuantiteCumulee() { + return composantBL.getBomQtyCumul(); + } + + @Override + public String getPanachage() { + return composantBL.getBomPanache(); + } + + @Override + public String getQuantite() { + return composantBL.getBomQty(); + } + + @Override + public String getMaquetteInterneExterne() { + return EMPTY; + } + + @Override + public Double getMass() { + if (composant.isPart()) { + return ((AbstractPart) composant).getMass(); + } else { + return null; + } + } + + @Override + public String getMassUnit() { + if (composant.isPart()) { + return ((AbstractPart) composant).getMassUnit(); + } else { + return StringHelper.EMPTY; + } + } + + @Override + public String getDesignationENG() { + String designation; + if (composant.isPart()) { + designation = ((AbstractPart) composant).getDesignationEN(); + } else if (composant.isGeneric()) { + designation = ((AbstractGenericRevision) composant).getDesignationEN(); + } else if (composant.isProduct()) { + designation = ((ProductRevision) composant).getDesignationEN(); + } else { + designation = StringHelper.EMPTY; + } + return designation; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractReceptorLine.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractReceptorLine.java new file mode 100644 index 0000000..19b9fb2 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractReceptorLine.java @@ -0,0 +1,264 @@ +package com.capgemini.reports.bomlineholder.flattener.line; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderHelper; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.rf.AbstractRF; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +/** + * Represents a Receptor whose RF does not have any Component. + * + * @param a Transformer object producing results of type T + * @param the result of a transformation by object of type U + */ +@Getter +@Slf4j +public abstract class AbstractReceptorLine implements SnecmaLine { + + private static final String NON = "Non"; + private static final String EMPTY = ""; + + private final BOMLineHolder recepteurBL; + private final BOMLineHolder repereBL; + private final ISnecmaObject recepteur; + private final AbstractRF repere; + private final int lineNumber; + private final TcSession session; + + + /** + * builds a {@link AbstractReceptorLine} object from its Receptor and Repere's {@link BOMLineHolder}. + * + * @param session + * @param recepteurBL the receptor + * @param repereRecepteurBL the repere of the receptor + * @param lineNum the line number in the bom + */ + public AbstractReceptorLine(TcSession session, final BOMLineHolder recepteurBL, final BOMLineHolder repereRecepteurBL, final int lineNum) { + this.session = session; + this.recepteurBL = recepteurBL; + this.repereBL = repereRecepteurBL; + this.recepteur = recepteurBL.getSnecmaObject(); + this.repere = (AbstractRF) repereRecepteurBL.getSnecmaObject(); + this.lineNumber = lineNum; + } + + @Override + public int compareTo(final SnecmaLine other) { + if (this.getClass().isAssignableFrom(other.getClass())) { + return compareTo((AbstractReceptorLine) other); + } else { + return getLineId().compareTo(other.getLineId()); + } + } + + + /** + * Compares this {@link AbstractReceptorLine} to an other one. + * + * @param other the other {@link AbstractReceptorLine} + * @return a difference number. 0 if equal. + */ + public int compareTo(final AbstractReceptorLine other) { + int cmp = recepteur.getItemId().compareTo(other.recepteur.getItemId()); + if (cmp != 0) { + return cmp; + } else { + return repere.getName().compareTo(other.repere.getName()); + } + } + + @Override + public String toString() { + return "Receptor(" + recepteur.getItemId() + "/" + repere.getName(); + } + + @Override + public String getLineId() { + return recepteur.getItemId() + "/" + repere.getName(); + } + + @Override + public String getIDReceptor() { + return this.getRecepteur().getItemId(); + } + + @Override + public String getNameReceptor() { + return this.getRecepteur().getName(); + } + + @Override + public String getRevisionReceptor() { + return this.getRecepteur().getRevisionId(); + } + + @Override + public String getRepereName() { + return this.getRepere().getName(); + } + + @Override + public String getRepereRevision() { + return this.getRepere().getRevisionId(); + } + + @Override + public String getResponsableRepere() { + try { + if (this.getRepere().isRFGeneric()) { + return BOMLineHolderHelper.findRfAdmin(this.getRepereBL()).getResponsableRepere(); + } else if (this.getRepereBL().getSnecmaObject().isRFPartOrPartAssemb()) { + if ("RF Part Assemb Revision".equals(this.getRepereBL().getSnecmaObject().getType())) { + return BOMLineHolderHelper.findRfAdminA(this.getRepereBL()).getResponsableRepere(); + } else { + return BOMLineHolderHelper.findRfAdmin(this.getRepereBL()).getResponsableRepere(); + } + } + } catch (KurtException e) { + log.warn("Unable to find a RF Admin below Rf: " + this.getRepereBL().getSnecmaObject().getName(), e); + return EMPTY; + } + return EMPTY; + } + + @Override + public String getSuiviMontage() { + String response; + if (this.getRepere().isRFGeneric()) { + response = NON; + } else { + try { + if (this.getRepereBL().getSnecmaObject().isRFPartOrPartAssemb()) { + if ("RF Part Assemb Revision".equals(this.getRepereBL().getSnecmaObject().getType())) { + response = BOMLineHolderHelper.findRfAdminA(this.getRepereBL()).getSuiviMontage(); + } else { + response = BOMLineHolderHelper.findRfAdminAP(this.getRepereBL()).getSuiviMontage(); + } + } else { + response = EMPTY; + } + } catch (KurtException e) { + log.warn("Unable to find a RF Admin A/AP below Rf Part / RF Part Assemb: " + this.getRepereBL().getSnecmaObject().getName(), e); + return EMPTY; + } + } + return response; + } + + @Override + public String getIDComponent() { + return EMPTY; + } + + @Override + public String getIDRevisionComponent() { + return EMPTY; + } + + @Override + public String getTypeReference() { + return EMPTY; + } + + @Override + public String getNameReference() { + return EMPTY; + } + + @Override + public String getReferenceConceptor() { + return EMPTY; + } + + @Override + public String getReferenceTransposed() { + return EMPTY; + } + + @Override + public String getReferenceAssociated() { + return EMPTY; + } + + @Override + public String getResponsableConception() { + return EMPTY; + } + + @Override + public String getArticleGestion() { + return EMPTY; + } + + @Override + public String getClassement() { + return EMPTY; + } + + @Override + public String getSuiviUtilisation() { + return EMPTY; + } + + @Override + public String getSuiviDureeVie() { + return EMPTY; + } + + @Override + public String[] getSuppliersList() { + return new String[0]; + } + + @Override + public String getALT() { + return EMPTY; + } + + @Override + public String getSB() { + return EMPTY; + } + + @Override + public String getQuantiteCumulee() { + return EMPTY; + } + + @Override + public String getPanachage() { + return EMPTY; + } + + @Override + public String getQuantite() { + return EMPTY; + } + + @Override + public String getMaquetteInterneExterne() { + return EMPTY; + } + + @Override + public Double getMass() { + return null; + } + + @Override + public String getMassUnit() { + return EMPTY; + } + + @Override + public String getDesignationENG() { + return StringHelper.EMPTY; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractReceptorRepere.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractReceptorRepere.java new file mode 100644 index 0000000..627d6fe --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractReceptorRepere.java @@ -0,0 +1,207 @@ +package com.capgemini.reports.bomlineholder.flattener.line; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderHelper; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.util.Map; + +/** + * Abstract class findAll the informations of receptor and repere. + * + * @param the type of result to be produced: a {@link Map}, a {@link String}... + * @param a Transformer object producing results of type T + */ +@Slf4j +@Getter +public abstract class AbstractReceptorRepere implements SnecmaLine { + + private static final String EMPTY = ""; + + private final BOMLineHolder objectTypeReceptor; + private final BOMLineHolder repereFonctionnel; + private final TcSession session; + + protected AbstractReceptorRepere(final TcSession session, final BOMLineHolder objectTypeReceptor, final BOMLineHolder repereFonctionnel) { + this.session = session; + this.objectTypeReceptor = objectTypeReceptor; + this.repereFonctionnel = repereFonctionnel; + } + + @Override + public String getIDReceptor() { + return objectTypeReceptor.getSnecmaObject().getItemId(); + } + + @Override + public String getNameReceptor() { + return objectTypeReceptor.getSnecmaObject().getName(); + } + + @Override + public String getRevisionReceptor() { + return objectTypeReceptor.getSnecmaObject().getRevisionId(); + } + + @Override + public String getRepereName() { + return repereFonctionnel.getSnecmaObject().getName(); + } + + @Override + public String getRepereRevision() { + return repereFonctionnel.getSnecmaObject().getRevisionId(); + } + + @Override + public String getResponsableRepere() { + try { + if (repereFonctionnel.getSnecmaObject().isRFGeneric()) { + return BOMLineHolderHelper.findRfAdmin(repereFonctionnel).getResponsableRepere(); + } else if (repereFonctionnel.getSnecmaObject().isRFPartOrPartAssemb()) { + if (SnecmaObjectTypes.RF_PART_ASSEMB_REVISION.equals(repereFonctionnel.getSnecmaObject().getType())) { + return BOMLineHolderHelper.findRfAdminA(repereFonctionnel).getResponsableRepere(); + } else { + return BOMLineHolderHelper.findRfAdmin(repereFonctionnel).getResponsableRepere(); + } + } + } catch (KurtException e) { + log.warn("Unable to find the correct RF Admins below Rf: " + repereFonctionnel.getSnecmaObject().getName(), e); + return EMPTY; + } + return EMPTY; + } + + @Override + public String getIDComponent() { + return EMPTY; + } + + @Override + public String getIDRevisionComponent() { + return EMPTY; + } + + @Override + public String getTypeReference() { + return EMPTY; + } + + @Override + public String getNameReference() { + return EMPTY; + } + + @Override + public String getReferenceConceptor() { + return EMPTY; + } + + @Override + public String getReferenceTransposed() { + return EMPTY; + } + + @Override + public String getReferenceAssociated() { + return EMPTY; + } + + @Override + public String getResponsableConception() { + return EMPTY; + } + + @Override + public String getArticleGestion() { + return EMPTY; + } + + @Override + public String getClassement() { + return EMPTY; + } + + @Override + public String getSuiviUtilisation() { + return EMPTY; + } + + @Override + public String getSuiviDureeVie() { + return EMPTY; + } + + @Override + public String[] getSuppliersList() { + return new String[0]; + } + + @Override + public String getALT() { + return EMPTY; + } + + @Override + public String getSB() { + return EMPTY; + } + + @Override + public String getQuantiteCumulee() { + return EMPTY; + } + + @Override + public String getPanachage() { + return EMPTY; + } + + @Override + public String getQuantite() { + return EMPTY; + } + + @Override + public String getSuiviMontage() { + return EMPTY; + } + + @Override + public Double getMass() { + return null; + } + + @Override + public String getMassUnit() { + return EMPTY; + } + + @Override + public String getMaquetteInterneExterne() { + try { + if (repereFonctionnel.getSnecmaObject().isRFGeneric()) { + return BOMLineHolderHelper.findRfAdmin(repereFonctionnel).getMaqIntExt(); + } else if (repereFonctionnel.getSnecmaObject().isRFPartOrPartAssemb()) { + if (SnecmaObjectTypes.RF_PART_ASSEMB_REVISION.equals(repereFonctionnel.getSnecmaObject().getType())) { + return EMPTY; + } else { + return BOMLineHolderHelper.findRfAdmin(repereFonctionnel).getMaqIntExt(); + } + } + } catch (KurtException e) { + log.warn("Unable to find the correct RF Admins below Rf: " + repereFonctionnel.getSnecmaObject().getName(), e); + return EMPTY; + } + return EMPTY; + } + + @Override + public String getDesignationENG() { + return EMPTY; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractTopLine.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractTopLine.java new file mode 100644 index 0000000..c7609e3 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/AbstractTopLine.java @@ -0,0 +1,223 @@ +package com.capgemini.reports.bomlineholder.flattener.line; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.generic.AbstractGenericRevision; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import lombok.Getter; + +/** + * Represents a top object. As a top object, it does not have a fater Receptor. + * + * @param a Transformer object producing results of type T + * @param the result of a transformation by object of type U + */ +@Getter +public abstract class AbstractTopLine implements SnecmaLine { + + private final BOMLineHolder bomLine; + private final ISnecmaObject bomLineObject; + private final int lineNumber; + + /** + * Builds a top Line form its {@link BOMLineHolder}. + * + * @param topBomLine a top {@link BOMLineHolder} + * @param lineNum the line number in the bom + */ + public AbstractTopLine(final BOMLineHolder topBomLine, final int lineNum) { + this.bomLine = topBomLine; + this.bomLineObject = topBomLine.getSnecmaObject(); + this.lineNumber = lineNum; + } + + @Override + public int compareTo(final SnecmaLine other) { + return getLineId().compareTo(other.getLineId()); + } + + @Override + public String toString() { + return "TopLine(Bom=" + bomLine.getUid() + ", obj=" + bomLineObject.getItemId() + ")"; + } + + @Override + public String getLineId() { + return bomLineObject.getItemId(); + } + + @Override + public String getIDReceptor() { + return StringHelper.EMPTY; + } + + @Override + public String getNameReceptor() { + return StringHelper.EMPTY; + } + + @Override + public String getRevisionReceptor() { + return StringHelper.EMPTY; + } + + @Override + public String getRepereName() { + return StringHelper.EMPTY; + } + + @Override + public String getRepereRevision() { + return StringHelper.EMPTY; + } + + @Override + public String getResponsableRepere() { + return StringHelper.EMPTY; + } + + @Override + public String getSuiviMontage() { + return StringHelper.EMPTY; + } + + @Override + public String getIDComponent() { + return bomLineObject.getItemId(); + } + + @Override + public String getIDRevisionComponent() { + return bomLineObject.getRevisionId(); + } + + @Override + public String getTypeReference() { + String typeReference; + if (bomLineObject.isPart()) { + typeReference = PartTypeExtractorHelper.extractType(bomLineObject); + } else if (bomLineObject.isProduct()) { + typeReference = "Produit"; + } else if (bomLineObject.isGeneric()) { + String type = bomLineObject.getType(); + if (SnecmaObjectTypes.GENERIC_REVISION.equals(type)) { + typeReference = "Générique"; + } else if (SnecmaObjectTypes.GENERIC_ASSEMB_REVISION.equals(type)) { + typeReference = "Générique Montage"; + } else { + typeReference = StringHelper.EMPTY; + } + } else { + typeReference = StringHelper.EMPTY; + } + return typeReference; + } + + @Override + public String getNameReference() { + return bomLineObject.getName(); + } + + @Override + public String getReferenceConceptor() { + return StringHelper.EMPTY; + } + + @Override + public String getReferenceTransposed() { + return StringHelper.EMPTY; + } + + @Override + public String getReferenceAssociated() { + return StringHelper.EMPTY; + } + + @Override + public String getResponsableConception() { + return StringHelper.EMPTY; + } + + @Override + public String getArticleGestion() { + return StringHelper.EMPTY; + } + + @Override + public String getClassement() { + return StringHelper.EMPTY; + } + + @Override + public String getSuiviUtilisation() { + return StringHelper.EMPTY; + } + + @Override + public String getSuiviDureeVie() { + return StringHelper.EMPTY; + } + + @Override + public String[] getSuppliersList() { + return new String[0]; + } + + @Override + public String getALT() { + return bomLine.getBomAlt(); + } + + @Override + public String getSB() { + return bomLine.getBomSb(); + } + + @Override + public String getQuantiteCumulee() { + return bomLine.getBomQtyCumul(); + } + + @Override + public String getPanachage() { + return bomLine.getBomPanache(); + } + + @Override + public String getQuantite() { + return bomLine.getBomQty(); + } + + @Override + public String getMaquetteInterneExterne() { + return StringHelper.EMPTY; + } + + @Override + public Double getMass() { + return null; + } + + @Override + public String getMassUnit() { + return StringHelper.EMPTY; + } + + @Override + public String getDesignationENG() { + String designation; + if (bomLineObject.isPart()) { + designation = ((AbstractPart) bomLineObject).getDesignationEN(); + } else if (bomLineObject.isGeneric()) { + designation = ((AbstractGenericRevision) bomLineObject).getDesignationEN(); + } else if (bomLineObject.isProduct()) { + designation = ((ProductRevision) bomLineObject).getDesignationEN(); + } else { + designation = StringHelper.EMPTY; + } + return designation; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/PartTypeExtractorHelper.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/PartTypeExtractorHelper.java new file mode 100644 index 0000000..92646ec --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/PartTypeExtractorHelper.java @@ -0,0 +1,71 @@ +package com.capgemini.reports.bomlineholder.flattener.line; + +import com.capgemini.framework.common.LanguageHelper; +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.part.*; +import lombok.extern.slf4j.Slf4j; + +/** + * Helps to extract the 'type' of a Part. + */ +@Slf4j +public final class PartTypeExtractorHelper { + + private static final String SLASH_SEPARATOR = " / "; + + private PartTypeExtractorHelper() { + // Nothing! + } + + /** + * Helps to extract the 'type' of a Part, sometimes by concatenating several fields.
    + * For instance, a Part Aero's type will be TypePartAero1, TypePartAero2, TypePartAero3 + * + * @param part a Part + * @return the type + */ + public static String extractType(final ISnecmaObject part) { + String thisType = part.getType(); + String returnContent; + if (SnecmaObjectTypes.ALTERNATE_REVISION.equals(thisType)) { + returnContent = extract((AlternateRevision) part); + } else if (SnecmaObjectTypes.DET_REVISION.equals(thisType)) { + returnContent = extract((DETRevision) part); + } else if (SnecmaObjectTypes.PART_AERO_REVISION.equals(thisType)) { + returnContent = extract((PartAeroRevision) part); + } else if (SnecmaObjectTypes.PART_NO_AERO_REVISION.equals(thisType)) { + returnContent = LanguageHelper.french(((PartNoAeroRevision) part).getTypeNoAero()); + } else if (SnecmaObjectTypes.PART_ASSEMB_REVISION.equals(thisType)) { + returnContent = extract((PartAssembRevision) part); + } else if (SnecmaObjectTypes.PART_MAT_REVISION.equals(thisType)) { + returnContent = "Matière"; + } else if (SnecmaObjectTypes.STANDARD_REVISION.equals(thisType)) { + returnContent = LanguageHelper.french(((StandardRevision) part).getTypeStandard()); + } else { + log.warn(StringHelper.concat("Could not extract Type from unsupported Part type: ", part.getItemId(), " of type ", thisType).toString()); + returnContent = ""; + } + return returnContent; + } + + private static String extract(final PartAssembRevision partAssemb) { + return StringHelper.implode(SLASH_SEPARATOR, LanguageHelper.french(partAssemb.getTypePartMontage1()), + LanguageHelper.french(partAssemb.getTypePartMontage2())); + } + + private static String extract(final PartAeroRevision partAero) { + return StringHelper.implode(SLASH_SEPARATOR, LanguageHelper.french(partAero.getTypeAero1()), LanguageHelper.french(partAero.getTypeAero2()), + LanguageHelper.french(partAero.getTypeAero3())); + } + + private static String extract(final DETRevision det) { + return StringHelper.implode(SLASH_SEPARATOR, LanguageHelper.french(det.getTypeDet1()), LanguageHelper.french(det.getTypeDet2())); + } + + private static String extract(final AlternateRevision alt) { + return StringHelper.implode(SLASH_SEPARATOR, LanguageHelper.french(alt.getTypeAlt1()), LanguageHelper.french(alt.getTypeAlt2())); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/SnecmaLine.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/SnecmaLine.java new file mode 100644 index 0000000..c7c9e78 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/flattener/line/SnecmaLine.java @@ -0,0 +1,241 @@ +package com.capgemini.reports.bomlineholder.flattener.line; + +import java.util.Map; + +/** + * Represents a set of objects having a strong Bom relationship.
    + * This interface is able to produce a result of type T from each type of line available.
    + * This interface extends {@link Comparable}, and by default uses the {@link SnecmaLine#getLineId() getLineId} method return value to compare, so a comparison whith an other line is a comparison of their nomenclature path, or structure. + * + * @param the type of result to be produced: a {@link Map}, a {@link String}... + * @param a Transformer object producing results of type T + */ +public interface SnecmaLine extends Comparable> { + + /** + * An Identifier for the line. Not unique.
    + * Identifies a the structure of this block of objects, for example by appending all their identifiers.
    + * Having the same getLineId is not like being equals, since some lesser important fields may be ignored during identifier creation.
    + * + * @return the Identifier, as a {@link String} + */ + String getLineId(); + + /** + * A counter for the line number in the nomenclature.
    + * + * @return the line number + */ + int getLineNumber(); + + /** + * The main method: produces a T object based on this line's properties. + * + * @param transformer the Transformer object + * @return the output object + */ + T transform(final U transformer); + + /** + * Get the ID of the line's receptor. + * + * @return ID receptor + */ + String getIDReceptor(); + + /** + * Get the receptor's name. + * + * @return receptor's name + */ + String getNameReceptor(); + + /** + * Get the receptor revision. + * + * @return receptor's revision + */ + String getRevisionReceptor(); + + /** + * Get the id of functional marker. + * + * @return ID Receptor Functional Marker + */ + String getRepereName(); + + /** + * Get the revision of functional marker. + * + * @return revision functional marker + */ + String getRepereRevision(); + + /** + * Get the object in charge marker. + * + * @return object in charge marker + */ + String getResponsableRepere(); + + /** + * Get suivi montage of marker. + * + * @return suivi montage of marker + */ + String getSuiviMontage(); + + /** + * Get ID component. + * + * @return ID component + */ + String getIDComponent(); + + /** + * Get ID Revision Component. + * + * @return ID Revision Component + */ + String getIDRevisionComponent(); + + /** + * Get type reference of the component. + * + * @return type reference of the component + */ + String getTypeReference(); + + /** + * Get reference name of component. + * + * @return reference name + */ + String getNameReference(); + + /** + * Get reference name of component, in English. + * + * @return reference name in english + */ + String getDesignationENG(); + + /** + * Get the reference conceptor. + * + * @return reference conceptor + */ + String getReferenceConceptor(); + + /** + * Get the reference transposed. + * + * @return the reference transposed + */ + String getReferenceTransposed(); + + /** + * Get the reference associated. + * + * @return reference associated + */ + String getReferenceAssociated(); + + /** + * Get the object in charge conception. + * + * @return responsable conception + */ + String getResponsableConception(); + + /** + * Get management's article. + * + * @return management's article + */ + String getArticleGestion(); + + /** + * Get classification. + * + * @return classification + */ + String getClassement(); + + /** + * Get use's following. + * + * @return use's following + */ + String getSuiviUtilisation(); + + /** + * Get lifetime's following. + * + * @return lifetime's following + */ + String getSuiviDureeVie(); + + /** + * Get list of suppliers. + * + * @return list of suppliers + */ + String[] getSuppliersList(); + + /** + * Get ALT. + * + * @return ALT + */ + String getALT(); + + /** + * Gett SB. + * + * @return SB + */ + String getSB(); + + /** + * Get quantity cumulated. + * + * @return quantity cumulated + */ + String getQuantiteCumulee(); + + /** + * Get panachage. + * + * @return panachage + */ + String getPanachage(); + + /** + * Get quantity. + * + * @return quantity + */ + String getQuantite(); + + /** + * Get maquette. + * + * @return maquette + */ + String getMaquetteInterneExterne(); + + /** + * Get Mass. + * + * @return mass + */ + Double getMass(); + + /** + * Get Mass Unit. + * + * @return mass unit + */ + String getMassUnit(); +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/processor/AltOrDetBehaviour.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/processor/AltOrDetBehaviour.java new file mode 100644 index 0000000..364c043 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/processor/AltOrDetBehaviour.java @@ -0,0 +1,48 @@ +package com.capgemini.reports.bomlineholder.processor; + +import com.capgemini.reports.snecmaobjects.part.AlternateRevision; +import com.capgemini.reports.snecmaobjects.part.DETRevision; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * This interface presents method for specifying a visitor's behaviour regarding {@link AlternateRevision} and {@link DETRevision} parts.
    + * Produces a {@link List} of {@link Map}s with specified Key and Value types. + * + * @param the Keys Type + * @param the Values Type + */ +public interface AltOrDetBehaviour extends Serializable { + + /** + * Tells the Visitor if the parts in the pseudo-folder of the provided ALt or DET should be visited. + * + * @return true if parts in the pseudo-folder of the provided ALt or DET should be visited. + */ + boolean shouldVisitPartsInPseudoFolder(); + + /** + * Tells the Visitor if the parts below the provided ALt or DET (as part of the usual nomenclature relationship) should be visited. + * + * @return true if parts in below the provided ALt or DET should be visited. + */ + boolean shouldVisitPartsBelowAlt(); + + /** + * Formats the line representing objects that are in the pseudo folder. + * + * @param map the map to fill + */ + void treatPartsInPseudoFolder(final Map map); + + + /** + * Formats the line representing objects that are directyl below an Alt or a Det. + * + * @param receptorMap the map to fill + */ + void treatAlternateOrDETAsReceptor(final Map receptorMap); + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/processor/DefaultAltOrDetBehaviour.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/processor/DefaultAltOrDetBehaviour.java new file mode 100644 index 0000000..08d54d7 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/processor/DefaultAltOrDetBehaviour.java @@ -0,0 +1,127 @@ +package com.capgemini.reports.bomlineholder.processor; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolder.BOMLineHolderState; +import com.capgemini.reports.exceptions.NotSupportedException; +import com.capgemini.reports.releasestatus.DefaultRevisionSelector; +import com.capgemini.reports.releasestatus.RevisionSelector; +import com.capgemini.reports.snecmaobjects.AbstractSnecmaObject; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.SnecmaObjectFactory; +import com.capgemini.reports.snecmaobjects.part.AbstractAltOrDetRevision; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import com.capgemini.reports.snecmaobjects.part.AlternateRevision; +import com.capgemini.reports.snecmaobjects.part.DETRevision; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; + +import java.util.*; + +/** + * This class does nothing specific with {@link AlternateRevision} or {@link DETRevision} parts.
    + * This class does provide some useful static methods like loading parts in pseudo folder, or obtaining the ItemRevision of an Alt or Det.
    + * Several methods should be overriden to do something useful on a as-needed basis, like: + *
      + *
    • {@link AltOrDetBehaviour#treatPartsInPseudoFolder(Map) fillRemainingFieldsOfPseudoFolder()}
    • + *
    • {@link AltOrDetBehaviour#treatAlternateOrDETAsReceptor(Map) treatAltOrDetReceptor()}
    • + *
    + * Can produce a {@link List} of {@link Map}s with specified Key and Value types. + * + * @param the Keys Type + * @param the Values Type + */ +@Slf4j +public class DefaultAltOrDetBehaviour implements AltOrDetBehaviour, IBOMLineHolderProcessor { + private static final long serialVersionUID = 9107530299095760608L; + + protected final transient TcSession session; + + private final RevisionSelector revisionSelector; + + /** + * Constructs a pseudo-folder loader. + * + * @param session an active {@link TcSession} + * @param date the limit date for revision's release date. + */ + public DefaultAltOrDetBehaviour(final TcSession session, final Calendar date) { + this.session = session; + this.revisionSelector = new DefaultRevisionSelector(date); + } + + @Override + public boolean shouldVisitPartsInPseudoFolder() { + return true; + } + + @Override + public boolean shouldVisitPartsBelowAlt() { + return true; + } + + @Override + public void treatPartsInPseudoFolder(final Map map) { + // Don't know what to do here, I'm just the default behaviour... maybe you want to override me and do something useful instead? + } + + @Override + public void treatAlternateOrDETAsReceptor(final Map receptorMap) { + // Don't know what to do here, I'm just the default behaviour... maybe you want to override me and do something useful instead? + } + + /** + * Processes the Pseudo-folder. Each {@link Item} in the pseudo-folder of the {@link BOMLineHolder} will load a corresponding {@link ItemRevision}.
    + * A purpose-built algorithm is provided for electing the 'correct' revision, which is then loaded in a {@link ISnecmaObject} back into the {@link BOMLineHolder} + * + * @param aBomLineHolder a {@link BOMLineHolder} to process + */ + @Override + public void process(final BOMLineHolder aBomLineHolder) { + ISnecmaObject snecmaObject = aBomLineHolder.getSnecmaObject(); + if (aBomLineHolder.getState() == BOMLineHolderState.PROCESSING && snecmaObject != null + && SnecmaObjectTypes.isAltOrDet(snecmaObject.getType())) { + + AbstractAltOrDetRevision altOrDetRevision = (AbstractAltOrDetRevision) snecmaObject; + // Select the revision of each Item + Map item2rev = selectAllRevisions(aBomLineHolder.getPseudoFolder()); + log.debug("Found a pseudo-Folder with {} parts in it. Found {} Revisions for them.", aBomLineHolder.getPseudoFolder().size(), + item2rev.size()); + + // Now build the Revision into a ISnecmaObject + altOrDetRevision.clearPseudoFolder(); + buildSnecmaObject(altOrDetRevision, item2rev.values()); + } + } + + protected Map selectAllRevisions(final List items) { + Map pseudoFolderRev = new HashMap<>(); + // This object has a pseudo-folder, let's find the correct revisions of its content + for (Item item : items) { + ItemRevision itemRev = revisionSelector.selectRevision(session, item).getItemRevision(); + pseudoFolderRev.put(item, itemRev); + } + return pseudoFolderRev; + } + + protected Map buildSnecmaObject(final AbstractAltOrDetRevision altOrDetRevision, + final Collection pseudoFolderRev) { + Map map = new HashMap<>(); + for (ItemRevision itemRev : pseudoFolderRev) { + try { + AbstractSnecmaObject objectInPF = SnecmaObjectFactory.build(session, itemRev); + if (objectInPF.isPart()) { + AbstractPart partInPF = (AbstractPart) objectInPF; + altOrDetRevision.addInPseudoFolder(partInPF); + map.put(itemRev, partInPF); + } + } catch (NotSupportedException e) { + log.error("Could not build one of ModelObjects from the Pseudo-folder of an Alt or Det", e); + } + } + return map; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/processor/IBOMLineHolderProcessor.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/processor/IBOMLineHolderProcessor.java new file mode 100644 index 0000000..81dcebb --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/processor/IBOMLineHolderProcessor.java @@ -0,0 +1,20 @@ +package com.capgemini.reports.bomlineholder.processor; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; + +import java.io.Serializable; + +/** + * Processes a {@link BOMLineHolder}, altering its content. + */ +public interface IBOMLineHolderProcessor extends Serializable { + + /** + * Unit element of work of the Processor.
    + * This method is called on each BomLineHolder if the {@link BOMLineHolder#process(IBOMLineHolderProcessor)} method is used on the Top BomLineHolder. + * + * @param aBomLineHolder + */ + void process(final BOMLineHolder aBomLineHolder); + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/visitor/AbstractBOMLineHolderVisitor.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/visitor/AbstractBOMLineHolderVisitor.java new file mode 100644 index 0000000..000a344 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/visitor/AbstractBOMLineHolderVisitor.java @@ -0,0 +1,597 @@ +package com.capgemini.reports.bomlineholder.visitor; + +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.processor.AltOrDetBehaviour; +import com.capgemini.reports.releasestatus.EffectivityBehaviourHelper; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.part.AbstractAltOrDetRevision; +import com.capgemini.reports.snecmaobjects.part.AlternateRevision; +import com.capgemini.reports.snecmaobjects.part.DETRevision; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +import java.util.*; + +/** + * Visit a {@link BOMLineHolder} tree.
    + * Produces a {@link List} of {@link Map}s with the provided Key and Value types.
    + * The behaviour of this generic visitor is specified by the constructor parameters. + * + * @param the Keys Type + * @param the Values Type + */ +@Getter +@EqualsAndHashCode +public abstract class AbstractBOMLineHolderVisitor implements IBOMLineHolderVisitor { + + private static final long serialVersionUID = 1362803093737028558L; + private static final String VISIT_BOM = "Visit {} Bom: {}"; + + // Sub-components that define the behaviour of this Visitor + protected final IReceptorVisitor> receptorVisitor; + protected final IComponentVisitor> componentVisitor; + /** + * This is the final list containing all entries. + */ + protected final List> theReportTable = new ArrayList<>(); + private final EffectivityBehaviourHelper effectivityBehaviour; + private final AltOrDetBehaviour altOrDetBehaviour; + private final boolean retrieveRepereReceptor; + private final boolean retrievePartNumberUnderRfGeneric; + private final boolean visitPartBelowPart; + + /** + * Constructor. + * + * @param receptorVisitor : specifies behaviour when visiting a Receptor {@link ISnecmaObject}. + * @param componentVisitor : specifies behaviour when visiting a Component {@link ISnecmaObject}. + * @param effectivityBehaviour : the behaviour regarding Effectivities + * @param altOrDetBehaviour : the behaviour regarding {@link AlternateRevision} or {@link DETRevision} parts. + * @param retrieveRepereReceptor boolean Take true if we retrieve the Repere Receptor properties. Else take false. + * @param retrievePartNumberUnderRfGeneric boolean Take true if we retrieve the Part number under the RF Generic. Take false else. + * @param visitPartBelowPart tells the Visitor weather it should visit a Part that is below another Part + */ + public AbstractBOMLineHolderVisitor(final IReceptorVisitor> receptorVisitor, final IComponentVisitor> componentVisitor, + final EffectivityBehaviourHelper effectivityBehaviour, final AltOrDetBehaviour altOrDetBehaviour, + final boolean retrieveRepereReceptor, final boolean retrievePartNumberUnderRfGeneric, final boolean visitPartBelowPart) { + this.receptorVisitor = receptorVisitor; + this.componentVisitor = componentVisitor; + this.effectivityBehaviour = effectivityBehaviour; + this.altOrDetBehaviour = altOrDetBehaviour; + this.retrieveRepereReceptor = retrieveRepereReceptor; + this.retrievePartNumberUnderRfGeneric = retrievePartNumberUnderRfGeneric; + this.visitPartBelowPart = visitPartBelowPart; + } + + /** + * Sort the children. + * + * @param bomHolder IBOMTree + */ + private static List sortBomChildren(final BOMLineHolder bomHolder) { + Collection childrenSet = bomHolder.getBomChilds(); + + // Convert array of elements to sort to a list + List sortedList = new ArrayList<>(childrenSet); + Collections.sort(sortedList, new Comparator() { + @Override + public int compare(final BOMLineHolder arg0, final BOMLineHolder arg1) { + ISnecmaObject snecmaObject0 = arg0.getSnecmaObject(); + String id0 = snecmaObject0 == null ? arg0.getKey() : snecmaObject0.getItemId(); + ISnecmaObject snecmaObject1 = arg1.getSnecmaObject(); + String id1 = snecmaObject1 == null ? arg1.getKey() : snecmaObject1.getItemId(); + return id0.compareTo(id1); + } + }); + return sortedList; + } + + /** + * Visit a Top BOMLineHolder and expand all the children to retrieve the properties. + */ + @Override + public List> visitTopReceptorBom(final BOMLineHolder aTopBomLine) { + // Create a Specific first line + visitSpecificFirstLine(aTopBomLine); + + // Analyze the type of the SnecmaObject and visit it in fonction of this type + analyzeAndVisitTopBom(aTopBomLine); + + return theReportTable; + } + + /** + * Visit a Top BOMLineHolder in fonction of his type. + * + * @param aTopBomLine BOMLineHolder + */ + private void analyzeAndVisitTopBom(final BOMLineHolder aTopBomLine) { + ISnecmaObject theSnecmaObject = aTopBomLine.getSnecmaObject(); + if (theSnecmaObject != null) { + if (theSnecmaObject.isGeneric() || theSnecmaObject.isProduct() || theSnecmaObject.isSuperModel()) { + visitGenericAsReceptor(aTopBomLine); + } + else if (theSnecmaObject.isPart()) { + visitPartAsReceptor(aTopBomLine, new HashMap()); + } + else if (theSnecmaObject.isRFPartOrPartAssemb()) { + visitRFBeforePart(aTopBomLine, new HashMap()); + } + else { + visitRFGenericAfterGenericReceptor(aTopBomLine, new HashMap()); + } + } + } + + /** + * Visit a Generic as a Receptor. + * + * @param aGenericReceptorBomLine BOMLineHolder + */ + private void visitGenericAsReceptor(final BOMLineHolder aGenericReceptorBomLine) { + Map theGenericReceptor = visitThisReceptor(aGenericReceptorBomLine); + + // Modify theGenericReceptor : Associate the generic with his RFGeneric + if (retrieveRepereReceptor) { + for (BOMLineHolder actualChildOfTopBom : sortBomChildren(aGenericReceptorBomLine)) { + if (actualChildOfTopBom.getSnecmaObject() == null) { + continue; + } + if (actualChildOfTopBom.getSnecmaObject().isRFGeneric()) { + visitRFGenericAfterGenericReceptor(actualChildOfTopBom, theGenericReceptor); + } + } + } + // Expand the children and use aGenericReceptorBomLine (Receptor + Repere properties) + for (BOMLineHolder actualChild : sortBomChildren(aGenericReceptorBomLine)) { + if (actualChild.getSnecmaObject() == null) { + continue; + } + if (actualChild.getSnecmaObject().isGeneric() || actualChild.getSnecmaObject().isSuperModel()) { + visitGenericAsComponent(actualChild, theGenericReceptor); + } + else if (actualChild.getSnecmaObject().isRFPartOrPartAssemb()) { + visitRFBeforePart(actualChild, theGenericReceptor); + } + else if (retrievePartNumberUnderRfGeneric && actualChild.getSnecmaObject().isRFGeneric()) { + visitRFGenericAndPartNumber(actualChild, theGenericReceptor); + } + else if (actualChild.getSnecmaObject().isSuperModel()){ + visitSuperModelAsComponent(actualChild, theGenericReceptor); + } + } + } + + /** + * Visit a Generic as a Component. + * + * @param aGenericComponentBomLine BOMLineHolder + * @param theGenericReceptor Map the map with the Generic Receptor and the RFGeneric Receptor properties + */ + private void visitGenericAsComponent(final BOMLineHolder aGenericComponentBomLine, final Map theGenericReceptor) { + // Retrieve the component properties + // May create an eventual receptor in specific reports + Map theGenericComponent = visitThisComponent(aGenericComponentBomLine); + + // Associate the generic with his RFGeneric + for (BOMLineHolder actualChildOfTopBom : sortBomChildren(aGenericComponentBomLine)) { + if (actualChildOfTopBom.getSnecmaObject() == null) { + continue; + } + if (actualChildOfTopBom.getSnecmaObject().isRFGeneric()) { + visitRFGenericAfterGenericComponent(actualChildOfTopBom, theGenericReceptor, theGenericComponent); + } + } + + // aGenericComponentBomLine may be a Receptor for his own children + if (!aGenericComponentBomLine.getBomChilds().isEmpty()) { + visitGenericAsReceptor(aGenericComponentBomLine); + } + } + + /** + * Visit a SuperModel as a Component. + * + * @param aSuperModelComponentBomLine BOMLineHolder + * @param theSuperModelReceptor Map the map with the SuperModel Receptor and the RFGeneric Receptor properties + */ + private void visitSuperModelAsComponent(final BOMLineHolder aSuperModelComponentBomLine, final Map theSuperModelReceptor) { + // Retrieve the component properties + // May create an eventual receptor in specific reports + Map theSuperModelComponent = visitThisComponent(aSuperModelComponentBomLine); + + // Associate the generic with his RFGeneric + for (BOMLineHolder actualChildOfTopBom : sortBomChildren(aSuperModelComponentBomLine)) { + if (actualChildOfTopBom.getSnecmaObject() == null) { + continue; + } + if (actualChildOfTopBom.getSnecmaObject().isRFGeneric()) { + visitRFGenericAfterGenericComponent(actualChildOfTopBom, theSuperModelReceptor, theSuperModelComponent); + } + } + + // aGenericComponentBomLine may be a Receptor for his own children + if (!aSuperModelComponentBomLine.getBomChilds().isEmpty()) { + visitGenericAsReceptor(aSuperModelComponentBomLine); + } + } + + + /** + * Visit a RFGeneric after a Generic Receptor (link Generic Receptor - RFGeneric Receptor). + * + * @param aRFGenericBomLine BOMLineHolder + * @param theGenericReceptor Map the map with the Generic Receptor properties + */ + private void visitRFGenericAfterGenericReceptor(final BOMLineHolder aRFGenericBomLine, final Map theGenericReceptor) { + mergeReceptorAndRepereReceptor(theGenericReceptor, getRFGenericForReceptor(aRFGenericBomLine)); + } + + /** + * Visit a RFGeneric after a Generic Component (link Generic Component - RFGeneric Component).
    + * A Generic Component is visited after a Generic Receptor and eventually a RFGeneric Receptor. + * + * @param aRFGenericBomLine BOMLineHolder + * @param theGenericReceptor Map the map with the Generic Receptor and RFGeneric Receptor properties + * @param theGenericComponent Map the map with the Generic Component properties + */ + private void visitRFGenericAfterGenericComponent(final BOMLineHolder aRFGenericBomLine, final Map theGenericReceptor, + final Map theGenericComponent) { + // Retrieve the Repere Component properties and merge it with the Component + mergeComponentAndRepereComponent(theGenericComponent, getRFGenericForComponent(aRFGenericBomLine)); + + // Add to report without modify the Receptor + addToReport(theGenericReceptor, theGenericComponent); + } + + /** + * Visit a RFGeneric and a Part number (Part Aero) (link Generic Receptor - RFGeneric - Part number Component).
    + * The RF Generic is before the Part number. + * + * @param aRFGenericBomLine BOMLineHolder + * @param theGenericReceptor Map the map with the Generic Receptor + */ + private void visitRFGenericAndPartNumber(final BOMLineHolder aRFGenericBomLine, final Map theGenericReceptor) { + Map theComponent = getRFGenericForComponent(aRFGenericBomLine); + for (BOMLineHolder actualChild : sortBomChildren(aRFGenericBomLine)) { + if (actualChild.getSnecmaObject() == null) { + continue; + } + if (actualChild.getSnecmaObject().isPart()) { + // Retrieve the Component properties and merge it with the Receptor properties + // Do not modify the Repere Component properties and the Receptor properties + mergeComponentAndRepereComponent(theComponent, visitThisComponent(actualChild)); + + // Add to the report without modify theReceptor + addToReport(theGenericReceptor, theComponent); + } + } + } + + /** + * Visit a RF (RFPart or RFPartAssemb only) before a Part Component (link RF Component - Part Component).
    + * The parameter should not be a RF Generic. + * + * @param aRFBomLine BOMLineHolder + * @param theReceptor Map the map with the Receptor and Repere properties.
    + * If the Receptor is a Generic : link GenericReceptor - RFGeneric Receptor.
    + * If the Receptor is a Part : link RF Receptor - Part Receptor. + */ + private void visitRFBeforePart(final BOMLineHolder aRFBomLine, final Map theReceptor) { + // Retrieve the Repere Component properties + Map theComponent = getTheRepereForComponent(aRFBomLine); + + // Prepare RF when the Part will become a Receptor + Map theFuturRepereReceptorForParts = new HashMap<>(); + if (retrieveRepereReceptor) { + theFuturRepereReceptorForParts = getTheRepereForReceptor(aRFBomLine); + } + + boolean doVisit = this.effectivityBehaviour.shouldVisit(aRFBomLine); + if (doVisit) { + for (BOMLineHolder actualChildOfRF : sortBomChildren(aRFBomLine)) { + if (actualChildOfRF.getSnecmaObject() == null) { + continue; + } + if (actualChildOfRF.getSnecmaObject().isPart()) { + visitPartAsComponent(actualChildOfRF, theReceptor, theComponent, theFuturRepereReceptorForParts); + } + } + } + } + + /** + * Visit a Part as Receptor (link RF Receptor - Part Receptor). + * + * @param aPartBomLine BOMLineHolder + * @param theRepereReceptor Map the map with the RF Receptor properties. + */ + private void visitPartAsReceptor(final BOMLineHolder aPartBomLine, final Map theRepereReceptor) { + // Retrieve the Part Receptor properties and do not modify it + Map thePartReceptor = visitThisReceptor(aPartBomLine); + String partType = aPartBomLine.getSnecmaObject().getType(); + if (SnecmaObjectTypes.isAltOrDet(partType)) { // Specific treatment of Alt or Det Receptor + altOrDetBehaviour.treatAlternateOrDETAsReceptor(thePartReceptor); + if (altOrDetBehaviour.shouldVisitPartsInPseudoFolder()) { + // Visit the pseudo-folder + visitPartsInPseudoFolder(aPartBomLine, thePartReceptor); + } + if (SnecmaObjectTypes.isAlt(partType)) { + visitPartReceptorChilds(aPartBomLine, theRepereReceptor, thePartReceptor, altOrDetBehaviour.shouldVisitPartsBelowAlt()); + } + } + else { + visitPartReceptorChilds(aPartBomLine, theRepereReceptor, thePartReceptor, visitPartBelowPart); + } + } + + private void visitPartReceptorChilds(final BOMLineHolder aPartBomLine, final Map theRepereReceptor, Map thePartReceptor, final boolean doVisitPartAsComponent) { + for (BOMLineHolder actualChildOfPart : sortBomChildren(aPartBomLine)) { + if (actualChildOfPart.getSnecmaObject() == null) { + continue; + } + // Handle Part children + if (actualChildOfPart.getSnecmaObject().isPart()) { + if (doVisitPartAsComponent) { + visitPartAsComponent(actualChildOfPart, thePartReceptor, receptorVisitor.emptyRf(), new HashMap()); + } + continue; + } + // Handle RF children + if (actualChildOfPart.getSnecmaObject().isRFPartOrPartAssemb()) { + // In order to mix Part Receptor and Repere Receptor without modify thePartReceptor + Map thePartReceptorWithRepereReceptor = new HashMap<>(); + thePartReceptorWithRepereReceptor.putAll(thePartReceptor); + mergeReceptorAndRepereReceptor(thePartReceptorWithRepereReceptor, theRepereReceptor); + + // To have the Repere Receptor properties + visitRFBeforePart(actualChildOfPart, thePartReceptorWithRepereReceptor); + } + } + } + + /** + * Visit a Part as Component (link RF Component - Part Component). + * + * @param aPartBomLine BOMLineHolder + * @param theReceptor Map the map with the Receptor and Repere properties.
    + * If the Receptor is a Generic : link GenericReceptor - RFGeneric Receptor.
    + * If the Receptor is a Part : link RF Receptor - Part Receptor. + * @param theRepereComponent Map the map with the RF Component properties + */ + private void visitPartAsComponent(final BOMLineHolder aPartBomLine, final Map theReceptor, final Map theRepereComponent, + final Map aFuturRepereReceptorForParts) { + // Visit this BomLineHolder, as a component + Map thePartComponent = visitThisComponent(aPartBomLine); + + // Retrieve the Component properties and merge it with the Receptor properties + // Do not modify the Repere Component properties and the Receptor properties + mergeComponentAndRepereComponent(thePartComponent, theRepereComponent); + + // Add to the report without modifying theReceptor + addToReport(theReceptor, thePartComponent); + + String fatherType = aPartBomLine.getSnecmaObject().getType(); + if (SnecmaObjectTypes.ALTERNATE_REVISION.equals(fatherType) || SnecmaObjectTypes.DET_REVISION.equals(fatherType)) { + if (altOrDetBehaviour.shouldVisitPartsBelowAlt()) { + visitPartAsReceptor(aPartBomLine, aFuturRepereReceptorForParts); + } + } + else { + // Continue the expansion for browsing Component children + visitPartAsReceptor(aPartBomLine, aFuturRepereReceptorForParts); + } + } + + /** + * Adds a line for each part in the pseudoFolder, including the provided receptor map in each line. + * + * @param fatherAltOrDetBomLine the Alt (or Det) whose pseudo-folder we must visit + */ + private void visitPartsInPseudoFolder(final BOMLineHolder fatherAltOrDetBomLine, final Map fatherAltOrDetAsReceptor) { + AbstractAltOrDetRevision iSnecmaObject = (AbstractAltOrDetRevision) fatherAltOrDetBomLine.getSnecmaObject(); + for (ISnecmaObject obj : iSnecmaObject.getPseudoFolder()) { + Map theLine = obj.accept(componentVisitor); + theLine.putAll(fatherAltOrDetAsReceptor); + altOrDetBehaviour.treatPartsInPseudoFolder(theLine); + theReportTable.add(theLine); + } + } + + /** + * Visit a BOMLineHolder's SnecmaObject using the {@link IReceptorVisitor}. + */ + protected abstract Map visitThisReceptor(final BOMLineHolder aBomLine); + + /** + * Visit a BOMLineHolder's SnecmaObject using the {@link IComponentVisitor}. + */ + protected abstract Map visitThisComponent(final BOMLineHolder aBomLine); + + /** + * Get the properties of a RFGeneric Receptor (link Generic Receptor - RFGeneric Receptor).
    + * Get the Admin properties on children in order to complete the RFGeneric properties. + * + * @param aRFGenericBomLine BOMLineHolder + * @return theRepere Map the RFGeneric Receptor properties + */ + private Map getRFGenericForReceptor(final BOMLineHolder aRFGenericBomLine) { + // Retrieve the Repere properties + Map theRepere = visitThisReceptor(aRFGenericBomLine); + + for (BOMLineHolder actualChildOfRF : sortBomChildren(aRFGenericBomLine)) { + // Sometimes the SnecmaObject in the BomLineholder may be null... + if (actualChildOfRF.getSnecmaObject() == null) { + continue; + } + + String childType = actualChildOfRF.getSnecmaObject().getType(); + // We are only concerned about the Admin children of this RF + if (!actualChildOfRF.getSnecmaObject().isAdmin()) { + continue; + } + + if (SnecmaObjectTypes.RF_ADMIN_REVISION.equals(childType) || SnecmaObjectTypes.RF_ADMIN_AG_REVISION.equals(childType)) { + mergeRepereReceptorandAdmin(theRepere, visitThisReceptor(actualChildOfRF)); + } + } + return theRepere; + } + + /** + * Get the properties of a RFGeneric Component (link Generic Component - RFGeneric Component).
    + * Get the Admin properties on children in order to complete the RFGeneric properties. + * + * @param aRFGenericBomLine BOMLineHolder + * @return theRepere Map the RFGeneric Component properties + */ + private Map getRFGenericForComponent(final BOMLineHolder aRFGenericBomLine) { + // Retrieve the Repere properties + Map theRepere = visitThisComponent(aRFGenericBomLine); + + for (BOMLineHolder actualChildOfRF : sortBomChildren(aRFGenericBomLine)) { + // Sometimes the SnecmaObject in the BomLineholder may be null... + if (actualChildOfRF.getSnecmaObject() == null) { + continue; + } + + String childType = actualChildOfRF.getSnecmaObject().getType(); + // We are only concerned about the Admin children of this RF + if (!actualChildOfRF.getSnecmaObject().isAdmin()) { + continue; + } + + if (SnecmaObjectTypes.RF_ADMIN_REVISION.equals(childType) || SnecmaObjectTypes.RF_ADMIN_AG_REVISION.equals(childType)) { + mergeRepereComponentandAdmin(theRepere, visitThisComponent(actualChildOfRF)); + } + } + return theRepere; + } + + /** + * Get the properties of a RF Receptor (except a RFGeneric) (link RF Receptor - Receptor).
    + * Get the Admin properties on children in order to complete the RF properties. + * + * @param aRFBomLine BOMLineHolder + * @return theRepere Map the RFGeneric Receptor properties + */ + private Map getTheRepereForReceptor(final BOMLineHolder aRFBomLine) { + // Retrieve the Repere properties + Map theRepere = visitThisReceptor(aRFBomLine); + + String parentRfType = aRFBomLine.getSnecmaObject().getType(); + for (BOMLineHolder actualChildOfRF : sortBomChildren(aRFBomLine)) { + // Sometimes the SnecmaObject in the BomLineholder may be null... + if (actualChildOfRF.getSnecmaObject() == null) { + continue; + } + + String childType = actualChildOfRF.getSnecmaObject().getType(); + // We are only concerned about the Admin children of this RF + if (!actualChildOfRF.getSnecmaObject().isAdmin()) { + continue; + } + + if (SnecmaObjectTypes.RF_PART_REVISION.equals(parentRfType)) { + if (SnecmaObjectTypes.RF_ADMIN_REVISION.equals(childType) || SnecmaObjectTypes.RF_ADMIN_AP_REVISION.equals(childType)) { + mergeRepereReceptorandAdmin(theRepere, visitThisReceptor(actualChildOfRF)); + } + } + else if (SnecmaObjectTypes.RF_PART_ASSEMB_REVISION.equals(parentRfType) + && SnecmaObjectTypes.RF_ADMIN_A_REVISION.equals(childType)) { + mergeRepereReceptorandAdmin(theRepere, visitThisReceptor(actualChildOfRF)); + } + } + return theRepere; + } + + /** + * Get the properties of a RF Component (except a RFGeneric) (link RF Component - Component).
    + * Get the Admin properties on children in order to complete the RF properties. + * + * @param aRFBomLine BOMLineHolder + * @return theRepere Map the RFGeneric Component properties + */ + private Map getTheRepereForComponent(final BOMLineHolder aRFBomLine) { + // Retrieve the Repere properties + Map theRepere = visitThisComponent(aRFBomLine); + + String parentRfType = aRFBomLine.getSnecmaObject().getType(); + for (BOMLineHolder actualChildOfRF : sortBomChildren(aRFBomLine)) { + // Sometimes the SnecmaObject in the BomLineholder may be null... + if (actualChildOfRF.getSnecmaObject() == null) { + continue; + } + + String childType = actualChildOfRF.getSnecmaObject().getType(); + // We are only concerned about the Admin children of this RF + if (!actualChildOfRF.getSnecmaObject().isAdmin()) { + continue; + } + + if (SnecmaObjectTypes.RF_PART_REVISION.equals(parentRfType)) { + if (SnecmaObjectTypes.RF_ADMIN_REVISION.equals(childType) || SnecmaObjectTypes.RF_ADMIN_AP_REVISION.equals(childType)) { + mergeRepereComponentandAdmin(theRepere, visitThisComponent(actualChildOfRF)); + } + } + else if (SnecmaObjectTypes.RF_PART_ASSEMB_REVISION.equals(parentRfType) + && SnecmaObjectTypes.RF_ADMIN_A_REVISION.equals(childType)) { + mergeRepereComponentandAdmin(theRepere, visitThisComponent(actualChildOfRF)); + } + } + return theRepere; + } + + /** + * Visit a specific first line if necessary for reports. + * + * @param bomHolder BOMLineHolder + */ + protected abstract void visitSpecificFirstLine(final BOMLineHolder bomHolder); + + /** + * Merge aReceptor and aRepereReceptor in aReceptor.
    + * Modify only aReceptor. + * + * @param aReceptor Map + * @param aRepereReceptor Map + */ + protected abstract void mergeReceptorAndRepereReceptor(final Map aReceptor, final Map aRepereReceptor); + + /** + * Merge aComponent and aRepereComponent and modify only aComponent.
    + * Modify only aComponent. + * + * @param aComponent Map + * @param aRepereComponent Map + */ + protected abstract void mergeComponentAndRepereComponent(final Map aComponent, final Map aRepereComponent); + + /** + * Merge aRepereReceptor and anAdmin and modify only aRepereReceptor. + * + * @param aRepereReceptor Map + * @param anAdmin Map + */ + protected abstract void mergeRepereReceptorandAdmin(final Map aRepereReceptor, final Map anAdmin); + + /** + * Merge aRepereComponent and anAdmin and modify only aRepereComponent. + * + * @param aRepereComponent Map + * @param anAdmin Map + */ + protected abstract void mergeRepereComponentandAdmin(final Map aRepereComponent, final Map anAdmin); + + /** + * Add aReceptor and aComponent to the R21 report.
    + * Do not modify aReceptor. + * + * @param aReceptor Map + */ + protected abstract void addToReport(final Map aReceptor, final Map aComponent); + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/visitor/BomLineBrowser.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/visitor/BomLineBrowser.java new file mode 100644 index 0000000..bae665d --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/visitor/BomLineBrowser.java @@ -0,0 +1,376 @@ +package com.capgemini.reports.bomlineholder.visitor; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderHelper; +import com.capgemini.reports.bomlineholder.ISnecmaLineProcessor; +import com.capgemini.reports.bomlineholder.flattener.line.SnecmaLine; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.MalformedNomenclatureException; +import com.capgemini.reports.filter.AllIsGoodFilter; +import com.capgemini.reports.filter.IFilterExplosionNomenclature; +import com.capgemini.reports.releasestatus.EffectivityBehaviourHelper; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.capgemini.reports.snecmaobjects.part.AbstractAltOrDetRevision; +import com.capgemini.reports.snecmaobjects.part.AbstractPart; +import com.capgemini.reports.snecmaobjects.part.AlternateRevision; +import com.capgemini.reports.snecmaobjects.part.DETRevision; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +/** + * Browse a {@link BOMLineHolder} tree, and presents methods for dealing with a coherent set of objects having a strong relationship in the Bom, like Generic-RfGeneric-PartAero.
    + * The various abstract methods each expose such coherent sets of objects, and are called in the browsing order. + */ +@Getter +@Setter +public class BomLineBrowser { + + // Sub-components that define the behaviour of this Visitor + private final EffectivityBehaviourHelper effectivityBehaviour; + private final boolean doRetrievePartNumberUnderRfGeneric; + private final boolean doVisitPartBelowPart; + private final boolean doVisitPartsInPseudoFolder; + + /** + * This filter can remove whole parts of the bom Tree. + */ + @Setter + private IFilterExplosionNomenclature filterNomenclature; + + /** + * This {@link ISnecmaLineProcessor} is called sequentially on all the {@link SnecmaLine}s of a receptor, BEFORE recursing. + */ + @Setter(value = AccessLevel.PROTECTED) + private ISnecmaLineProcessor preProcessor; + + /** + * This {@link ISnecmaLineProcessor} is eventually called on all the {@link SnecmaLine}s of a receptor, through depth-first recursion. + */ + @Setter(value = AccessLevel.PROTECTED) + private ISnecmaLineProcessor processor; + + /** + * Constructor. + * + * @param effectivityBehaviour : the behaviour regarding Effectivities + * @param visitPartsInPseudoFolder : the behaviour regarding pseudofolders of {@link AlternateRevision} or {@link DETRevision} parts. + * @param retrievePartNumberUnderRfGeneric boolean Take true if we retrieve the Part number under the RF Generic. Take false else. + * @param visitPartBelowPart tells the Visitor weather it should visit a Part that is below another Part + */ + public BomLineBrowser(final EffectivityBehaviourHelper effectivityBehaviour, final boolean visitPartsInPseudoFolder, + final boolean retrievePartNumberUnderRfGeneric, final boolean visitPartBelowPart) { + this.effectivityBehaviour = effectivityBehaviour; + this.doVisitPartsInPseudoFolder = visitPartsInPseudoFolder; + this.doRetrievePartNumberUnderRfGeneric = retrievePartNumberUnderRfGeneric; + this.doVisitPartBelowPart = visitPartBelowPart; + this.processor = new PassiveProcessor(); + this.filterNomenclature = new AllIsGoodFilter(); + } + + private static BOMLineHolder extractRfGeneric(final BOMLineHolder aGeneric) throws MalformedNomenclatureException { + try { + return BOMLineHolderHelper.findRfGenericBL(aGeneric); + } catch (InvalidInputException e) { + throw new MalformedNomenclatureException("No RF Generic found below a null Generic", e); + } + } + + /** + * Visit a Top BOMLineHolder and expand all the children to retrieve the properties. + */ + public void visitTopReceptorBom(final TcSession session, final BOMLineHolder aTopBomLine) throws MalformedNomenclatureException { + ISnecmaObject theSnecmaObject = aTopBomLine.getSnecmaObject(); + if (theSnecmaObject != null) { + processor.visitTopBom(aTopBomLine); + if (theSnecmaObject.isProduct()) { + visitProductAsReceptor(session, aTopBomLine); + } else if (theSnecmaObject.isGeneric()) { + visitGenericAsReceptor(session, aTopBomLine); + } else if (theSnecmaObject.isPart()) { + visitPartAsReceptor(session, aTopBomLine); + } else { + throw new MalformedNomenclatureException("Unupported bom: topLine " + aTopBomLine.getSnecmaObject().getItemId() + + " is not a Generic, a Product, or a Part. It is a " + aTopBomLine.getSnecmaObject().getType()); + } + } else { + throw new MalformedNomenclatureException("Empty top BomLine"); + } + } + + private void visitPartAsReceptor(final TcSession session, final BOMLineHolder aPart) { + if (preProcessor != null) { + for (BOMLineHolder child : aPart.getBomChilds()) { + if (filterNomenclature.isExcluded(session, child)) { + continue; + } + if (doVisitPartBelowPart && child.getSnecmaObject().isPart()) { + preProcessor.visitPartPart(aPart, child); // Non-recursive + } + if (child.getSnecmaObject().isRFPartOrPartAssemb()) { + preProcessor.visitReceptorRepere(session, aPart, child); + visitRfPartNoRec(session, aPart, child); + } + } + if (SnecmaObjectTypes.isAltOrDet(aPart.getSnecmaObject().getType()) && doVisitPartsInPseudoFolder) { // Specific treatment of Alt or Det Receptor + List pseudoFolder1 = ((AbstractAltOrDetRevision) aPart.getSnecmaObject()).getPseudoFolder(); + for (AbstractPart child : pseudoFolder1) { + if (!filterNomenclature.isExcluded(child)) { + // Visit the pseudo-folder + preProcessor.visitPartsInPseudoFolder(aPart, child); + } + } + } + } + + // There may be other children, like some Parts, RF Parts + for (BOMLineHolder child : aPart.getBomChilds()) { + if (filterNomenclature.isExcluded(session, child)) { + continue; + } + if (doVisitPartBelowPart && child.getSnecmaObject().isPart()) { + processor.visitPartPart(aPart, child); + visitPartAsReceptor(session, child); // Recursive + } + if (child.getSnecmaObject().isRFPartOrPartAssemb()) { + visitRfPart(session, aPart, child); + } + } + if (SnecmaObjectTypes.isAltOrDet(aPart.getSnecmaObject().getType()) && doVisitPartsInPseudoFolder) { // Specific treatment of Alt or Det Receptor + List pseudoFolder1 = ((AbstractAltOrDetRevision) aPart.getSnecmaObject()).getPseudoFolder(); + for (AbstractPart child : pseudoFolder1) { + if (!filterNomenclature.isExcluded(child)) { + processor.visitPartsInPseudoFolder(aPart, child); + } + } + } + } + + private void visitRfPartNoRec(final TcSession session, final BOMLineHolder aPart, final BOMLineHolder rfPart) { + boolean doVisit = this.effectivityBehaviour.shouldVisit(rfPart); + if (doVisit) { + boolean partFound = false; + for (BOMLineHolder child : rfPart.getBomChilds()) { + if (child.getSnecmaObject().isPart()) { + partFound = true; + if (filterNomenclature.isExcluded(session, child)) { + continue; + } + if (child.getSnecmaObject().isPart()) { + preProcessor.visitPartAsComponent(aPart, rfPart, child); + } + } + } + if (!partFound) { + preProcessor.visitReceptorWithoutComponent(aPart, rfPart); + } + } + } + + private void visitRfPart(final TcSession session, final BOMLineHolder aPart, final BOMLineHolder rfPart) { + boolean doVisit = this.effectivityBehaviour.shouldVisit(rfPart); + if (doVisit) { + processor.visitReceptorRepere(session, aPart, rfPart); + boolean partFound = false; + for (BOMLineHolder child : rfPart.getBomChilds()) { + if (child.getSnecmaObject().isPart()) { + partFound = true; + if (filterNomenclature.isExcluded(session, child)) { + continue; + } + processor.visitPartAsComponent(aPart, rfPart, child); + visitPartAsReceptor(session, child); + } + } + if (!partFound) { + processor.visitReceptorWithoutComponent(aPart, rfPart); + } + } + } + + private void visitProductAsReceptor(final TcSession session, final BOMLineHolder productReceptors) throws MalformedNomenclatureException { + if (preProcessor != null) { + for (BOMLineHolder child : productReceptors.getBomChilds()) { + if (child.getSnecmaObject().isGeneric() && !filterNomenclature.isExcluded(session, child) + && !filterNomenclature.isExcluded(session, productReceptors)) { + BOMLineHolder rfGenericComponent = extractRfGeneric(child); + preProcessor.visitProductGeneric(productReceptors, child, rfGenericComponent); + preProcessor.visitReceptorRepere(session, productReceptors, rfGenericComponent); // Receptor appears bundled with its component's repere + } + } + } + + // Recursive processing + for (BOMLineHolder child : productReceptors.getBomChilds()) { + if (child.getSnecmaObject().isGeneric() && !filterNomenclature.isExcluded(session, child) && !filterNomenclature.isExcluded(session, productReceptors)) { + // According to the MDD, there is one and only one RF Generic below any Generic. + BOMLineHolder rfGenericComponent = extractRfGeneric(child); + processor.visitProductGeneric(productReceptors, child, rfGenericComponent); + processor.visitReceptorRepere(session, productReceptors, rfGenericComponent); + // Now the component becomes receptor + visitGenericAsReceptor(session, child); + } + } + + } + + private void visitGenericAsReceptor(final TcSession session, final BOMLineHolder genericReceptor) throws MalformedNomenclatureException { + BOMLineHolder rfGeneric = extractRfGeneric(genericReceptor); + if (preProcessor != null) { + // Pre-processing + if (doRetrievePartNumberUnderRfGeneric) { + // Go ahead and extract the generic / Rf Generic / Part + visitRfGeneric(session, genericReceptor, rfGeneric, preProcessor); + } + // There may be other children, like some RF parts + for (BOMLineHolder child : genericReceptor.getBomChilds()) { + if (filterNomenclature.isExcluded(session, child)) { + continue; + } + if (child.getSnecmaObject().isRFPartOrPartAssemb()) { + visitRfPartAsComponentNoRec(session, genericReceptor, rfGeneric, child); + } else if (child.getSnecmaObject().isGeneric()) { + visitGenericAsComponentNoRec(session, genericReceptor, rfGeneric, child); + } + } + } + + // Recursive treatment now + if (doRetrievePartNumberUnderRfGeneric) { + // Go ahead and extract the generic / Rf Generic / Part + visitRfGeneric(session, genericReceptor, rfGeneric, processor); + } + + // There may be other children, like some RF parts + for (BOMLineHolder child : genericReceptor.getBomChilds()) { + if (filterNomenclature.isExcluded(session, child)) { + continue; + } + if (child.getSnecmaObject().isRFPartOrPartAssemb()) { + visitRfPartAsComponentRec(session, genericReceptor, rfGeneric, child); + } else if (child.getSnecmaObject().isGeneric()) { + BOMLineHolder rfGenericComponent = extractRfGeneric(child); + if (!filterNomenclature.isExcluded(session, rfGenericComponent)) { + processor.visitQuad(genericReceptor, rfGeneric, child, rfGenericComponent); + processor.visitReceptorRepere(session, genericReceptor, rfGenericComponent); + visitGenericAsReceptor(session, child); + } + } + } + } + + private void visitGenericAsComponentNoRec(final TcSession session, final BOMLineHolder genericReceptor, final BOMLineHolder rfGenericReceptor, + final BOMLineHolder genericComponent) throws MalformedNomenclatureException { + // According to the MDD, there is one and only one RF Generic below any Generic. + BOMLineHolder rfGenericComponent = extractRfGeneric(genericComponent); + if (!filterNomenclature.isExcluded(session, rfGenericComponent)) { + preProcessor.visitReceptorRepere(session, genericReceptor, rfGenericComponent); + preProcessor.visitQuad(genericReceptor, rfGenericReceptor, genericComponent, rfGenericComponent); + } + } + + private void visitRfPartAsComponentNoRec(final TcSession session, final BOMLineHolder receptor, final BOMLineHolder rfReceptor, final BOMLineHolder rfPart) { + if (effectivityBehaviour.shouldVisit(rfPart)) { + boolean partFound = false; + preProcessor.visitReceptorRepere(session, receptor, rfPart); + for (BOMLineHolder child : rfPart.getBomChilds()) { + if (child.getSnecmaObject().isPart()) { + if (!filterNomenclature.isExcluded(session, child)) { + preProcessor.visitQuad(receptor, rfReceptor, child, rfPart); + } + partFound = true; + } + } + if (!partFound) { + preProcessor.visitReceptorWithoutComponent(receptor, rfPart); + } + } + } + + private void visitRfPartAsComponentRec(final TcSession session, final BOMLineHolder receptor, final BOMLineHolder rfReceptor, final BOMLineHolder rfPart) { + if (effectivityBehaviour.shouldVisit(rfPart)) { + // Recursivity + boolean partFound = false; + processor.visitReceptorRepere(session, receptor, rfPart); + for (BOMLineHolder child : rfPart.getBomChilds()) { + if (child.getSnecmaObject().isPart()) { + if (!filterNomenclature.isExcluded(session, child)) { + processor.visitQuad(receptor, rfReceptor, child, rfPart); + visitPartAsReceptor(session, child); + } + partFound = true; + } + } + if (!partFound) { + processor.visitReceptorWithoutComponent(receptor, rfPart); + } + } + } + + // RF Generics have a single PartAero below them. Also below , RF Admin(s) carry data about this RfGeneric + private void visitRfGeneric(final TcSession session, final BOMLineHolder genericReceptor, final BOMLineHolder rfGeneric, final ISnecmaLineProcessor proc) + throws MalformedNomenclatureException { + for (BOMLineHolder child : rfGeneric.getBomChilds()) { + if (child.getSnecmaObject().isPart() && !filterNomenclature.isExcluded(session, child)) { + proc.visitPartNumber(genericReceptor, rfGeneric, child); + return; + } + } + throw new MalformedNomenclatureException("No part aero found below RfGeneric"); + } + + private static class PassiveProcessor implements ISnecmaLineProcessor { + + @Override + public void visitTopBom(final BOMLineHolder aTopBom) { + // Nothing to do + } + + @Override + public void visitQuad(final BOMLineHolder receptor, final BOMLineHolder rfReceptor, final BOMLineHolder component, + final BOMLineHolder rfComponent) { + // Nothing to do + } + + @Override + public void visitProductGeneric(final BOMLineHolder productReceptor, final BOMLineHolder genericComponent, + final BOMLineHolder rfGenericComponent) { + // Nothing to do + } + + @Override + public void visitPartNumber(final BOMLineHolder genericReceptor, final BOMLineHolder rfGeneric, final BOMLineHolder child) { + // Nothing to do + } + + @Override + public void visitPartAsComponent(final BOMLineHolder part, final BOMLineHolder rfPart, final BOMLineHolder child) { + // Nothing to do + } + + @Override + public void visitPartPart(final BOMLineHolder fatherPart, final BOMLineHolder childPart) { + // Nothing to do + } + + @Override + public void visitPartsInPseudoFolder(final BOMLineHolder aPart, final AbstractPart child) { + // Nothing to do + } + + @Override + public void visitReceptorWithoutComponent(final BOMLineHolder part, final BOMLineHolder rfPart) { + // Nothing to do + } + + @Override + public void visitReceptorRepere(TcSession session, final BOMLineHolder anObject, final BOMLineHolder aRF) { + // Nothing to do + } + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/visitor/IBOMLineHolderExtractor.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/visitor/IBOMLineHolderExtractor.java new file mode 100644 index 0000000..65e225a --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/visitor/IBOMLineHolderExtractor.java @@ -0,0 +1,23 @@ +package com.capgemini.reports.bomlineholder.visitor; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; + +import java.io.Serializable; + +/** + * Extractor of {@link BOMLineHolder} data. Can Extract objects to produce an output.
    + * Produces a custom T object. + * + * @param the output object Type + */ +public interface IBOMLineHolderExtractor extends Serializable { + + /** + * Visit the Top element of the Bom. + * + * @param aBomLineHolder + * @return the produced object (if any) + */ + T visitTopReceptorBom(final BOMLineHolder aBomLineHolder); + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/visitor/IBOMLineHolderVisitor.java b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/visitor/IBOMLineHolderVisitor.java new file mode 100644 index 0000000..e8075d1 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/bomlineholder/visitor/IBOMLineHolderVisitor.java @@ -0,0 +1,26 @@ +package com.capgemini.reports.bomlineholder.visitor; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; + +import java.util.List; +import java.util.Map; + +/** + * Visitor of {@link BOMLineHolder}.
    + * Produces a {@link List} of {@link Map}s with specified Key and Value types. + * + * @param the Keys Type + * @param the Values Type + */ +public interface IBOMLineHolderVisitor extends IBOMLineHolderExtractor>> { + + /** + * Visitor which can used the BOMLineHolder properties to make a chosen report. + * + * @param aBomLineHolder BOMLineHolder + * @return ArrayList> + */ + @Override + List> visitTopReceptorBom(final BOMLineHolder aBomLineHolder); + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/changeobjects/UnitRevision.java b/teamcenter/src/main/java/com/capgemini/reports/changeobjects/UnitRevision.java new file mode 100644 index 0000000..59be60d --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/changeobjects/UnitRevision.java @@ -0,0 +1,343 @@ +package com.capgemini.reports.changeobjects; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.object.pom.status.TcReleaseStatus; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.changeobjects.change.TcChangeRequestRevision; +import com.capgemini.reports.documentationobjects.DocTechnic; +import com.capgemini.reports.snecmaobjects.generic.AbstractGeneric; +import com.capgemini.reports.snecmaobjects.generic.Generic; +import com.capgemini.reports.snecmaobjects.generic.GenericAssemb; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.teamcenter.queries.saved.WorkflowOnUnitQuery; +import com.capgemini.reports.workflows.Task; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.*; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.*; +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.*; + +/** + * Class representing a Unit. + */ +@Slf4j +@EqualsAndHashCode +public class UnitRevision implements Serializable { + private static final long serialVersionUID = -1152481045274400434L; + + private static final String REGEX_DOCUMENT_DE_GEL_OR_FREEZE_DOCUMENT = "(.*\\bDocument de gel\\b.*)|(.*\\bFreeze document\\b.*)"; + private static final String TYPE_ITEM_REVISION = "ItemRevision"; + private static final String EMPTY_STRING = StringHelper.EMPTY; + + // Messages + private static final String MSG_NO_RELEASE_STATUS_FOUND = "No ReleaseStatus has been found on the unit revision {}"; + private static final String MSG_NO_GENERIC_FOUND = "No Generic has been found on the Unit revision {}"; + + private final TcSession session; + private final ItemRevision itemRevision; + + private UnitRevision(final TcSession session, final ItemRevision itemRevision) { + this.session = session; + this.itemRevision = itemRevision; + } + + + /** + * Build a UnitRevision.
    + */ + public static UnitRevision build(final TcSession session, final ItemRevision unitTc) { + return new UnitRevision(session, unitTc); + } + + /** + * Choose an appropriate revision of Unit in a list of units ({@link UnitRevision}) from a reference range.
    + * This list may be the list of built {@link UnitRevision} in a built {@link ProductRevision}.
    + * + * @param referenceRange String - the wanted range + * @param unitListinProduct List - the list of {@link UnitRevision} + * @param wantedStatus {@link StatusEnum} - all the wanted status + * @return the selected UnitRevision + */ + public static UnitRevision chooseRevisionOfUnitFromRange(final String referenceRange, final List unitListinProduct, + final StatusEnum... wantedStatus) { + // Obtain the list of all the UnitRevision with same range + List resultUnits = UnitRevision.getUnitRevisionWithSameRange(referenceRange, unitListinProduct); + if (resultUnits.size() == 1) { + return resultUnits.get(0); + } + + // Select A unit + return UnitRevision.getUnitRevisionFromStatusWithMostRecentReleaseDate(resultUnits, null, wantedStatus); + } + + /** + * Return all the {@link UnitRevision} with the same range as the reference parameter. + * + * @param referenceRange String - the reference range + * @param unitList List - the list of unit + * @return the list of UnitRevision with the same range + */ + private static List getUnitRevisionWithSameRange(final String referenceRange, final List unitList) { + List selectedUnits = new ArrayList<>(); + for (UnitRevision unitRev : unitList) { + if (referenceRange.equals(unitRev.getUnitRange())) { + selectedUnits.add(unitRev); + } + } + return selectedUnits; + } + + /** + * Return all the {@link ItemRevision} with the same range as the reference parameter. + * + * @param referenceRange String - the reference range + * @param unitList List - the list of unit + * @return the list of ItemRevision with the same range + */ + public static List getItemRevisionWithSameRange(final TcSession session, final String referenceRange, final List unitList) { + List selectedUnits = new ArrayList<>(); + for (ItemRevision unitRev : unitList) { + if (referenceRange.equals(getRangeOfItemRevision(session, unitRev))) { + selectedUnits.add(unitRev); + } + } + return selectedUnits; + } + + /** + * Get the range of a Unit ({@link ItemRevision}). + * + * @param unit {@link ItemRevision} - the entry unit + * @return unitRange String - the range of the unit. May be null. + */ + public static String getRangeOfItemRevision(final TcSession session, final ItemRevision unit) { + session.loadProperties(unit, "release_status_list"); + ReleaseStatus[] releaseStatuses = unit.get_release_status_list(); + session.loadProperties(releaseStatuses); + for (ReleaseStatus releaseStatus : releaseStatuses) { + if (SnecmaObjectTypes.EFFECTIVITY.equals(releaseStatus.get_name())) { + session.loadProperties(releaseStatus, "effectivities"); + ModelObject[] effectivities = releaseStatus.get_effectivities(); + session.loadProperties(effectivities); + if (effectivities.length == 0) { + log.error("ReleaseStatus named 'TcEffectivity' does not contain Effectivities..."); + } else { + ModelObject objectEffectivity = effectivities[0]; // There should only be one effectivity, we ignore the rest of the list's content + // Cast of the ModelObject to the TcEffectivity of Teamcenter, do not confuse with the TcEffectivity of this application + return ((Effectivity) objectEffectivity).get_unit_range_text(); + } + } + } + return null; + } + + /** + * Returns the {@link UnitRevision} whose {@link TcReleaseStatus} has the most recent release date, amongst the provided UnitRevision.
    + * + * @param unitRevisions the List of candidate {@link UnitRevision}s + * @param userDate the limit user date, only items released before that date will be examined + * @param wantedStatus {@link StatusEnum} - Enumeration of wanted status + * @return the most up-to-date UnitRevision + */ + private static UnitRevision getUnitRevisionFromStatusWithMostRecentReleaseDate(final List unitRevisions, final Calendar userDate, + final StatusEnum... wantedStatus) { + Calendar latestReleaseDate = null; + UnitRevision highestUnitRevision = null; + for (UnitRevision curUnitRevision : unitRevisions) { + // Get the TcReleaseStatus + List listReleaseStatus; + if (wantedStatus == null || wantedStatus.length == 0) { + listReleaseStatus = curUnitRevision.getReleaseStatusContainingMaturity(); + } else { + listReleaseStatus = TcReleaseStatus.filter(curUnitRevision.getReleaseStatusContainingMaturity(), wantedStatus); + } + + // Select the most recent + for (TcReleaseStatus status : listReleaseStatus) { + if (status != null) { + Calendar date = status.dateReleased(); + if (latestReleaseDate == null && safeBefore(userDate, date)) { + highestUnitRevision = curUnitRevision; + latestReleaseDate = date; + } else if (latestReleaseDate != null && latestReleaseDate.compareTo(date) < 0 && safeBefore(userDate, date)) { + highestUnitRevision = curUnitRevision; + latestReleaseDate = date; + } + } + } + } + return highestUnitRevision; + } + + private static boolean safeBefore(final Calendar userDate, final Calendar date) { + return userDate == null || date.before(userDate); + } + + public String getUid() { + return itemRevision.getUid(); + } + + public String getItemId() { + return itemRevision.get_item_id(); + } + + public String getRevision() { + return itemRevision.get_item_revision_id(); + } + + public String getName() { + return itemRevision.get_object_name(); + } + + public String getType() { + return itemRevision.getTypeObject().getName(); + } + + public boolean isExceptionnel() { + String unitExceptionnel = getMasterFormRev().getPropertyObject(PV_UNIT_EXCEPTIONNEL).getStringValue(); + return "Oui / Yes".equalsIgnoreCase(unitExceptionnel); + } + + public DocTechnic getTechnicalDocGel() { + session.loadProperties(itemRevision, PV_DELIVERABLES); + ModelObject[] documents = itemRevision.getPropertyObject(PV_DELIVERABLES).getModelObjectArrayValue(); + session.loadProperties(documents); + Calendar latestMod = null; + DocTechnic technicalDocGel = null; + for (ModelObject currentDoc : documents) { + ItemRevision docAsItemRev = (ItemRevision) currentDoc; + if (DOC_TECHNIC_REVISION.equals(docAsItemRev.getTypeObject().getName())) { + DocTechnic technicalDoc = new DocTechnic(session, docAsItemRev); + if (technicalDoc.getTypeDocTechnic1().matches(REGEX_DOCUMENT_DE_GEL_OR_FREEZE_DOCUMENT)) { + Calendar modDate = docAsItemRev.get_last_mod_date(); + if (latestMod == null || modDate.after(latestMod)) { + latestMod = modDate; + technicalDocGel = technicalDoc; + } + } + } + } + return technicalDocGel; + } + + private Form getMasterFormRev() { + Form masterTag = itemRevision.get_item_master_tag(); + session.loadProperties(masterTag); + return masterTag; + } + + /** + * Returns the Unit Range of a built UnitRevision.
    + * Obtained from the TcReleaseStatus named "TcEffectivity", who owns a (single) TcEffectivity, who owns the requested range. + * + * @return the unit Range + */ + public String getUnitRange() { + TcReleaseStatus tcReleaseStatuses = getReleaseStatusContaininEffectivity(); + if (tcReleaseStatuses == null || tcReleaseStatuses.getEffectivity() == null) { + return EMPTY_STRING; + } else { + return tcReleaseStatuses.getEffectivity().unitRange(); + } + } + + + public List getReleaseStatusContainingMaturity() { + List tcReleaseStatuses = new ArrayList<>(); + session.loadProperties(itemRevision, "release_status_list"); + ReleaseStatus[] releaseStatuses = itemRevision.get_release_status_list(); + session.loadProperties(releaseStatuses); + if (releaseStatuses.length == 0) { + log.debug(MSG_NO_RELEASE_STATUS_FOUND, itemRevision.get_item_id()); + } else { + for (ReleaseStatus status : releaseStatuses) { + TcReleaseStatus statusSnecma = new TcReleaseStatus(session, status); + if (!statusSnecma.isEffectivity()) { + tcReleaseStatuses.add(statusSnecma); + } + } + } + return tcReleaseStatuses; + } + + public TcReleaseStatus getReleaseStatusContaininEffectivity() { + session.loadProperties(itemRevision, "release_status_list"); + ReleaseStatus[] releaseStatuses = itemRevision.get_release_status_list(); + session.loadProperties(releaseStatuses); + if (releaseStatuses.length == 0) { + log.debug(MSG_NO_RELEASE_STATUS_FOUND, itemRevision.get_item_id()); + } else { + for (ReleaseStatus status : releaseStatuses) { + TcReleaseStatus statusSnecma = new TcReleaseStatus(session, status); + if (statusSnecma.isEffectivity()) { + return statusSnecma; + } + } + } + return null; + } + + + public List getGenerics() { + List tcGenerics = new ArrayList<>(); + session.loadProperties(itemRevision, PV_GENERIC); + ModelObject[] generics = itemRevision.getPropertyObject(PV_GENERIC).getModelObjectArrayValue(); + session.loadProperties(generics); + if (generics.length == 0) { + log.debug(MSG_NO_GENERIC_FOUND, itemRevision.get_item_id()); + } else { + for (ModelObject generic : generics) { + String objectType = generic.getTypeObject().getName(); + if (GENERIC.equals(objectType)) { + tcGenerics.add(new Generic(session, (Item) generic)); + } else if (GENERIC_ASSEMB.equals(objectType)) { + tcGenerics.add(new GenericAssemb(session, (Item) generic)); + } else { + log.warn("Obtained an objectType in the pseudofolder Generic of a Unit, which is not a Generic or Generic Assemb"); + } + } + } + + return tcGenerics; + } + + public List getChangeRequestsList() { + List changeRequestRevs = new ArrayList<>(); + session.loadProperties(itemRevision, PV_CHANGE_LIST); + ModelObject[] changes = itemRevision.getPropertyObject(PV_CHANGE_LIST).getModelObjectArrayValue(); + session.loadProperties(changes); + for (ModelObject currentChange : changes) { + ItemRevision changeAsItemRev = (ItemRevision) currentChange; + String changeType = changeAsItemRev.getTypeObject().getName(); + if (changeType != null && changeType.contains("PV4")) { // Filter the changes: we only want the new types of objects, whose names begin with 'PV4' + changeRequestRevs.add(new TcChangeRequestRevision(session, changeAsItemRev)); + } + } + + return changeRequestRevs; + } + + + public List getWorkflowsValidationUnitParSO() { + List tasks = new ArrayList<>(); + List result = WorkflowOnUnitQuery.searchValidationUnitParSO(session, getItemId()).findAll(); + for (EPMTask process : result) { + tasks.add(new Task(session, process)); + } + return tasks; + } + + @Override + public String toString() { + return getType() + " with ID= " + getItemId() + " REV= " + getRevision() + " RANGE= " + getUnitRange(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/changeobjects/change/AbstractChangeObject.java b/teamcenter/src/main/java/com/capgemini/reports/changeobjects/change/AbstractChangeObject.java new file mode 100644 index 0000000..fbba810 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/changeobjects/change/AbstractChangeObject.java @@ -0,0 +1,195 @@ +package com.capgemini.reports.changeobjects.change; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.pom.status.TcReleaseStatus; +import com.capgemini.reports.exceptions.NotSupportedException; +import com.capgemini.reports.snecmaobjects.SnecmaObjectFactory; +import com.capgemini.reports.snecmaobjects.generic.AbstractGeneric; +import com.capgemini.reports.teamcenter.queries.saved.WorkflowOnChangeQuery; +import com.capgemini.reports.users.SnecmaUser; +import com.capgemini.reports.workflows.Task; +import com.google.common.base.Joiner; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.*; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.util.*; + +import static com.capgemini.framework.teamcenter.TeamcenterObjectProperties.ITEM_ID; +import static com.capgemini.framework.teamcenter.TeamcenterObjectProperties.PROP_LIGNE_PRODUIT; +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.CM_HAS_SOLUTION_ITEM; +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.OBJECT_TYPE; +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.*; + +/** + * Abstract class representing a ChangeObject. + */ +@Slf4j +public abstract class AbstractChangeObject implements Serializable { + private static final long serialVersionUID = -133060583639527983L; + + protected final TcSession session; + protected final ItemRevision itemRevision; + protected SnecmaUser user; + + protected AbstractChangeObject(final TcSession session, final ItemRevision itemRevision) { + this.session = session; + this.itemRevision = itemRevision; + } + + private static Item obtainItem(final TcSession session, final ModelObject currentObject) throws NotSupportedException { + Item item; + if (currentObject instanceof Item) { + // Normal behavior: master in the pseudo-folder + item = (Item) currentObject; + } else if (currentObject instanceof ItemRevision) { + // There might still be ItemRevisions here! We must try to findAll their Item, and pursue + ItemRevision tempRev = (ItemRevision) currentObject; + session.loadProperties(tempRev, "items_tag"); + item = tempRev.get_items_tag(); + session.loadProperties(item); + } else { + throw new NotSupportedException("Found a {} (with UID = {}) in the pseudo-folder. Not supported object, skipping..."); + } + return item; + + } + + public String getItemId() { + return itemRevision.get_item_id(); + } + + public String getRevisionId() { + return itemRevision.get_item_revision_id(); + } + + public int getSequenceId() { + return itemRevision.get_sequence_id(); + } + + public String getChangeName() { + return itemRevision.get_object_name(); + } + + public Calendar getDateCreation() { + return itemRevision.get_creation_date(); + } + + public String getChangeType() { + return itemRevision.getTypeObject().getName(); + } + + public SnecmaUser getUser() { + session.loadProperties(itemRevision, "owning_user"); + User owningUser = (User) itemRevision.get_owning_user(); + session.loadProperties(owningUser); + return new SnecmaUser(session, owningUser); + } + + public List getLignesProduit() { + List lineList = new ArrayList<>(); + Collections.addAll(lineList, itemRevision.getPropertyObject(PROP_LIGNE_PRODUIT).getStringArrayValue()); + return lineList; + } + + public List getReleaseStatusContainingEffectivity() { + List releaseStatusContainingEffectivity = new ArrayList<>(); + session.loadProperties(itemRevision, "release_status_list"); + ReleaseStatus[] releaseStatuses = itemRevision.get_release_status_list(); + session.loadProperties(releaseStatuses); + for (ReleaseStatus status : releaseStatuses) { + TcReleaseStatus statusSnecma = new TcReleaseStatus(session, status); + if (statusSnecma.isEffectivity()) { + releaseStatusContainingEffectivity.add(statusSnecma); + } + } + return releaseStatusContainingEffectivity; + } + + + public List getReleaseStatusContainingMaturity() { + List releaseStatusContainingMaturity = new ArrayList<>(); + session.loadProperties(itemRevision, "release_status_list"); + ReleaseStatus[] releaseStatuses = itemRevision.get_release_status_list(); + session.loadProperties(releaseStatuses); + for (ReleaseStatus status : releaseStatuses) { + TcReleaseStatus statusSnecma = new TcReleaseStatus(session, status); + if (statusSnecma.isChangeMaturity()) { + releaseStatusContainingMaturity.add(statusSnecma); + } + } + return releaseStatusContainingMaturity; + } + + /** + * Set the list of all Workflows associated to this change. + */ + public List getWkfList() { + List result = new WorkflowOnChangeQuery(session).searchIDAndRevision(this.getItemId(), this.getRevisionId()).searchSequenceId(String.valueOf(getSequenceId())).findAll(); + List taskList = new ArrayList<>(); + for (EPMTask task : result) { + taskList.add(new Task(session, task)); + } + return taskList; + } + + /** + * Get the list of the generic 'with/without rupture of interchangeabiliy' from an ItemRevision representing a ChangeNotice/Request. + */ + AbstractGeneric loadGeneric(final ModelObject genericObject) throws NotSupportedException { + return SnecmaObjectFactory.build(session, obtainItem(session, genericObject)); + } + + @Override + public String toString() { + return this.getChangeType() + " " + this.getItemId() + "/" + this.getRevisionId(); + } + + /** + * Method to get Parts from CR/CN or FPP inside the apres pseudo folder + * If input param is not null it gets the apres pseudo folder of this ModelObject (case of a FPP) + * If it is null it gets the apres pseudo folder of itemRevision attribute of the current instance (Case of CR/CN) + * + * @param object, ModelObject where the apres pseudo folder is + * @return Set + */ + public Set getPartsFromApresPseudoFolder(ModelObject object) { + List apresPseudoFolderContent; + + // sous modification pseudo folder for fpp + if (object != null) { + session.loadProperties(object, CM_HAS_SOLUTION_ITEM); + apresPseudoFolderContent = object.getPropertyObject(CM_HAS_SOLUTION_ITEM).getModelObjectListValue(); + } else { + // for cr/cn + session.loadProperties(itemRevision, CM_HAS_SOLUTION_ITEM); + apresPseudoFolderContent = itemRevision.getPropertyObject(CM_HAS_SOLUTION_ITEM).getModelObjectListValue(); + } + Set result = new HashSet<>(); + for (ModelObject part : apresPseudoFolderContent) { + // get parts type + session.loadProperties(part, OBJECT_TYPE, ITEM_ID); + String part_type = part.getPropertyObject(OBJECT_TYPE).getStringValue(); + if (PART_AERO_REVISION.equals(part_type) || PART_NO_AERO_REVISION.equals(part_type) || STANDARD_REVISION.equals(part_type) || DET_REVISION.equals(part_type) || PART_MAT_REVISION.equals(part_type) || ALTERNATE_REVISION.equals(part_type) || PART_ASSEMB_REVISION.equals(part_type)) { + result.add(part); + } + } + return result; + } + + /** + * Return a String with all itemsID of the modelObjects in the set separated by ; + * + * @param set + * @return String + */ + public static String getItemIdFromModelObjectSetToString(Set set) { + Set result = new HashSet<>(); + for (ModelObject model : set) { + result.add(model.getPropertyObject(ITEM_ID).getStringValue()); + } + return Joiner.on(";").join(result); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/changeobjects/change/FPPRevision.java b/teamcenter/src/main/java/com/capgemini/reports/changeobjects/change/FPPRevision.java new file mode 100644 index 0000000..e955e33 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/changeobjects/change/FPPRevision.java @@ -0,0 +1,41 @@ +package com.capgemini.reports.changeobjects.change; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.*; + +/** + * Class representing a TC FPP Revision. + */ +public class FPPRevision extends AbstractChangeObject { + private static final long serialVersionUID = 2601916478580482L; + + public FPPRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public String getOrigineDemande() { + return itemRevision.getPropertyObject(PV_ORIGINE_DEMANDE).getStringValue(); + } + + /** + * Method to get Parts inside the apres pseudo folder inside each mod of the sous-modifications pseudo folder + * + * @return List + */ + public Set getPartsOfSubModifications() { + Set result = new HashSet<>(); + session.loadProperties(itemRevision, CM_IMPLEMENTED_BY); + List sousModificationsPseudoFolderContent = itemRevision.getPropertyObject(CM_IMPLEMENTED_BY).getModelObjectListValue(); + for (ModelObject mod : sousModificationsPseudoFolderContent) { + result.addAll(getPartsFromApresPseudoFolder(mod)); + } + return result; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/changeobjects/change/TcChangeNoticeRevision.java b/teamcenter/src/main/java/com/capgemini/reports/changeobjects/change/TcChangeNoticeRevision.java new file mode 100644 index 0000000..aedba88 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/changeobjects/change/TcChangeNoticeRevision.java @@ -0,0 +1,121 @@ +package com.capgemini.reports.changeobjects.change; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.exceptions.NotSupportedException; +import com.capgemini.reports.snecmaobjects.generic.AbstractGeneric; +import com.capgemini.reports.teamcenter.queries.saved.WorkflowOnChangeQuery; +import com.capgemini.reports.workflows.Task; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.EPMTask; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +import static com.capgemini.framework.teamcenter.TeamcenterObjectTypes.CHANGE_REQUEST_REVISION; +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.*; + +/** + * Class representing a modification of a Unit. + */ +@Slf4j +public class TcChangeNoticeRevision extends AbstractChangeObject { + private static final long serialVersionUID = -8781834231342513659L; + + private static final Pattern ETUDE_STUDY = Pattern.compile(".*(Etude|Study).*"); + + public TcChangeNoticeRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public String getTypeModification() { + return itemRevision.getPropertyObject(PV4_TYPE_MODIFICATION).getDisplayableValue(); + } + + @Override + public List getWkfList() { + List tasks = new ArrayList<>(); + for (EPMTask epmTask : new WorkflowOnChangeQuery(session).searchIDAndRevision(getItemId(), getRevisionId()).searchSequenceId(String.valueOf(getSequenceId())).findAll()) { + if (!Task.TaskState.COMPLETED.equals(Task.TaskState.findState(epmTask.get_state()))) { + tasks.add(new Task(session, epmTask)); + } + } + return tasks; + } + + /** + * Returns true if this generic's type is {@code Etude / Study}. + * + * @return true or false + */ + public boolean isEtude() { + return ETUDE_STUDY.matcher(getTypeModification()).matches(); + } + + public List getImplementsCR() { + List implementsCR = new ArrayList<>(); + session.loadProperties(itemRevision, CM_IMPLEMENTS); + ModelObject[] changes = itemRevision.getPropertyObject(CM_IMPLEMENTS).getModelObjectArrayValue(); + session.loadProperties(changes); + for (ModelObject change : changes) { + if (!SnecmaObjectTypes.isRecursively(CHANGE_REQUEST_REVISION, change.getTypeObject())) { + log.warn("Found a {} object in the '{}' pseudo-folder of ChangeNotice {}, expecting only ChangeRequests. Skipping...", + change.getTypeObject().getName(), CM_IMPLEMENTS, getItemId()); + continue; + } + + implementsCR.add(new TcChangeRequestRevision(session, (ItemRevision) change)); + } + return implementsCR; + } + + public List getListOfGenericRevWithOrWithoutRupture() { + List generics = new ArrayList<>(); + List genericsObjects = new ArrayList<>(); + session.loadProperties(itemRevision, PV_IMP_GENERICS_WITH_INTER, PV_IMP_GENERICS_WITHOUT_INTER); + genericsObjects.addAll(itemRevision.getPropertyObject(PV_IMP_GENERICS_WITH_INTER).getModelObjectListValue()); + genericsObjects.addAll(itemRevision.getPropertyObject(PV_IMP_GENERICS_WITHOUT_INTER).getModelObjectListValue()); + session.loadProperties(genericsObjects.toArray(new ModelObject[genericsObjects.size()])); + for (ModelObject genericsObject : genericsObjects) { + try { + generics.add(loadGeneric(genericsObject)); + } catch (NotSupportedException e) { + log.warn("Unsupported object {} found in pseudo-folder {} or {}", genericsObject.getUid(), PV_IMP_GENERICS_WITH_INTER, PV_IMP_GENERICS_WITHOUT_INTER); + } + } + return generics; + } + + public List getListOfGenericRevWithRupture() { + List generics = new ArrayList<>(); + session.loadProperties(itemRevision, PV_IMP_GENERICS_WITH_INTER); + ModelObject[] genericsObjects = itemRevision.getPropertyObject(PV_IMP_GENERICS_WITH_INTER).getModelObjectArrayValue(); + session.loadProperties(genericsObjects); + for (ModelObject genericsObject : genericsObjects) { + try { + generics.add(loadGeneric(genericsObject)); + } catch (NotSupportedException e) { + log.warn("Unsupported object {} found in pseudo-folder {} or {}", genericsObject.getUid(), PV_IMP_GENERICS_WITH_INTER, PV_IMP_GENERICS_WITHOUT_INTER); + } + } + return generics; + } + + public List getListOfGenericRevWithoutRupture() { + List generics = new ArrayList<>(); + session.loadProperties(itemRevision, PV_IMP_GENERICS_WITHOUT_INTER); + ModelObject[] genericsObjects = itemRevision.getPropertyObject(PV_IMP_GENERICS_WITHOUT_INTER).getModelObjectArrayValue(); + session.loadProperties(genericsObjects); + for (ModelObject genericsObject : genericsObjects) { + try { + generics.add(loadGeneric(genericsObject)); + } catch (NotSupportedException e) { + log.warn("Unsupported object {} found in pseudo-folder {}", genericsObject.getUid(), PV_IMP_GENERICS_WITHOUT_INTER); + } + } + return generics; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/changeobjects/change/TcChangeRequestRevision.java b/teamcenter/src/main/java/com/capgemini/reports/changeobjects/change/TcChangeRequestRevision.java new file mode 100644 index 0000000..19578d9 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/changeobjects/change/TcChangeRequestRevision.java @@ -0,0 +1,114 @@ +package com.capgemini.reports.changeobjects.change; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum.AbstractStatusFilter; +import com.capgemini.framework.teamcenter.object.pom.status.TcReleaseStatus; +import com.capgemini.framework.teamcenter.resolution.filtering.TcTypeExclusionFilter; +import com.capgemini.reports.exceptions.NotSupportedException; +import com.capgemini.reports.snecmaobjects.generic.AbstractGeneric; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.*; +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.*; + +/** + * Class representing a modification. + */ +@Slf4j +public class TcChangeRequestRevision extends AbstractChangeObject { + private static final long serialVersionUID = -2682203641880659660L; + + public TcChangeRequestRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public List getFppList() { + session.loadProperties(itemRevision, CM_IMPLEMENTS); + ModelObject[] implementsObjects = itemRevision.getPropertyObject(CM_IMPLEMENTS).getModelObjectArrayValue(); + session.loadProperties(implementsObjects); + List fppRevisions = new ArrayList<>(); + for (ModelObject implementsObject : implementsObjects) { + fppRevisions.add(new FPPRevision(session, (ItemRevision) implementsObject)); + } + return fppRevisions; + } + + /** + * Returns true if this CR is a CAD, DCAD, or MACE (actually, {@code PV4_CAD_ACRRevision}, {@code PV4_DCADRevision}, {@code PV4_MACERevision}). + * + * @return true if this CR is a CAD, DCAD, or MACE + */ + public boolean isCadOrDCadOrMace() { + String changeType = getChangeType(); + return PV4_CAD_ACR_REVISION.equals(changeType) || PV4_DCAD_REVISION.equals(changeType) || PV4_MACE_REVISION.equals(changeType); + } + + + public List getChangeNoticesList() { + List changeNotices = new ArrayList<>(); + session.loadProperties(itemRevision, CM_IMPLEMENTED_BY); + ModelObject[] objects = itemRevision.getPropertyObject(CM_IMPLEMENTED_BY).getModelObjectArrayValue(); + session.loadProperties(objects); + for (ModelObject currentObject : objects) { + changeNotices.add(new TcChangeNoticeRevision(session, (ItemRevision) currentObject)); + } + return changeNotices; + } + + public List getChangeNoticesList(final TcTypeExclusionFilter typeExlusionFilter, final AbstractStatusFilter statusExclusionFilter) { + List changeNotices = new ArrayList<>(); + for (TcChangeNoticeRevision changeNotice : getChangeNoticesList()) { + if (typeExlusionFilter.isIncluded(changeNotice.getChangeType()) && !hasExcludeStatuses(statusExclusionFilter, changeNotice)) { + changeNotices.add(changeNotice); + } + } + return changeNotices; + } + + private boolean hasExcludeStatuses(AbstractStatusFilter statusExclusionFilter, TcChangeNoticeRevision changeNotice) { + for (TcReleaseStatus status : changeNotice.getReleaseStatusContainingMaturity()) { + if (statusExclusionFilter.isExcluded(status)) { + return true; + } + } + return false; + } + + public String getTypeModSupportProcess() { + return itemRevision.getPropertyObject(PV4_TYPE_MODIFICATION).getDisplayableValue(); + } + + public List getListOfGenericRevWithOrWithoutRupture() { + List generics = new ArrayList<>(); + List genericsObjects = new ArrayList<>(); + session.loadProperties(itemRevision, PV_IMP_GENERICS_WITH_INTER, PV_IMP_GENERICS_WITHOUT_INTER); + genericsObjects.addAll(itemRevision.getPropertyObject(PV_IMP_GENERICS_WITH_INTER).getModelObjectListValue()); + genericsObjects.addAll(itemRevision.getPropertyObject(PV_IMP_GENERICS_WITHOUT_INTER).getModelObjectListValue()); + session.loadProperties(genericsObjects.toArray(new ModelObject[genericsObjects.size()])); + for (ModelObject genericsObject : genericsObjects) { + try { + generics.add(loadGeneric(genericsObject)); + } catch (NotSupportedException e) { + log.warn("Unsupported object {} found in pseudo-folder {} or {}", genericsObject.getUid(), PV_IMP_GENERICS_WITH_INTER, PV_IMP_GENERICS_WITHOUT_INTER); + } + } + return generics; + } + + public String getApprobationSO() { + session.loadProperties(itemRevision, PV_EXTERNAL_APPROBATION); + ModelObject[] approbationSOarray = itemRevision.getPropertyObject(PV_EXTERNAL_APPROBATION).getModelObjectArrayValue(); + session.loadProperties(approbationSOarray); + for (ModelObject model : approbationSOarray) { + if (APPROBATION_SO.equals(model.getTypeObject().getName())) { + return model.getPropertyObject(PV_NUMERO_APPROBATION).getStringValue(); + } + } + return null; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/AbstractDoc.java b/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/AbstractDoc.java new file mode 100644 index 0000000..b9a0065 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/AbstractDoc.java @@ -0,0 +1,113 @@ +package com.capgemini.reports.documentationobjects; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.pom.status.TcReleaseStatus; +import com.teamcenter.soa.client.model.strong.Form; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.ReleaseStatus; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.NIVEAU_SENSIBILITE; + +/** + * Abstract class for all objects of type Document. Contains Id, Revision, Name and Type. + */ +public abstract class AbstractDoc implements Serializable { + private static final long serialVersionUID = -3082137888946282380L; + protected final ItemRevision itemRevision; + protected final TcSession session; + + private List statuses; + private Form masterFormRev; + + public AbstractDoc(final TcSession session, final ItemRevision itemRevision) { + this.session = session; + this.itemRevision = itemRevision; + } + + public String getUid() { + return itemRevision.getUid(); + } + + public String getType() { + return itemRevision.getTypeObject().getName(); + } + + public String getDocId() { + return itemRevision.get_item_id(); + } + + public String getRevision() { + return itemRevision.get_item_revision_id(); + } + + public String getName() { + return itemRevision.get_object_name(); + } + + public Calendar getDateCreation() { + return itemRevision.get_creation_date(); + } + + public Item getItem() { + session.loadProperties(itemRevision, "items_tag"); + Item item = itemRevision.get_items_tag(); + session.loadProperties(item); + return item; + } + + + public Form getMasterForm() { + Item item = getItem(); + session.loadProperties(item, "item_master_tag"); + Form masterTag = item.get_item_master_tag(); + session.loadProperties(masterTag); + return masterTag; + } + + public Form getMasterFormRev() { + if (masterFormRev == null) { + masterFormRev = itemRevision.get_item_master_tag(); + session.loadProperties(masterFormRev); + } + return masterFormRev; + } + + public List getStatus() { + if (statuses == null) { + statuses = new ArrayList<>(); + session.loadProperties(itemRevision, "release_status_list"); + ReleaseStatus[] releaseStatuses = itemRevision.get_release_status_list(); + session.loadProperties(releaseStatuses); + for (ReleaseStatus releaseStatus : releaseStatuses) { + TcReleaseStatus tcReleaseStatus = new TcReleaseStatus(session, releaseStatus); + statuses.add(tcReleaseStatus); + } + } + return statuses; + } + + public String getNiveauSensibilite() { + session.loadProperties(itemRevision, NIVEAU_SENSIBILITE); + return itemRevision.getPropertyObject(NIVEAU_SENSIBILITE).getStringValue(); + } + + @Override + public String toString() { + return this.getType() + " " + this.getDocId() + "/" + this.getRevision(); + } + + /** + * Visitor method. + * + * @param docVisitor a {@link IDocVisitor} + * @param anything you may want to return from your visit + * @return the outcome of the visit + */ + public abstract T accept(final IDocVisitor docVisitor); +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/DocDrawing.java b/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/DocDrawing.java new file mode 100644 index 0000000..a750b5a --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/DocDrawing.java @@ -0,0 +1,32 @@ +package com.capgemini.reports.documentationobjects; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_DESIGNATION_EN; +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_INDICE_PLAN; + +/** + * Class representing a DocDrawing. + */ +public class DocDrawing extends AbstractDoc { + private static final long serialVersionUID = -7465031832786627181L; + + + public DocDrawing(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public String getDesignationEn() { + return getMasterFormRev().getPropertyObject(PV_DESIGNATION_EN).getStringValue(); + } + + public String getIndicePlan() { + return getMasterFormRev().getPropertyObject(PV_INDICE_PLAN).getStringValue(); + } + + @Override + public T accept(final IDocVisitor docVisitor) { + return docVisitor.visit(this); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/DocFactory.java b/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/DocFactory.java new file mode 100644 index 0000000..07b796a --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/DocFactory.java @@ -0,0 +1,56 @@ +package com.capgemini.reports.documentationobjects; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; + +/** + * Factory for all {@link AbstractDoc}s. + */ +@Slf4j +public final class DocFactory { + + private DocFactory() { + // Nothing to do + } + + /** + * Builds an {@link AbstractDoc} from an {@link ItemRevision}.
    + */ + public static AbstractDoc build(final TcSession session, final Item doc) { + String docType = doc.getTypeObject().getName(); + switch (docType) { + case SnecmaObjectTypes.DOC_NORM: + return new DocNorm(session, doc); + case SnecmaObjectTypes.DOC_NORM_STANDARD: + return new DocNormStandard(session, doc); + default: + log.warn("Unable to find the builder for doc: {}", docType); + return null; + } + } + + /** + * Builds an {@link AbstractDoc} from an {@link ItemRevision}.
    + */ + public static AbstractDoc build(final TcSession session, final ItemRevision docRev) { + String docType = docRev.getTypeObject().getName(); + switch (docType) { + case SnecmaObjectTypes.DOC_DRAWING_REVISION: + return new DocDrawing(session, docRev); + case SnecmaObjectTypes.DOC_GEOMETRY_REVISION: + return new DocGeometry(session, docRev); + case SnecmaObjectTypes.DOC_NORM_REVISION: + return new DocNorm(session, docRev); + case SnecmaObjectTypes.DOC_NORM_STANDARD_REVISION: + return new DocNormStandard(session, docRev); + case SnecmaObjectTypes.DOC_TECHNIC_REVISION: + return new DocTechnic(session, docRev); + default: + log.warn("Unable to find the builder for doc: {}", docType); + return null; + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/DocGeometry.java b/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/DocGeometry.java new file mode 100644 index 0000000..f40dbab --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/DocGeometry.java @@ -0,0 +1,37 @@ +package com.capgemini.reports.documentationobjects; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_DESIGNATION_EN; +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_INDICE_CARTOUCHE; + +/** + * Class representing a DocGeometry. + */ +@Slf4j +public class DocGeometry extends AbstractDoc { + private static final long serialVersionUID = -7626101075442466263L; + + public DocGeometry(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public String getName() { + return itemRevision.get_object_name(); + } + + public String getDesignationEN() { + return getMasterFormRev().getPropertyObject(PV_DESIGNATION_EN).getStringValue(); + } + + public String getIndiceCartouche() { + return getMasterFormRev().getPropertyObject(PV_INDICE_CARTOUCHE).getStringValue(); + } + + @Override + public T accept(final IDocVisitor docVisitor) { + return docVisitor.visit(this); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/DocNorm.java b/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/DocNorm.java new file mode 100644 index 0000000..5ca9873 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/DocNorm.java @@ -0,0 +1,82 @@ +package com.capgemini.reports.documentationobjects; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.*; + +/** + * Class representing a DocNorm. + */ +public class DocNorm extends AbstractDoc { + private static final long serialVersionUID = 8380671472697651060L; + private final Item item; + + public DocNorm(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + this.item = null; + } + + public DocNorm(final TcSession session, final Item item) { + super(session, null); + this.item = item; + } + + public String getItemName() { + if (item == null) { + return getItem().get_object_name(); + } else { + return item.get_object_name(); + } + } + + @Override + public String getType() { + if (item == null) { + return super.getType(); + } else { + return item.getTypeObject().getName(); + } + } + + @Override + public String getDocId() { + if (item == null) { + return super.getDocId(); + } else { + return item.get_item_id(); + } + } + + @Override + public String getRevision() { + if (item == null) { + return super.getRevision(); + } else { + return ""; + } + } + + public String getDesignationEn() { + return getMasterFormRev().getPropertyObject(PV_DESIGNATION_EN).getStringValue(); + } + + public String getTypeDocNorm() { + return getMasterFormRev().getPropertyObject(PV_TYPE_DOC_NORM).getStringValue(); + } + + public String getIdOrigine() { + return getMasterFormRev().getPropertyObject(PV_ID_ORIGINE).getStringValue(); + } + + public String getSensibiliteSecurite() { + return getMasterForm().getPropertyObject(PV_SENSIBILITE_SECURITE).getStringValue(); + } + + @Override + public T accept(final IDocVisitor docVisitor) { + return docVisitor.visit(this); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/DocNormStandard.java b/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/DocNormStandard.java new file mode 100644 index 0000000..a24a11b --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/DocNormStandard.java @@ -0,0 +1,75 @@ +package com.capgemini.reports.documentationobjects; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_DESIGNATION_EN; +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_ID_ORIGINE; + +/** + * Class representing a DocNormStandard. + */ +public class DocNormStandard extends AbstractDoc { + private static final long serialVersionUID = 882873890678687030L; + private final Item item; + + public DocNormStandard(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + this.item = null; + } + + public DocNormStandard(final TcSession session, final Item item) { + super(session, null); + this.item = item; + } + + public String getItemName() { + if (item == null) { + return getItem().get_object_name(); + } else { + return item.get_object_name(); + } + } + + @Override + public String getType() { + if (item == null) { + return super.getType(); + } else { + return item.getTypeObject().getName(); + } + } + + @Override + public String getDocId() { + if (item == null) { + return super.getDocId(); + } else { + return item.get_item_id(); + } + } + + @Override + public String getRevision() { + if (item == null) { + return super.getRevision(); + } else { + return ""; + } + } + + public String getDesignationEn() { + return getMasterFormRev().getPropertyObject(PV_DESIGNATION_EN).getStringValue(); + } + + public String getIdOrigine() { + return getMasterFormRev().getPropertyObject(PV_ID_ORIGINE).getStringValue(); + } + + @Override + public T accept(final IDocVisitor docVisitor) { + return docVisitor.visit(this); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/DocTechnic.java b/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/DocTechnic.java new file mode 100644 index 0000000..57b126c --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/DocTechnic.java @@ -0,0 +1,50 @@ +package com.capgemini.reports.documentationobjects; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.*; + +/** + * Represent a document of Gel of Unit. + */ +public class DocTechnic extends AbstractDoc { + private static final long serialVersionUID = -6347639229060368050L; + + public DocTechnic(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public String getIndice() { + return getMasterFormRev().getPropertyObject(PV_INDICE_DOCUMENT).getStringValue(); + } + + public String getReference() { + return getDocId(); + } + + public String getTypeDocTechnic1() { + return getMasterFormRev().getPropertyObject(PV_TYPE_DOC_TECHNIC_1).getStringValue(); + } + + public String getTypeDocTechnic2() { + return getMasterFormRev().getPropertyObject(PV_TYPE_DOC_TECHNIC_2).getStringValue(); + } + + public String getIdOrigine() { + return getMasterFormRev().getPropertyObject(PV_ID_ORIGINE).getStringValue(); + } + + public String getDesignationEn() { + return getMasterFormRev().getPropertyObject(PV_DESIGNATION_EN).getStringValue(); + } + + public String getSensibiliteSecurite() { + return getMasterForm().getPropertyObject(PV_SENSIBILITE_SECURITE).getStringValue(); + } + + @Override + public T accept(final IDocVisitor docVisitor) { + return docVisitor.visit(this); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/IDocVisitor.java b/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/IDocVisitor.java new file mode 100644 index 0000000..dc92dd5 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/documentationobjects/IDocVisitor.java @@ -0,0 +1,49 @@ +package com.capgemini.reports.documentationobjects; + +/** + * Interface for visitor Pattern, allows someone to visit every Doc type avaialble and implement a dedicated treatent. + * + * @param a produced object during the visit + */ +public interface IDocVisitor { + + /** + * Behaviour when visiting a {@link DocDrawing}. + * + * @param doc + * @return a produced result + */ + T visit(final DocDrawing doc); + + /** + * Behaviour when visiting a {@link DocGeometry}. + * + * @param doc + * @return a produced result + */ + T visit(final DocGeometry doc); + + /** + * Behaviour when visiting a {@link DocNorm}. + * + * @param doc + * @return a produced result + */ + T visit(final DocNorm doc); + + /** + * Behaviour when visiting a {@link DocNormStandard}. + * + * @param doc + * @return a produced result + */ + T visit(final DocNormStandard doc); + + /** + * Behaviour when visiting a {@link DocTechnic}. + * + * @param doc + * @return a produced result + */ + T visit(final DocTechnic doc); +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/exceptions/InvalidInputException.java b/teamcenter/src/main/java/com/capgemini/reports/exceptions/InvalidInputException.java new file mode 100644 index 0000000..4553b90 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/exceptions/InvalidInputException.java @@ -0,0 +1,84 @@ +package com.capgemini.reports.exceptions; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; + +/** KURT functional input value errors ("not a number" etc). */ +public class InvalidInputException extends KurtException { + + private static final long serialVersionUID = -8816332546502998913L; + + protected final UserInputErrorEnum userInputError; + + /** + * Constructs an INTERNAL_ERROR, used when something went wrong while checking the user inputs.
    + * In this case, the user input could not be checked because an internal error occurred first. + * + * @param aMessage a precise Error message for the developer + */ + public InvalidInputException(final String aMessage) { + super(aMessage); + this.userInputError = UserInputErrorEnum.INTERNAL_ERROR; + } + + /** + * Constructs an Exception that may occur if the user provided some wrong inputs.
    + * A preset message will be sent to the user depending on the error.
    + * A preset message will be sent to the Exception log depending on the error.
    + * + * @param aUserInputError {@link UserInputErrorEnum} explaining what went wrong + */ + public InvalidInputException(final UserInputErrorEnum aUserInputError) { + super(aUserInputError.msgEn); + this.userInputError = aUserInputError; + } + + /** + * Constructs an Exception that may occur if the user provided some wrong inputs.
    + * A preset message will be sent to the user depending on the error.
    + * A preset message will be sent to the Exception log depending on the error.
    + * + * @param aUserInputError {@link UserInputErrorEnum} explaining what went wrong + * @param originalException the original exception + */ + public InvalidInputException(final UserInputErrorEnum aUserInputError, final Throwable originalException) { + super(aUserInputError.msgEn, originalException); + this.userInputError = aUserInputError; + } + + /** + * Constructs an Exception that may occur if the user provided some wrong inputs.
    + * A preset message message will be sent to the user depending on the error.
    + * The specified message parameter will be sent to the Exception log and override the default one.
    + * + * @param aMessage a precise Error message for the programmer + * @param aUserInputError {@link UserInputErrorEnum} explaining what went wrong + */ + public InvalidInputException(final String aMessage, final UserInputErrorEnum aUserInputError) { + super(aMessage); + this.userInputError = aUserInputError; + } + + /** + * Constructs an INTERNAL_ERROR, used when something went wrong while checking the user inputs.
    + * In this case, the user input could not be checked because an internal error occurred first.
    + * The original exception is stored for reference. + * + * @param aMessage a precise Error message for the developer + * @param anException the original error + */ + public InvalidInputException(final String aMessage, final Throwable anException) { + super(aMessage, anException); + this.userInputError = UserInputErrorEnum.INTERNAL_ERROR; + } + + /** + * Returns the message to be sent to the user. + * + * @return the message + */ + @Override + public String getErrorMessageForUser() { + return userInputError.msgFr; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/exceptions/InvalidUserInputException.java b/teamcenter/src/main/java/com/capgemini/reports/exceptions/InvalidUserInputException.java new file mode 100644 index 0000000..de6a8d1 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/exceptions/InvalidUserInputException.java @@ -0,0 +1,90 @@ +package com.capgemini.reports.exceptions; + +import lombok.Getter; + +/** + * KURT functional input value errors ("not a number" etc), specifically coming from the user. + *

    + * Carries a message explaining to the user why the input is wrong.
    + * Also carries contextual information, such as which report has caused this error. + */ +@Getter +public class InvalidUserInputException extends InvalidInputException { + + private static final long serialVersionUID = -8816332546502998913L; + + protected String userInputDynamicError = ""; + + /** + * Builds an Internal Error Exception, with custom message for debugging. + * + * @param anError Error description for devs + */ + public InvalidUserInputException(final String anError) { + super(anError); + } + + /** + * Builds an Internal Error Exception, with custom message for debugging. Includes the Throwable that caused the error. + * + * @param anError Error description for devs + * @param originalError the Original Error that caused all the drama + */ + public InvalidUserInputException(final String anError, final Throwable originalError) { + super(anError, originalError); + } + + /** + * Builds an exception which explains what happened to the user, and to the developer. + * + * @param anError an {@link com.capgemini.reports.exceptions.UserInputErrorEnum} that explains what happened for the user, and for the developper. + */ + public InvalidUserInputException(final UserInputErrorEnum anError) { + super(anError.getMsgEn(), anError); + } + + /** + * Builds an exception which explains what happened to the user, and to the developer. + * + * @param anError an {@link com.capgemini.reports.exceptions.UserInputErrorEnum} that explains what happened for the user, and for the developper. + * @param originalError the original {@link Throwable} Exception that caused the failure. + */ + public InvalidUserInputException(final UserInputErrorEnum anError, final Throwable originalError) { + super(anError, originalError); + } + + + /** + * Builds dynamic exception which explains what happened to the user, and to the developer. + * + * @param anError an {@link com.capgemini.reports.exceptions.UserInputErrorEnum} that explains what happened for the user, and for the developper. + * @param tags String the dynamic parameters to add to the error. + */ + public InvalidUserInputException(final UserInputErrorEnum anError, final String... tags) { + super(replaceTags(anError.getMsgEn(), tags)); + this.userInputDynamicError = replaceTags(anError.getMsgFr(), tags); + } + + private static String replaceTags(final String message, final String[] tags) { + String msg = message; + for (String tag : tags) { + msg = msg.replaceFirst("\\{\\}", tag); + } + return msg; + } + + /** + * Returns the message to be sent to the user. + * + * @return the message + */ + @Override + public String getErrorMessageForUser() { + if (!userInputDynamicError.isEmpty()) { + return userInputDynamicError; + } + else { + return userInputError.msgFr; + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/exceptions/MalformedNomenclatureException.java b/teamcenter/src/main/java/com/capgemini/reports/exceptions/MalformedNomenclatureException.java new file mode 100644 index 0000000..5570a11 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/exceptions/MalformedNomenclatureException.java @@ -0,0 +1,31 @@ +package com.capgemini.reports.exceptions; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; + +/** Exception thrown when the nomenclature is not as expected. */ +public class MalformedNomenclatureException extends KurtException { + + + private static final long serialVersionUID = -3794378881986432701L; + + /** + * throw this exception when the nomenclature isn't as axpected (i.e. missing elements like part number below RF Generic, some RF Admins, etc. + * + * @param aMessage a message explaining just how wrong the nomenclature is + */ + public MalformedNomenclatureException(final String aMessage) { + super(aMessage); + } + + /** + * throw this exception when the nomenclature isn't as axpected (i.e. missing elements like part number below RF Generic, some RF Admins, etc. + * + * @param aMessage a message explaining just how wrong the nomenclature is + * @param anException the original exception that can be interpreted as a malformed nomenclature exception. + */ + + public MalformedNomenclatureException(final String aMessage, final Throwable anException) { + super(aMessage, anException); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/exceptions/NoConfChangesException.java b/teamcenter/src/main/java/com/capgemini/reports/exceptions/NoConfChangesException.java new file mode 100644 index 0000000..c403c6d --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/exceptions/NoConfChangesException.java @@ -0,0 +1,10 @@ +package com.capgemini.reports.exceptions; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; + +public class NoConfChangesException extends KurtException { + + public NoConfChangesException(String aMessage) { + super(aMessage); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/exceptions/NotFoundException.java b/teamcenter/src/main/java/com/capgemini/reports/exceptions/NotFoundException.java new file mode 100644 index 0000000..2bcfe23 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/exceptions/NotFoundException.java @@ -0,0 +1,29 @@ +package com.capgemini.reports.exceptions; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; + +/** Erreur générée lorsqu'un objet n'a pas été trouvé dans teamcenter. */ +public class NotFoundException extends KurtException { + + private static final long serialVersionUID = -5126739618564266946L; + + /** + * Constructor. + * + * @param aMessage Error message + */ + public NotFoundException(final String aMessage) { + super(aMessage); + } + + /** + * Constructor. + * + * @param aMessage Error message + * @param anException Original exception + */ + public NotFoundException(final String aMessage, final Throwable anException) { + super(aMessage, anException); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/exceptions/NotSupportedException.java b/teamcenter/src/main/java/com/capgemini/reports/exceptions/NotSupportedException.java new file mode 100644 index 0000000..229131b --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/exceptions/NotSupportedException.java @@ -0,0 +1,30 @@ +package com.capgemini.reports.exceptions; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; + +/** Represents the exception to throw when the operation requested cannot be performed (it is not implemented, or non-sensical. */ +public class NotSupportedException extends KurtException { + + /** Serialization UID. **/ + private static final long serialVersionUID = -7975389522450629095L; + + /** + * Constructor. + * + * @param aMessage Error message + */ + public NotSupportedException(final String aMessage) { + super(aMessage); + } + + /** + * Constructor. + * + * @param aMessage Error message + * @param anException Original exception + */ + public NotSupportedException(final String aMessage, final Throwable anException) { + super(aMessage, anException); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/exceptions/ServiceException.java b/teamcenter/src/main/java/com/capgemini/reports/exceptions/ServiceException.java new file mode 100644 index 0000000..d190482 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/exceptions/ServiceException.java @@ -0,0 +1,32 @@ +package com.capgemini.reports.exceptions; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; + +/** + * Exception déclenchée lorsqu'un service n'est pas capable de remplir sa tâche. + * + */ +public class ServiceException extends KurtException { + + private static final long serialVersionUID = -5463974860193499398L; + + /** + * Constructor. + * + * @param aMessage Error message + */ + public ServiceException(String aMessage) { + super(aMessage); + } + + /** + * Constructor. + * + * @param aMessage Error message + * @param anException Original exception + */ + public ServiceException(String aMessage, Throwable anException) { + super(aMessage, anException); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/exceptions/UserInputErrorEnum.java b/teamcenter/src/main/java/com/capgemini/reports/exceptions/UserInputErrorEnum.java new file mode 100644 index 0000000..f7563eb --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/exceptions/UserInputErrorEnum.java @@ -0,0 +1,184 @@ +package com.capgemini.reports.exceptions; + +import lombok.Getter; + +/** + * List of all possible problems the user needs to know about.
    + * WARNING -> Unsupported characters in web browser ie8 : (') and (&) use numeric code. + */ +@Getter +public enum UserInputErrorEnum { + + /** + * Error occurring if the user is requesting a report that has already been asked for, which is still in the queues. + */ + DUPLICATE_REPORT_LAUNCHED_RECENTLY("Previous similar recent launch detected. Prompting user to confirm.", "Une demande identique lancée par {} est déjà en attente de génération. Vous allez être associé au résultat de ce lancement "), + /** + * Error occurring if the user is requesting a report that HE himself has already been asked for, which is still in the queues. + */ + DUPLICATE_REPORT_LAUNCHED_RECENTLY_BY_SELF("Previous similar recent launch detected from the same user. Denying launch.", "Lancement rejeté. Vous avez déjà lancé une demande identique, qui est en attente de génération."), + /** + * Error occurring if the user is requestinga scheduling with a name that already exists. + */ + DUPLICATE_SCHEDULING("Previous scheduling with same name detected. Denying scheduling.", "Lancement rejeté. Une planification du même nom existe déjà."), + + /** + * Error occurring if the user has input a non-numeric Unit. + */ + UNIT_NOT_NUMERIC("Server requested to perform report with non-numeric UNIT argument", "Le Unit fourni n’est pas un nombre."), + /** + * Error occurring if the User has input a product that can not be found in the TC database. + */ + INCORRECT_PRODUCT("Server called with bad arguments: productID is null", "Aucun produit n’a été fourni."), + /** + * Error occurring if the User has input a an invalid Generic under a (possibly valid) Product-Unit. + */ + PRODUCT_UNIT_GENERIC_INVALID("Could not find a correct Product/Unit/Generic combination", "Impossible de trouver le générique fourni sous ce couple produit-unit."), + /** + * Error occurring if the User has input a an invalid Generic Assemb under a (possibly valid) Product-Unit. + */ + PRODUCT_UNIT_GENERIC_ASSEMB_INVALID("Could not find a correct Product/Unit/GenericAssemb combination", "Impossible de trouver le générique assemb fourni sous ce couple produit-unit."), + /** + * Error occurring if the User has input a an invalid Generic for the Product-Unit. + */ + PRODUCT_UNIT_GENERIC_DOES_NOT_EXIST("The requested generic could not be found in the database.", "Le triplet produit-unit-générique n’existe pas."), + /** + * Error occurring When an internal error has occurred. + */ + INTERNAL_ERROR("Internal error", "Une erreur interne s’est produite."), + /** + * Error occurring if the User has input a an invalid Generic. + */ + GENERIC_DOES_NOT_EXIST("Generic does not exist ", "Le Générique est inconnu. Aucune donnée ne peut être affichée"), + /** + * Error occurring if the User has input a an invalid Generic Assemb. + */ + GENERIC_ASSEMB_DOES_NOT_EXIST("Generic Assemb does not exist ", "Générique Montage inconnu."), + /** + * Error occurring if the User has input a an invalid Unit for the Product. + */ + PRODUCT_AND_UNIT_DOES_NOT_EXIST("The unit is not associated to product.", "Le Unit n'est pas associé au Produit."), + /** + * Error occurring if the User has input a an invalid Generic Assemb or Generic under a (possibly valid) Product-Unit. + */ + GENERIC_INPUT("Generic does not exist ", "Saisir un Générique (Générique/Générique Montage) ou cocher ‘Vue Model list’, le ou est exclusif. »"), + /** + * Error occurring if the User has input a an invalid Generic Assemb. + */ + NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_PRODUCT_AND_UNIT("No data could be extracted, the triplet product/unit/generic is not consistent", "Aucune donnée n’a pu être extraite, relancer le rapport après avoir vérifié les critères saisis. Pour rappel, le triplet ‘générique / produit / unit’ doit être cohérent."), + /** + * Error occurring if the User has input a an invalid Generic Assemb or Generic under a (possibly valid) Product-Unit. + */ + NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_ASSEMB_PRODUCT_AND_UNIT("No data could be extracted, the triplet product/unit/genericAssemb is not consistent", "Aucune donnée n’a pu être extraite, relancer le rapport après avoir vérifié les critères saisis. Pour rappel, le triplet ‘générique montage / produit / unit’ doit être cohérent."), + /** + * Error occurring if the User has input a an invalid type object. + */ + THE_SELECTED_OBJECT_IS_NOT_PERMITTED_ON_THIS_REPORT("The selected object is not permitted on this report.", "L’objet sélectionné n’est pas autorisé sur ce rapport."), + + // Created for R07 + /** + * Error occurring if the User has input an invalid Product-Unit. + */ + THE_UNIT_1_IS_NOT_ASSOCIATED_TO_THE_PRODUCT_1("The unit 1 is not associated to the product 1.", "Le unit 1 n’est pas associé au produit 1."), + /** + * Error occurring if the User has input an invalid Product-Unit. + */ + THE_UNIT_2_IS_NOT_ASSOCIATED_TO_THE_PRODUCT_2("The unit 2 is not associated to the product 2.", "Le unit 2 n’est pas associé au produit 2."), + + // Created for R11 + /** + * Error occurring if the User has input a an invalid Product. + */ + PRODUCT_DOES_NOT_EXIST_NO_DATA_TO_PRINT("Product does not not exist. Unable to print any data.", "Le Produit est inconnu. Aucune donnée ne peut être affichée."), + /** + * Error occurring if the User has input a an invalid type of Generic. + */ + THE_GENERIC_MUST_BELONG_TO_THE_TECHNICAL_VIEW("The generic must be a geric type. Unable to print any data.", "Le générique doit être de type générique. Aucune donnée ne peut être affichée."), + /** + * Error occurring if the User has input a an invalid Generic under a (possibly valid) Product-Unit. + */ + NO_GENERIC_REVISION_IS_ASSOCIATED_TO_THE_PRODUCT_UNIT_NO_DATA_TO_PRINT("No Generic Revision is associated to the product-unit. Unbale to print any data.", "Aucune révision du Générique ne s’applique pour le Produit Unit. Aucune donnée ne peut être affichée."), + + // Created for R16 + /** + * Error occurring if the User has input a an invalid Product or couple of Product-Unit. + */ + WRONG_EFFECTIVITY_THE_PRODUCT_DOES_NOT_EXIST_OR_THE_UNIT_DOES_NOT_EXIST_FOR_THE_PRODUCT("Wrong effectivity, the product does not exist or the unit does not exit for the product.", "Effectivité erronée, produit inconnu ou unit inconnu pour ce produit."), + /** + * Error occurring if the User has input a an invalid Generic or Product-Unit-Generic. + */ + GENERIC_DOES_NOT_EXIST_OR_ENTRY_EFFECTIVITY_IS_NOT_COMPATIBLE_WITH_THE_GENERIC("Generic does not exist - OR - entry effectivity is not compatible with the Generic.", "Générique inconnu – OU - l’effectivité saisie n’est pas compatible avec le générique."), + + // Created for R19 + /** + * Error occurring if the User has selected an invalid object. + */ + TYPE_DOCUMENT_SELECTED_NOT_AUTHORIZED("

    " + "

    The type of item selected is not compatible with the report R19." + "

    The only types compatible are:

    " + "

    - Document "DocDrawing" (revision)

    " + "

    - Document "DocNorm" (master and review)

    " + "

    - Document "DocNormStandard" (master and review)

    " + "

    - Document "DocTechnic" (revision)

    " + "
    ", "
    " + "

    Le type d'article sélectionné n'est pas compatible avec le rapport R19.

    " + "

    Les seuls types compatibles sont les suivants:

    " + "

    - Document "DocDrawing" (révision)

    " + "

    - Document "DocNorm" (master et révision)

    " + "

    - Document "DocNormStandard" (master et révision)

    " + "

    - Document "DocTechnic" (révision)

    " + "
    "), + + // Created for R20 + /** + * Error occurring if the User has input an invalid Product-Unit. + */ + THE_UNIT_AFTER_IS_NOT_ASSOCIATED_TO_THE_PRODUCT_AFTER("The Unit ‘After’ is not associated to the Product ‘After’", "Le Unit ‘Après’ n’est pas associé au Produit ‘Après’."), + /** + * Error occurring if the User has input an invalid Product-Unit. + */ + THE_UNIT_BEFORE_IS_NOT_ASSOCIATED_TO_THE_PRODUCT_BEFORE("The Unit ‘Before’ is not associated to the Product ‘Before’", "Le Unit ‘Avant’ n’est pas associé au Produit ‘Avant’."), + /** + * Error occurring if the User has input an Product-Unit after where th unit's latest maturity status is of the wrong type. + */ + THE_LATEST_UNIT_AFTER_DOES_NOT_HAVE_THE_APPROPRIATE_MATURITY("The latest Unit ‘After’ does not have the proper maturity status", "La révision du Unit ‘Après’ la plus récemment statuée n‘a pas la maturité appropriée pour le gel du unit."), + /** + * Error occurring if the User has input an Product-Unit before where th unit's latest maturity status is of the wrong type. + */ + THE_LATEST_UNIT_BEFORE_DOES_NOT_HAVE_THE_APPROPRIATE_MATURITY("The latest Unit ‘Before’ does not have the proper maturity status", "La révision du Unit ‘Avant’ la plus récemment statuée n‘a pas la maturité appropriée pour le gel du unit."), + /** + * Dynamic error occurring if a ChangeRequest doesn't exist. + */ + UNKNOWN_CHANGE_REQUEST("Unknown ChangeRequest {}", "ChangeRequest {} inconnu"), + /** + * Dynamic error occurring if a ChangeRequest is not compatible with the Unit Before. + */ + REMOVED_CHANGE_REQUEST_IS_NOT_COMPATIBLE_WITH_BEFORE_EFFECTIVITY("Removed ChangeRequest {} is not compatible with ‘Before’ effectivity", "ChangeRequest {} retirée, elle n’est pas compatible avec l’effectivité ‘Avant’ saisie."), + /** + * Dynamic error occurring if a ChangeRequest is deprecated. + */ + REMOVED_CHANGE_REQUEST_IS_DEPRECATED("The LMR Change Request {} is deprecated, which is not authorized for an LMR.", "La modification suivante n’est pas un changeRequest non déprécié : {}."), + /** + * Dynamic error occurring if a ChangeRequest has several revisions under a Unit. + */ + SEVERAL_REVISIONS_OF_RETRIEVED_CHANGE_REQUEST_ARE_COMPATIBLE_WITH_BEFORE_EFFECTIVITY("Several revisions of retrieved ChangeRequest {} are compatible with the ‘Before’ effectivity.", "Plusieurs révisions du ChangeRequest {} retiré sont compatibles avec l’effectivité ‘Avant’ saisie."), + /** + * Error occurring if the User has input an invalid ID or UID. + */ + OBJECT_DOES_NOT_EXIST("The Object does not seem to exist in Tc", "L’objet demandé n’existe pas"), + + NO_DATA_COULD_BE_EXTRACTED_NO_FROZEN_OR_OPEN_UNIT_TO_THE_PRODUCT("No data could be extracted, no open or frozen Unit found for this Product.", "Aucune donnée n’a pu etre extraite, aucun Unit ouvert ou gelé trouvé pour ce Produit."), + NO_DATA_COULD_BE_EXTRACTED_NO_OPEN_UNIT_TO_THE_PRODUCT("No data could be extracted, no open Unit found for this Product.", "Aucune donnée n’a pu etre extraite, aucun Unit ouvert trouvé pour ce Produit."), + + NO_DATA_EXTRACTED_FOR_CRITERIA("No data could be extracted for the criteria.", "Aucune donnée n’a pu etre extraite pour les critères saisis."), + + NO_CONFIGURATION_CHANGES("No configuration changes. Report generation canceled.", "Aucune configuration en évolution. La génération du rapport a été annulée"), + INVALID_FILE("Invalid file. Report generation canceled.", "Fichier non conforme. La génération du rapport a été annulée"), + + // Created for R24 + /** + * Error occurring if no generics exist for the Product-Unit. + */ + NO_GENERIC_FOUND_FOR_THIS_PU("No data could be extracted, no generic found for this Product/Unit or Product.", "Aucune donnée n’a pu etre extraite, aucun générique trouvé pour ce Product/Unit ou Produit."), + + /** + * Error occurring if no data exists to be shown in the User Interface. This is normal behavior. + */ + NOTHING_TO_BE_SHOWN("Nothing to be shown", "Il n'y a rien à afficher"), + + UNABLE_TO_USE_REVISION_RULE("Unable to use the revision rule required for the report. Thank you for renewing your request.", "Impossible d’utiliser la règle de révision nécessaire à l’élaboration du rapport. Merci de renouveler votre demande."); + + protected final String msgEn; + protected final String msgFr; + + UserInputErrorEnum(final String aMsgEn, final String aMsgFr) { + msgEn = aMsgEn; + msgFr = aMsgFr; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/filter/AllIsGoodFilter.java b/teamcenter/src/main/java/com/capgemini/reports/filter/AllIsGoodFilter.java new file mode 100644 index 0000000..772e3c1 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/filter/AllIsGoodFilter.java @@ -0,0 +1,30 @@ +package com.capgemini.reports.filter; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; + +/** Class which implements IFilterExplosionNomenclature, always returns false which means : no part should ever be excluded. */ +public class AllIsGoodFilter implements IFilterExplosionNomenclature { + + @Override + public boolean isExcluded(TcSession session, final BOMLineHolder object) { + return false; + } + + @Override + public boolean isExcluded(final ISnecmaObject object) { + return false; + } + + @Override + public boolean isExcluded(final String type) { + return false; + } + + @Override + public boolean isIncluded(final String type) { + return true; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/filter/FilterExcludeByType.java b/teamcenter/src/main/java/com/capgemini/reports/filter/FilterExcludeByType.java new file mode 100644 index 0000000..4f44123 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/filter/FilterExcludeByType.java @@ -0,0 +1,29 @@ +package com.capgemini.reports.filter; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.resolution.filtering.TcTypeExclusionFilter; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; + +/** Filters objects according to their type. */ +public class FilterExcludeByType extends TcTypeExclusionFilter implements IFilterExplosionNomenclature { + + /** + * Builds a Filter instance, that will ALLOW any object of the provided type. + * + * @param authorizedTypes the object types to be included + */ + public FilterExcludeByType(final String... authorizedTypes) { + super(authorizedTypes); + } + + @Override + public boolean isExcluded(TcSession session, final BOMLineHolder objectToFind) { + return super.isExcluded(objectToFind.getObjectType()); + } + + @Override + public boolean isExcluded(final ISnecmaObject object) { + return super.isExcluded(object.getType()); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/filter/FilterIncludeByType.java b/teamcenter/src/main/java/com/capgemini/reports/filter/FilterIncludeByType.java new file mode 100644 index 0000000..a5b13e6 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/filter/FilterIncludeByType.java @@ -0,0 +1,30 @@ +package com.capgemini.reports.filter; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.resolution.filtering.TcTypeInclusionFilter; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; + + +/** Filters objects according to their type. */ +public class FilterIncludeByType extends TcTypeInclusionFilter implements IFilterExplosionNomenclature { + + /** + * Builds a Filter instance, that will ALLOW any object of the provided type. + * + * @param authorizedTypes the object types to be included + */ + public FilterIncludeByType(final String... authorizedTypes) { + super(authorizedTypes); + } + + @Override + public boolean isExcluded(TcSession session, final BOMLineHolder objectToFind) { + return super.isExcluded(objectToFind.getObjectType()); + } + + @Override + public boolean isExcluded(final ISnecmaObject object) { + return super.isExcluded(object.getType()); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/filter/IFilterExplosionNomenclature.java b/teamcenter/src/main/java/com/capgemini/reports/filter/IFilterExplosionNomenclature.java new file mode 100644 index 0000000..8e0c065 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/filter/IFilterExplosionNomenclature.java @@ -0,0 +1,28 @@ +package com.capgemini.reports.filter; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.resolution.filtering.ITcTypeFilter; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; + +/** Interface for classes that can act as filters on a series of {@link BOMLineHolder}s or {@link ISnecmaObject}s. */ +public interface IFilterExplosionNomenclature extends ITcTypeFilter { + + /** + * Tests the provided object for exclusion. + * + * + * @param session + * @param object the object to be tested + * @return true if the object should be excluded + */ + boolean isExcluded(TcSession session, final BOMLineHolder object); + + /** + * Tests the provided object for exclusion. + * + * @param object the object to be tested + * @return true if the object should be excluded + */ + boolean isExcluded(final ISnecmaObject object); +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/releasestatus/DefaultRevisionSelector.java b/teamcenter/src/main/java/com/capgemini/reports/releasestatus/DefaultRevisionSelector.java new file mode 100644 index 0000000..ed85953 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/releasestatus/DefaultRevisionSelector.java @@ -0,0 +1,69 @@ +package com.capgemini.reports.releasestatus; + +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.teamcenter.ObjectInfoHelper; +import com.google.common.base.Optional; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; + +import java.util.Calendar; +import java.util.List; + +/** + * This class is a Default Selector of Revision. Its job is to return the latest {@link ItemRevision} of the {@link Item}.
    + * First looks for the revision which has the TcReleaseStatus with the latest release_date (that is before the embedded deadline).
    + * If no Revision have a TcReleaseStatus, or if none of these statuses have a release date, then returns the Revision with the latest last_mod_date (that is before the provided deadline). + */ +@Slf4j +public class DefaultRevisionSelector implements RevisionSelector { + + private static final long serialVersionUID = 8373335997828920471L; + + private final Calendar deadline; + + private final StatusEnum[] allowedStatuses; + + /** + * Builds a {@link DefaultRevisionSelector} with a {@link Calendar} as a deadline (for release date/mod date) and an (optional) list of allowed TcReleaseStatus. + * + * @param deadline deadline: no status set after this date is allowed / no Revision modified after this date either. If null, all dates are allowed. + * @param allowedStatuses a list of allowed {@link StatusEnum}. If empty, all status are accepted + */ + public DefaultRevisionSelector(final Calendar deadline, final StatusEnum... allowedStatuses) { + this.deadline = deadline; + this.allowedStatuses = allowedStatuses; + } + + /** + * Returns the latest {@link ItemRevision} of the {@link Item}.
    + * First looks for the revision which has the TcReleaseStatus with the latest release_date (that is before the embedded deadline). This TcReleaseStatus must also be in an allowed status (see constructor).
    + * If no Revision have a TcReleaseStatus, or if none of these statuses have a release date, or if no status is allowed, then returns the Revision with the latest last_mod_date (that is before the provided deadline). + * + * @param session an active {@link TcSession} + * @param item the {@link Item} for which we need to find a Revision + * @return ItemRevision the most Up-to-date Revision + */ + @Override + public RevisionStatusAndDate selectRevision(final TcSession session, final Item item) { + String itemID = item.get_item_id(); + String deadLineStr = deadline == null ? "no date" : TeamcenterDateFormatter.formatCalendarToPattern(deadline, "yyyy-MMM-dd"); + log.debug("START findAll correct revision for Item in pseudo-folder of an Alternate or Det {}, with date {}", itemID, deadLineStr); + + List itemsRevision = new ItemRevisionQuery(session).searchID(itemID).findAll(); + Optional bestRevision = ObjectInfoHelper.getRevisionAndStatusWithMostRecentReleaseDate(session, itemsRevision, deadline, allowedStatuses); + if (bestRevision.isPresent()) { + RevisionStatusAndDate rev = bestRevision.get(); + log.debug("The highest revision of the Item {} is {}, it has the latest realease_date", itemID, + rev.getItemRevision().get_item_revision_id()); + return bestRevision.get(); + } else { + RevisionStatusAndDate latestItemRev = ObjectInfoHelper.getRevisionAndStatusWithMostRecentModificationDate(itemsRevision, deadline); + log.debug("The highest revision of the Item {} is {}, it has the latest last_mod_date", itemID, latestItemRev.getItemRevision().get_item_revision_id()); + return latestItemRev; + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/releasestatus/EffectivityBehaviourHelper.java b/teamcenter/src/main/java/com/capgemini/reports/releasestatus/EffectivityBehaviourHelper.java new file mode 100644 index 0000000..661f45d --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/releasestatus/EffectivityBehaviourHelper.java @@ -0,0 +1,99 @@ +package com.capgemini.reports.releasestatus; + +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.regex.Pattern; + +/** + * This Helper class presents methods for specifying a visitor's behaviour regarding parts with effectivities. + */ +@EqualsAndHashCode +public final class EffectivityBehaviourHelper implements Serializable { + + private static final long serialVersionUID = 4967460714547927907L; + private static final Pattern UNIT_EFFECTIVITY_PATTERN = Pattern.compile(".*((Configuré en utilisant Numéro d'unité)|(Configured Using Unit Number)).*"); + + private final EffectivityBehaviourEnum behaviour; + + private EffectivityBehaviourHelper(final EffectivityBehaviourEnum behaviour) { + this.behaviour = behaviour; + } + + /** + * Construct an TcEffectivity Behaviour which always visits Parts with any effectivity. + * + * @return the {@link EffectivityBehaviourHelper}. + */ + public static EffectivityBehaviourHelper visitAnyPart() { + return new EffectivityBehaviourHelper(EffectivityBehaviourEnum.ALWAYS_VISIT); + } + + /** + * Construct an TcEffectivity Behaviour which only visits Parts with UNIT effectivity. + * + * @return the {@link EffectivityBehaviourHelper}. + */ + public static EffectivityBehaviourHelper visitOnlyUnitManagedParts() { + return new EffectivityBehaviourHelper(EffectivityBehaviourEnum.ONLY_UNIT_MANAGED); + } + + private static boolean referencesUnit(final String blConfigString) { + return UNIT_EFFECTIVITY_PATTERN.matcher(blConfigString).matches(); + } + + /** + * Returns true if the {@link BOMLineHolder} should be visited based on the behaviour specified and the effectivity list provided.
    + * Mostly used for {@link BOMLineHolder}s holding a RF Part because these objects might have both Unit and Date effectivity.
    + * The available behaviours are the following: + *
      + *
    • ALWAYS_VISIT.
    • + *
    • ONLY_UNIT_MANAGED.
    • + *
    • ONLY_DATE_MANAGED.
    • + *
    + * + * @param aBomLineHolder the {@link BOMLineHolder} to investigate + * @return true if the object should be visited, false otherwise + */ + public boolean shouldVisit(final BOMLineHolder aBomLineHolder) { + final String blConfigString = aBomLineHolder.getBomConfig(); // The reason this bomLine is here, explained by Tc in a String + if (blConfigString == null || blConfigString.isEmpty()) { + return true; // Unknown effectivity, keep the bomLine by default + } + boolean result; + switch (behaviour) { + case ALWAYS_VISIT: + result = true; + break; + case ONLY_DATE_MANAGED: + result = !referencesUnit(blConfigString); + break; + case ONLY_UNIT_MANAGED: + result = referencesUnit(blConfigString); + break; + default: + result = true; + break; + } + return result; + } + + /** + * Desired behaviour regarding effectivities. + */ + private enum EffectivityBehaviourEnum { + /** + * Always visit regardless of effectivities. + */ + ALWAYS_VISIT, + /** + * Only visit if the object is managed in units. + */ + ONLY_UNIT_MANAGED, + /** + * Only visit if the object is managed with date effectivities. + */ + ONLY_DATE_MANAGED + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/releasestatus/RevisionSelector.java b/teamcenter/src/main/java/com/capgemini/reports/releasestatus/RevisionSelector.java new file mode 100644 index 0000000..8835f7f --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/releasestatus/RevisionSelector.java @@ -0,0 +1,23 @@ +package com.capgemini.reports.releasestatus; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import java.io.Serializable; + +/** + * This interface provides an algorithm which can chose a specific Revision of an Item. + */ +public interface RevisionSelector extends Serializable { + + /** + * Returns the correct {@link ItemRevision} of the {@link Item}.
    + * The exact algorithm for selecting the Revision must be coded inside this method.
    + * + * @param session the Tc session + * @param item the {@link Item} for which we need to find a Revision + * @return ItemRevision the selected Revision + */ + RevisionStatusAndDate selectRevision(final TcSession session, final Item item); +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/releasestatus/RevisionStatusAndDate.java b/teamcenter/src/main/java/com/capgemini/reports/releasestatus/RevisionStatusAndDate.java new file mode 100644 index 0000000..0a681f9 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/releasestatus/RevisionStatusAndDate.java @@ -0,0 +1,20 @@ +package com.capgemini.reports.releasestatus; + +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.ReleaseStatus; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Calendar; + +/** + * POJO container for an {@link ItemRevision}, which was elected because of one of its {@link ReleaseStatus} or {@link Calendar}. + */ +@AllArgsConstructor +@Getter +public class RevisionStatusAndDate { + private final Calendar releaseDate; + private final ReleaseStatus releaseStatus; + private final ItemRevision itemRevision; + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/DualGenerics.java b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/DualGenerics.java new file mode 100644 index 0000000..9bd214e --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/DualGenerics.java @@ -0,0 +1,50 @@ +package com.capgemini.reports.reports.parameters; + +import java.io.Serializable; + +/** + * This class carries a Product and both a Generic and a Generic Assemb below, for comparison.
    + * This class is able to present a design vue or an assembly view. + * + */ +public class DualGenerics implements Serializable { + + private static final long serialVersionUID = -2761749803279516469L; + + private final Generics generic; + private final Generics genericAssemb; + + /** + * Construct object contain generic and genericAssemb and productUnit. + * + * @param productUnit a {@link ProductUnit} + * @param genericID a Generic ID + * @param genericAssembID a Generic Assemb ID + */ + public DualGenerics(final ProductUnit productUnit, final String genericID, final String genericAssembID) { + super(); + this.generic = new Generics(productUnit, genericID, ""); + this.genericAssemb = new Generics(productUnit, "", genericAssembID); + + } + + /** + * Return generic view. + * + * @return generic + */ + public Generics asGeneric() { + return generic; + } + + /** + * Return genericAssemb view. + * + * @return genericAssemb + */ + public Generics asGenericAssemb() { + return genericAssemb; + } + + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/EffectivityDate.java b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/EffectivityDate.java new file mode 100644 index 0000000..91e3e0c --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/EffectivityDate.java @@ -0,0 +1,102 @@ +package com.capgemini.reports.reports.parameters; + +import com.capgemini.framework.common.StringHelper; +import com.capgemini.framework.common.TeamcenterDateFormatter; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +import java.io.Serializable; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Locale; +import java.util.TimeZone; + +/** + * Represents a date.
    + * Can represent NOW or a specific date in time. Its {@link Calendar} attribute (dateTime ) may be null to represent 'now'. + * + */ +@Getter +@EqualsAndHashCode +public class EffectivityDate implements Serializable { + + private static final long serialVersionUID = -5328049346240627147L; + + /** Is null when {@code isNow == true}. */ + private final Calendar dateTime; + private final boolean now; + + /** + * Creates a date. If the Calendar is null, the date will be the current date. + * + * @param dateTime the Calendar date + */ + public EffectivityDate(final Calendar dateTime) { + super(); + this.now = dateTime == null; + this.dateTime = dateTime; + } + + /** + * Creates a date. If the input String is null or empty, the date will be the current date. + * + * @param date the date with format : dd-MM-yyyy. + */ + public EffectivityDate(final String date) { + this.now = date == null || date.isEmpty(); + this.dateTime = now ? null : TeamcenterDateFormatter.makeTeamcenterCalendar(date); + } + + /** Creates a {@link EffectivityDate} representing the current time. */ + public EffectivityDate() { + super(); + this.dateTime = null; + this.now = true; + } + + /** + * Returns a String representation of this effectivity in a format that Tc can recognize in a query.
    + * Ex {@code 09-Feb-2015} + * + * @return the date as a {@link String}, using {@link Locale#US} + */ + public String getFormattedDateForTcRequest() { + return TeamcenterDateFormatter.translateDateFormatForRequest(dateTime); + } + + /** + * Returns a String representation of this effectivity in a format that a French User can understand.
    + * Uses : {@code dd mmmm yyyy} and {@link TimeZone}: Europe (Paris) and french Locale. Ex: {@code 08 Juillet 2015} + * + * @return the date as a {@link String}, using {@link Locale#US} + */ + public String getFormattedDateForFrenchUser() { + return TeamcenterDateFormatter.formatCalendarToFrench(now ? Calendar.getInstance() : dateTime); + } + + /** + * Format date with the GUI format: dd-MM-yyyy. + * + * @return String value of date + */ + public String formatAsInputCriteria() { + + String theFormatedDate = StringHelper.EMPTY; + + if (dateTime != null) { + SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy", Locale.FRENCH); + sdf.setTimeZone(TeamcenterDateFormatter.getParisTimeZone()); + theFormatedDate = sdf.format(dateTime.getTime()); + } + + return theFormatedDate; + } + + @Override + public String toString() { + return "TcEffectivity date : " + (now ? "now" : dateTime.getTime().toString()); + } + + + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/Generics.java b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/Generics.java new file mode 100644 index 0000000..ad5060b --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/Generics.java @@ -0,0 +1,197 @@ +package com.capgemini.reports.reports.parameters; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemQuery; +import com.capgemini.reports.exceptions.NotFoundException; +import com.teamcenter.soa.client.model.strong.Item; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.util.List; + +/** + * This class gathers information about a product (+unit), and optionally a generic or a generic assemb.
    + * This class allows either:
    + *
      + *
    • A product and its unit
    • + *
    • A product, its unit, and a Generic that exists under this product
    • + *
    • A product, its unit, and a GenericAssemb that exists under this product
    • + *
    + */ +@Slf4j +@Getter +@EqualsAndHashCode +public class Generics implements Serializable { + + private static final long serialVersionUID = 2362411651537951479L; + private static final String GENERIC_BOM = "GenericBom"; + private static final String ASSEMBLY_BOM = "AssemblyBom"; + private static final String TECHNICAL_BOM = "TechnicalBom"; + private final String generic; + private final String genericAssemb; + private final String revision; + private final ProductUnit productUnit; + private final GenericType type; + + + /** + * Constructs a {@link Generics}. + * + * @param productUnit a {@link ProductUnit} (mandatory) + * @param genericID (may be null) + * @param genericAssembID (may be null) + */ + public Generics(final ProductUnit productUnit, final String genericID, final String genericAssembID) { + super(); + this.productUnit = productUnit; + if (genericID != null && !genericID.isEmpty()) { + this.type = GenericType.GENERIC; + this.generic = genericID; + this.genericAssemb = null; + } else { + if (genericAssembID != null && !genericAssembID.isEmpty()) { + this.type = GenericType.GENERIC_ASSEMB; + this.generic = null; + this.genericAssemb = genericAssembID; + } else { + this.type = GenericType.ONLY_PRODUCT; + this.generic = null; + this.genericAssemb = null; + } + } + // The parameter revision is not used via this constructor. + this.revision = null; + } + + /** + * Constructs a {@link Generics} Revision. + * + * @param productUnit a {@link ProductUnit} (mandatory) + * @param genericID (may be null) + * @param genericAssembID (may be null) + * @param genericRevision (may be null) the revision of the Generic + */ + public Generics(final ProductUnit productUnit, final String genericID, final String genericAssembID, final String genericRevision) { + super(); + this.productUnit = productUnit; + if (genericID != null && !genericID.isEmpty()) { + this.type = GenericType.GENERIC; + this.generic = genericID; + this.genericAssemb = null; + } else { + if (genericAssembID != null && !genericAssembID.isEmpty()) { + this.type = GenericType.GENERIC_ASSEMB; + this.generic = null; + this.genericAssemb = genericAssembID; + } else { + this.type = GenericType.ONLY_PRODUCT; + this.generic = null; + this.genericAssemb = null; + } + } + this.revision = genericRevision; + } + + /** + * Returns the corresponding Teamcenter {@link Item} (a product, Generic or Generic Assemb). + * + * @param session the {@link TcSession} to perform the query. + * @return the {@link Item} representing the item. + * @throws NotFoundException if no reults were found + */ + public Item getItem(final TcSession session) throws NotFoundException { + ItemQuery savedQuery = new ItemQuery(session); + switch (this.type) { + case GENERIC: + savedQuery.searchID(generic); + break; + case GENERIC_ASSEMB: + savedQuery.searchID(genericAssemb); + break; + case ONLY_PRODUCT: + savedQuery.searchID(productUnit.getProductID()); + break; + default: + String msg = "Undefined Generics state: cannot obtain the ItemRevision"; + log.error(msg); + throw new NotFoundException(msg); + } + List results = savedQuery.findAll(); + if (results == null || results.isEmpty()) { + throw new NotFoundException("No Generic found with the provided ID"); + } + return results.get(0); + } + + /** + * Returns the corresponding item ID (of the product, Generic or Generic Assemb). + * + * @return the item ID + */ + public String getID() { + String returnStr; + switch (this.type) { + case GENERIC: + returnStr = generic; + break; + case GENERIC_ASSEMB: + returnStr = genericAssemb; + break; + case ONLY_PRODUCT: + returnStr = productUnit.getProductID(); + break; + default: + log.warn("Undefined Generics state: cannot select an itemID"); + returnStr = ""; + break; + } + return returnStr; + } + + @Override + public String toString() { + String returnStr; + switch (type) { + case GENERIC: + returnStr = "Generic: " + generic; + break; + case GENERIC_ASSEMB: + returnStr = "Generic Assemb: " + genericAssemb; + break; + case ONLY_PRODUCT: + returnStr = "No Generics selected, using father Product: " + productUnit.getProductID(); + break; + default: + returnStr = "Undefined Generics state: defaulting to father Product: " + productUnit.getProductID(); + break; + } + return returnStr; + } + + /** + * Represents a Product-Unit, and some optional Generic or GenericAssemb under it. + */ + @Getter + public enum GenericType { + /** + * Represents only a product-unit. Follows a BomView named "TechnicalBom". + */ + ONLY_PRODUCT(TECHNICAL_BOM), + /** + * Represents a product-unit and a generic under it. Follows a BomView named "GenericBOM". + */ + GENERIC(GENERIC_BOM), + /** + * Represents a product-unit and a genericAssemb under it. Follows a BomView named "AssemblyBOM". + */ + GENERIC_ASSEMB(ASSEMBLY_BOM); + + private final String bomLinkType; + + GenericType(final String bomLinkType) { + this.bomLinkType = bomLinkType; + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/IChecker.java b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/IChecker.java new file mode 100644 index 0000000..51fbe00 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/IChecker.java @@ -0,0 +1,20 @@ +package com.capgemini.reports.reports.parameters; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.exceptions.InvalidUserInputException; + +/** + * Represents some required checks for the report parameters.
    + * This interface offers a {@link #check(TcSession)} method which will validate the user inputs. + */ +public interface IChecker { + + /** + * This method performs checks on the validity of the user inputs.
    + * + * @param session the {@link TcSession} to be used to check data from the Teamcenter servers. + * @throws InvalidUserInputException a {@link InvalidUserInputException} must be raised when the check has failed. + */ + void check(final TcSession session) throws InvalidUserInputException; + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/MonoMulti.java b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/MonoMulti.java new file mode 100644 index 0000000..71bf34d --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/MonoMulti.java @@ -0,0 +1,28 @@ +package com.capgemini.reports.reports.parameters; + +/** + * This class represent the choice of using mono-level or multi-level BOM explosion. + * + */ +public enum MonoMulti { + /** The MONO type of resolution structure. */ + MONO, + /** The MULTI type of resolution structure. */ + MULTI; + + /** + * Constructs a {@link MonoMulti} according to user input. + * + * @param input a String containing the user input. + * @return the {@link MonoMulti} + */ + public static MonoMulti build(final String input) { + // Checking mono-multi + if ("multi".equalsIgnoreCase(input)) { + return MULTI; + } + else { + return MONO; + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/ProductUnit.java b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/ProductUnit.java new file mode 100644 index 0000000..90274fd --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/ProductUnit.java @@ -0,0 +1,106 @@ +package com.capgemini.reports.reports.parameters; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemQuery; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; + +/** + * Represents a Product-unit association.
    + */ +@Slf4j +@EqualsAndHashCode +public class ProductUnit implements Serializable { + private static final long serialVersionUID = -2970983080244741025L; + + private static final String EMPTY = ""; + + private final String productID; + + /** + * This is the raw user input String. + */ + private final String unitStr; + + /** + * This is the validated user input integer. + */ + private int unit; + + public ProductUnit(String productID) { + this(productID, null); + } + + /** + * Basic constructor. + * + * @param productID the ID of the product + * @param unit a unit + */ + public ProductUnit(final String productID, final int unit) { + super(); + this.productID = productID; + this.unit = unit; + this.unitStr = String.valueOf(unit); + } + + /** + * Basic constructor. + * + * @param productID the ID of the product + * @param unitStr a unit (String representation) + */ + public ProductUnit(final String productID, final String unitStr) { + super(); + this.productID = productID == null ? EMPTY : productID; + this.unitStr = unitStr == null ? EMPTY : unitStr; + } + + /** + * Parse the unit String. After the parsing, the integer unit becomes available for further processing. + * + * @throws InvalidUserInputException if the unit could not be understood + */ + public void parseUserUnit() throws InvalidUserInputException { + try { + this.unit = Integer.parseInt(unitStr); + } catch (NumberFormatException e) { + UserInputErrorEnum unitNotNumeric = UserInputErrorEnum.UNIT_NOT_NUMERIC; + log.error(unitNotNumeric.getMsgEn() + ": \"" + unitStr + "\" ", e); + throw new InvalidUserInputException(unitNotNumeric, e); + } + } + + /** + * Returns the corresponding Teamcenter item (a product, Generic or Generic Assemb). + * + * @param session the {@link TcSession} to perform the query. + * @return the {@link ItemRevision} representing the end item. + */ + public Item getProduct(final TcSession session) { + return new ItemQuery(session).searchID(productID).findAll().get(0); + } + + public String getProductID() { + return productID; + } + + public int getUnit() { + return unit; + } + + public String getUnitStr() { + return unitStr; + } + + @Override + public String toString() { + return productID + "-" + unitStr; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/SuperModel.java b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/SuperModel.java new file mode 100644 index 0000000..418f319 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/SuperModel.java @@ -0,0 +1,116 @@ +package com.capgemini.reports.reports.parameters; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemQuery; +import com.capgemini.reports.exceptions.NotFoundException; +import com.teamcenter.soa.client.model.strong.Item; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.util.List; + +/** + * This class gathers information about a product (+unit), and optionally a generic or a generic assemb.
    + * This class allows either:
    + *
      + *
    • A product and its unit
    • + *
    • A product, its unit, and a Generic that exists under this product
    • + *
    • A product, its unit, and a GenericAssemb that exists under this product
    • + *
    + */ +@Slf4j +@Getter +@EqualsAndHashCode +public class SuperModel implements Serializable { + + private static final long serialVersionUID = 2362411651537951479L; + private static final String GENERIC_BOM = "GenericBom"; + private static final String ASSEMBLY_BOM = "AssemblyBom"; + private static final String TECHNICAL_BOM = "TechnicalBom"; + private final String supermodel; + private final String revision; + private final ProductUnit productUnit; + + + /** + * Constructs a {@link SuperModel}. + * + * @param productUnit a {@link ProductUnit} (mandatory) + * @param supermodel (mandatory) + */ + public SuperModel(final ProductUnit productUnit, final String supermodel) { + super(); + this.productUnit = productUnit; + this.supermodel = supermodel; + // The parameter revision is not used via this constructor. + this.revision = null; + } + + /** + * Constructs a {@link SuperModel} Revision. + * + * @param productUnit a {@link ProductUnit} (mandatory) + * @param supermodel (may be null) + * @param revision (may be null) the revision of the Supermodel + */ + public SuperModel(final ProductUnit productUnit, final String supermodel, final String revision) { + super(); + this.productUnit = productUnit; + this.supermodel = supermodel; + this.revision = revision; + } + + /** + * Returns the corresponding Teamcenter {@link Item} (a product, Generic or Generic Assemb). + * + * @param session the {@link TcSession} to perform the query. + * @return the {@link Item} representing the item. + * @throws NotFoundException if no reults were found + */ + public Item getItem(final TcSession session) throws NotFoundException { + ItemQuery savedQuery = new ItemQuery(session); + savedQuery.searchID(supermodel); + List results = savedQuery.findAll(); + if (results == null || results.isEmpty()) { + throw new NotFoundException("No Super Model found with the provided ID"); + } + return results.get(0); + } + + /** + * Represents a Product-Unit, and some optional Generic or GenericAssemb under it. + */ + @Getter + public enum GenericType { + /** + * Represents only a product-unit. Follows a BomView named "TechnicalBom". + */ + ONLY_PRODUCT(TECHNICAL_BOM), + /** + * Represents a product-unit and a generic under it. Follows a BomView named "GenericBOM". + */ + GENERIC(GENERIC_BOM), + /** + * Represents a product-unit and a genericAssemb under it. Follows a BomView named "AssemblyBOM". + */ + GENERIC_ASSEMB(ASSEMBLY_BOM); + + private final String bomLinkType; + + GenericType(final String bomLinkType) { + this.bomLinkType = bomLinkType; + } + } + + + /** + * Returns the corresponding item ID (of the product, Generic or Generic Assemb). + * + * @return the item ID + */ + public String getID() { + return supermodel; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/EffectivityChecker.java b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/EffectivityChecker.java new file mode 100644 index 0000000..3115cda --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/EffectivityChecker.java @@ -0,0 +1,37 @@ +package com.capgemini.reports.reports.parameters.checker; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.reports.parameters.IChecker; +import lombok.extern.slf4j.Slf4j; + +import java.util.Calendar; + +/** + * Checks is a given {@link EffectivityDate} is in a valid state. + */ +@Slf4j +public class EffectivityChecker implements IChecker { + + private final EffectivityDate effectivity; + + /** + * Builds a {@link IChecker} to verify the validity of the provided {@link EffectivityDate}. + */ + public EffectivityChecker(final EffectivityDate effectivity) { + this.effectivity = effectivity; + } + + @Override + public void check(final TcSession session) throws InvalidUserInputException { + if (!effectivity.isNow()) { + Calendar dateTime = effectivity.getDateTime(); + if (dateTime == null) { + log.error("EffectivityDate state is invalid: Calendar is null but TcEffectivity is not NOW."); + throw new InvalidUserInputException(UserInputErrorEnum.INTERNAL_ERROR); + } + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/GenericConditionR21Checker.java b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/GenericConditionR21Checker.java new file mode 100644 index 0000000..713cd6a --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/GenericConditionR21Checker.java @@ -0,0 +1,89 @@ +package com.capgemini.reports.reports.parameters.checker; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.reports.parameters.DualGenerics; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.teamcenter.ObjectInfoHelper; +import com.capgemini.reports.teamcenter.ObjectInfoLoader; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import java.util.List; + +/** + * Checks some conditions on a Generic for the R21 report. + */ +public class GenericConditionR21Checker implements IChecker { + + private final ProductUnit productUnit; + private final DualGenerics dualGenerics; + + /** + * Define productUnit and dualGenerics configuration. + * + * @param productUnit a {@link ProductUnit} + * @param dualGenerics a {@link DualGenerics} + */ + public GenericConditionR21Checker(final ProductUnit productUnit, final DualGenerics dualGenerics) { + this.productUnit = productUnit; + this.dualGenerics = dualGenerics; + } + + + @Override + public void check(final TcSession session) throws InvalidUserInputException { + checkGenericConditionR21(session); + checkGenericAssembConditionR21(session); + } + + private void checkGenericConditionR21(final TcSession session) throws InvalidUserInputException { + + // Parse user input + productUnit.parseUserUnit(); + int userUnit = productUnit.getUnit(); + + ObjectInfoLoader objectInfoLoader = new ObjectInfoLoader(session); + // Get existing units in Database + try { + List genericsRevision = objectInfoLoader.getGenericUnderProduct(dualGenerics.asGeneric(), productUnit); + if (genericsRevision == null || genericsRevision.isEmpty()) { + throw new InvalidUserInputException(UserInputErrorEnum.GENERIC_DOES_NOT_EXIST); + } + boolean isGenericHasAnUnitRevision = ObjectInfoHelper.getClosestGenerics(session, dualGenerics.asGeneric().getID(), userUnit, genericsRevision); + + if (!isGenericHasAnUnitRevision) { + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_PRODUCT_AND_UNIT); + } + } catch (NotFoundException e) { + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_PRODUCT_AND_UNIT, e); + } + + } + + private void checkGenericAssembConditionR21(final TcSession session) throws InvalidUserInputException { + // Parse user input + productUnit.parseUserUnit(); + int userUnit = productUnit.getUnit(); + + ObjectInfoLoader objectInfoLoader = new ObjectInfoLoader(session); + // Get existing units in Database + try { + List genericsAssembRevision = objectInfoLoader.getGenericAssembUnderProduct(dualGenerics.asGenericAssemb(), productUnit); + if (genericsAssembRevision == null || genericsAssembRevision.isEmpty()) { + throw new InvalidUserInputException(UserInputErrorEnum.GENERIC_ASSEMB_DOES_NOT_EXIST); + } + boolean isGenericHasAnUnitRevision = + ObjectInfoHelper.getClosestGenerics(session, dualGenerics.asGenericAssemb().getID(), userUnit, genericsAssembRevision); + + if (!isGenericHasAnUnitRevision) { + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_PRODUCT_AND_UNIT); + } + } catch (NotFoundException e) { + throw new InvalidUserInputException(UserInputErrorEnum.NO_DATA_COULD_BE_EXTRACTED_FOR_GENERIC_PRODUCT_AND_UNIT, e); + } + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/GenericExistenceChecker.java b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/GenericExistenceChecker.java new file mode 100644 index 0000000..aef5785 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/GenericExistenceChecker.java @@ -0,0 +1,64 @@ +package com.capgemini.reports.reports.parameters.checker; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemQuery; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.reports.parameters.Generics; +import com.capgemini.reports.reports.parameters.IChecker; +import com.teamcenter.soa.client.model.strong.Item; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +/** + * This class checks if a Generics (which represents a Generic and/or GenericAssemb) exists within the TC database. + */ +@Slf4j +public class GenericExistenceChecker implements IChecker { + + protected final Generics generics; + + public GenericExistenceChecker(final Generics generics) { + this.generics = generics; + } + + @Override + public void check(final TcSession session) throws InvalidUserInputException { + switch (generics.getType()) { + case GENERIC: + genericExists(session); + break; + case GENERIC_ASSEMB: + genericAssembExists(session); + break; + case ONLY_PRODUCT: + break; + default: + log.error("Unsupported Enum value"); + break; + } + } + + protected void genericExists(final TcSession session) throws InvalidUserInputException { + List list = new ItemQuery(session).searchID(generics.getGeneric()).searchGeneric().findAll(); + if (list == null || list.isEmpty()) { + throw new InvalidUserInputException(getTechnicalErrorMsg()); + } + } + + protected UserInputErrorEnum getTechnicalErrorMsg() { + return UserInputErrorEnum.GENERIC_DOES_NOT_EXIST; + } + + private void genericAssembExists(final TcSession session) throws InvalidUserInputException { + List list = new ItemQuery(session).searchID(generics.getGenericAssemb()).searchGenericAssemb().findAll(); + if (list == null || list.isEmpty()) { + throw new InvalidUserInputException(getAssemblyErrorMsg()); + } + } + + private UserInputErrorEnum getAssemblyErrorMsg() { + return UserInputErrorEnum.GENERIC_ASSEMB_DOES_NOT_EXIST; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/GenericUnderProductUnitChecker.java b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/GenericUnderProductUnitChecker.java new file mode 100644 index 0000000..a46a5e1 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/GenericUnderProductUnitChecker.java @@ -0,0 +1,98 @@ +package com.capgemini.reports.reports.parameters.checker; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.reports.parameters.Generics; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.teamcenter.ObjectInfoLoader; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +/** + * This class checks if a {@link Generics}' Generic and/or GenericAssemb exist under the {@link Generics}' Product-Unit. + */ +@Slf4j +public class GenericUnderProductUnitChecker implements IChecker { + + private final Generics generics; + + /** + * Simple Constructor. + * + * @param generic the {@link Generics} + */ + public GenericUnderProductUnitChecker(final Generics generic) { + this.generics = generic; + } + + @Override + public void check(final TcSession session) throws InvalidUserInputException { + switch (generics.getType()) { + case GENERIC: + genericExists(session); + break; + case GENERIC_ASSEMB: + genericAssembExists(session); + break; + case ONLY_PRODUCT: + break; + default: + log.error("Unsupported Enum value, defaulting to ONLY_PRODUCT"); + break; + } + } + + /** + * Checks the generic ID. + */ + private boolean genericExists(final TcSession session) throws InvalidUserInputException { + ProductUnit productUnit = generics.getProductUnit(); + String thisGeneric = generics.getGeneric(); + try { + List genericsFound = new ObjectInfoLoader(session).getGenericsRevisionOfProduct(productUnit); + for (String existingGeneric : genericsFound) { + if (thisGeneric.equals(existingGeneric)) { + return true; + } + } + log.error("No Generic found with ID \"{}\" for productUnit={}", thisGeneric, productUnit); + log.error(" + Existing Generic IDs: {}", genericsFound); + throw new InvalidUserInputException(getTechnicalErrorMessage()); + } catch (NotFoundException e) { + throw new InvalidUserInputException(getTechnicalErrorMessage(), e); + } + } + + private UserInputErrorEnum getTechnicalErrorMessage() { + return UserInputErrorEnum.PRODUCT_UNIT_GENERIC_INVALID; + } + + /** + * Checks the generic Assemb ID. + */ + private boolean genericAssembExists(final TcSession session) throws InvalidUserInputException { + ProductUnit productUnit = generics.getProductUnit(); + String genericAssemb = generics.getGenericAssemb(); + try { + List genericsAssemb = new ObjectInfoLoader(session).getGenericsAssembliesRevisionOfProduct(productUnit); + for (String existingGenericAssemb : genericsAssemb) { + if (genericAssemb.equals(existingGenericAssemb)) { + return true; + } + } + log.error("No Generic Assemb found with ID \"{}\" for productUnit={}", genericAssemb, productUnit); + log.error(" + Existing GenericAssemb IDs: {}", genericsAssemb); + throw new InvalidUserInputException(getAssemblyErrorMessage()); + } catch (NotFoundException e) { + throw new InvalidUserInputException(getAssemblyErrorMessage(), e); + } + } + + private UserInputErrorEnum getAssemblyErrorMessage() { + return UserInputErrorEnum.PRODUCT_UNIT_GENERIC_ASSEMB_INVALID; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/ModelObjectChecker.java b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/ModelObjectChecker.java new file mode 100644 index 0000000..5c82f14 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/ModelObjectChecker.java @@ -0,0 +1,64 @@ +package com.capgemini.reports.reports.parameters.checker; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.teamcenter.queries.DirectQuery; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import java.util.regex.Pattern; + + +/** This class checks if a ModelObject exists by looking for its uid in Teamcenter. */ +public class ModelObjectChecker implements IChecker { + + private final String[] typePatterns; + private final String objectUID; + + /** + * Constructs a checker that verifies if the type of the ModelObject whose UID is provided matches any of the type filters.
    + * Note: the provided types maybe Item Master or Item Revision Types.
    + * Note2: At least one filter element must be provided. + * + * @param objectUID String UID of the ModelObject + * @param typeFilters the allowed types. Each must be an {@link Item}'s Type or {@link ItemRevision}'s type (i.e. 'DocNorm' or 'DocDrawing Revision')... + */ + public ModelObjectChecker(final String objectUID, final String... typeFilters) { + this.objectUID = objectUID; + this.typePatterns = new String[typeFilters.length]; + + for (int num = 0; num < typeFilters.length; num++) { + this.typePatterns[num] = ".*" + typeFilters[num] + ".*"; + } + } + + @Override + public void check(final TcSession session) throws InvalidUserInputException { + if (typePatterns.length == 0) { + throw new InvalidUserInputException("No Type pattern was specified"); // Should never happen: one must not build a checker without at least one filter element + } + + ModelObject modelObject; + try { + modelObject = new DirectQuery<>(session).searchByUID(objectUID); + } + catch (NotFoundException e) { + throw new InvalidUserInputException(UserInputErrorEnum.OBJECT_DOES_NOT_EXIST, e); + } + + String actualType = modelObject.getTypeObject().getName(); + + for (String type : typePatterns) { + if (Pattern.matches(type, actualType)) { + return; // Type is ok + } + } + // If we findAll here type is not authorised + throw new InvalidUserInputException(UserInputErrorEnum.TYPE_DOCUMENT_SELECTED_NOT_AUTHORIZED); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/ObjectTypeChecker.java b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/ObjectTypeChecker.java new file mode 100644 index 0000000..c6d6a76 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/ObjectTypeChecker.java @@ -0,0 +1,63 @@ +package com.capgemini.reports.reports.parameters.checker; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemQuery; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.reports.parameters.IChecker; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import java.util.List; +import java.util.regex.Pattern; + +/** + * Checks if the provided itemId belongs to one of the types provided.
    + * Note: the provided types must be Item Types, not ItemRevision types (i.e. 'PartAero' or 'Standard' are ok, but not 'PartAero Revision'. + */ +public class ObjectTypeChecker implements IChecker { + + private final String itemId; + private final String[] typePatterns; + + /** + * Constructs a checker tht verifies if the type of the Item whose ID is provided matches any of the type filters.
    + * Note: the provided types must be Item Types, not ItemRevision types (i.e. 'PartAero' or 'Standard' are ok, but not 'PartAero Revision'.
    + * Note2: At least one filter element must be provided. + * + * @param itemId the Id of the Item + * @param typeFilters the provided types. Each must be {@link Item} Type, not {@link ItemRevision} type (i.e. 'PartAero' or 'Standard' are ok, but not 'PartAero Revision'. + */ + public ObjectTypeChecker(final String itemId, final String... typeFilters) { + this.itemId = itemId; + this.typePatterns = new String[typeFilters.length]; + for (int num = 0; num < typeFilters.length; num++) { + this.typePatterns[num] = ".*" + typeFilters[num] + ".*"; + } + } + + @Override + public void check(final TcSession session) throws InvalidUserInputException { + if (typePatterns.length == 0) { + throw new InvalidUserInputException("No Type pattern was specified"); // Should never happen: one must not build a checker without at least one filter element + } + List items = new ItemQuery(session).searchID(itemId).findAll(); + if (items == null || items.isEmpty()) { + throw new InvalidUserInputException(getErrorMessage()); + } + for(Item item : items) { + String actualType = item.getTypeObject().getName(); + for (String type : typePatterns) { + if (Pattern.matches(type, actualType)) { + return; // Type is ok + } + } + } + // If we findAll here type is not authorised + throw new InvalidUserInputException(getErrorMessage()); + } + + protected UserInputErrorEnum getErrorMessage() { + return UserInputErrorEnum.THE_SELECTED_OBJECT_IS_NOT_PERMITTED_ON_THIS_REPORT; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/ProductChecker.java b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/ProductChecker.java new file mode 100644 index 0000000..50c4cd6 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/ProductChecker.java @@ -0,0 +1,47 @@ +package com.capgemini.reports.reports.parameters.checker; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemQuery; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.reports.parameters.IChecker; +import com.teamcenter.soa.client.model.strong.Item; +import lombok.Getter; + +import java.util.List; + +/** + * This class checks if a product exists by looking for its ID in Teamcenter. + */ +public class ProductChecker implements IChecker { + + private final String productID; + @Getter + private Item product; + + /** + * Simple constructor. + * + * @param aProductID a String + */ + public ProductChecker(final String aProductID) { + productID = aProductID; + } + + @Override + public void check(final TcSession session) throws InvalidUserInputException { + if (productID == null || productID.isEmpty()) { + throw new InvalidUserInputException(getErrorMsg()); + } + List queryObjects = new ItemQuery(session).searchID(productID).searchProduct().findAll(); + if ((queryObjects == null) || (queryObjects.isEmpty())) { + throw new InvalidUserInputException(getErrorMsg()); + } else { + product = queryObjects.get(0); + } + } + + private UserInputErrorEnum getErrorMsg() { + return UserInputErrorEnum.PRODUCT_DOES_NOT_EXIST_NO_DATA_TO_PRINT; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/ProductUnitChecker.java b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/ProductUnitChecker.java new file mode 100644 index 0000000..f2fbf1f --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/ProductUnitChecker.java @@ -0,0 +1,80 @@ +package com.capgemini.reports.reports.parameters.checker; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.teamcenter.ObjectInfoLoader; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +/** + * This class checks if a a given Product-Unit is valid.
    + * It checks weather: + *
      + *
    • The provided unit is parseable to a numeric value
    • + *
    • The product ID provided points to a product
    • + *
    • The product has a matching unit number
    • + *
    + */ +@Slf4j +public class ProductUnitChecker implements IChecker { + + private final ProductUnit productUnit; + + /** + * Simple constructor. + * + * @param productUnit the {@link ProductUnit} to be checked. + */ + public ProductUnitChecker(final ProductUnit productUnit) { + this.productUnit = productUnit; + } + + @Override + public void check(final TcSession session) throws InvalidUserInputException { + String productID = productUnit.getProductID(); + UserInputErrorEnum productAndUnitDoesNotExist = getErrorMessage(); + try { + // Parse user input + productUnit.parseUserUnit(); + int userUnit = productUnit.getUnit(); + + // Get existing units in Database + List units = new ObjectInfoLoader(session).getUnitsOfProduct(productID); + + // check if the user input Unit exists in the list returned by Tc + for (String existingTcUnitStr : units) { + int tcUnit = parseTeamcenterUnit(existingTcUnitStr); + if (userUnit == tcUnit) { + // Found a matching unit, test passed + return; + } + } + // The check has failed if it gets here + log.error(productAndUnitDoesNotExist.getMsgEn()); + log.error("Existing units for this product ({}): {}", productID, units); + throw new InvalidUserInputException(productAndUnitDoesNotExist); + } catch (NotFoundException e) { + throw new InvalidUserInputException(getErrorMessage(), e); + + } + } + + protected UserInputErrorEnum getErrorMessage() { + return UserInputErrorEnum.PRODUCT_AND_UNIT_DOES_NOT_EXIST; + } + + private int parseTeamcenterUnit(final String tcUnitStr) throws InvalidUserInputException { + try { + return Integer.parseInt(tcUnitStr); + } catch (NumberFormatException e) { + log.error("Teamcenter returned a non-parseable unit String : \"" + tcUnitStr + "\"", e); + throw new InvalidUserInputException(UserInputErrorEnum.INTERNAL_ERROR, e); + } + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/ProductUnitGenericChecker.java b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/ProductUnitGenericChecker.java new file mode 100644 index 0000000..2ed0c34 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/ProductUnitGenericChecker.java @@ -0,0 +1,110 @@ +package com.capgemini.reports.reports.parameters.checker; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.changeobjects.UnitRevision; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.snecmaobjects.generic.AbstractGenericRevision; +import com.capgemini.reports.teamcenter.ObjectInfoHelper; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_UNIT; + +/** + * This class checks if a a given Product-Unit-Generic is valid. + */ +@Slf4j +public class ProductUnitGenericChecker implements IChecker { + + private final String genericId; + private final ProductUnit productUnit; + + /** + * Constructor. + * + * @param genericId String - the generic Id + * @param productUnit {@link ProductUnit} + */ + public ProductUnitGenericChecker(final String genericId, final ProductUnit productUnit) { + this.genericId = genericId; + this.productUnit = productUnit; + } + + private static List transformArray(final ModelObject[] objects) { + List newList = new ArrayList<>(); + for (ModelObject object : objects) { + newList.add((ItemRevision) object); + } + return newList; + } + + @Override + public void check(final TcSession session) throws InvalidUserInputException { + productUnit.parseUserUnit(); + + // Find the product + List productRevisions = new ItemRevisionQuery(session).searchID(productUnit.getProductID()).findAll(); + if (productRevisions == null || productRevisions.isEmpty()) { + throw new InvalidUserInputException( + UserInputErrorEnum.WRONG_EFFECTIVITY_THE_PRODUCT_DOES_NOT_EXIST_OR_THE_UNIT_DOES_NOT_EXIST_FOR_THE_PRODUCT); + } + ItemRevision product = productRevisions.get(0); // Only one revision of Product + + // Find the units of the product + session.loadProperties(product, PV_UNIT); + ModelObject[] objects = product.getPropertyObject(PV_UNIT).getModelObjectArrayValue(); + session.loadProperties(objects); + if (objects == null || objects.length == 0) { + throw new InvalidUserInputException( + UserInputErrorEnum.WRONG_EFFECTIVITY_THE_PRODUCT_DOES_NOT_EXIST_OR_THE_UNIT_DOES_NOT_EXIST_FOR_THE_PRODUCT); + } + + // Find Unit Revision + List result = UnitRevision.getItemRevisionWithSameRange(session, productUnit.getUnitStr(), transformArray(objects)); + if (result.isEmpty()) { + throw new InvalidUserInputException( + UserInputErrorEnum.WRONG_EFFECTIVITY_THE_PRODUCT_DOES_NOT_EXIST_OR_THE_UNIT_DOES_NOT_EXIST_FOR_THE_PRODUCT); + } + + // Find Generic Revision + List generics = getGenericItemRevision(session); + if (generics == null) { + throw new InvalidUserInputException(UserInputErrorEnum.INTERNAL_ERROR); + } + if (generics.isEmpty()) { + throw new InvalidUserInputException(UserInputErrorEnum.GENERIC_DOES_NOT_EXIST_OR_ENTRY_EFFECTIVITY_IS_NOT_COMPATIBLE_WITH_THE_GENERIC); + } + } + + /** + * Get the appropriate Generic Revision. + * + * @param session TcSession + * @return ItemRevision the generic revision + * @throws InvalidUserInputException for the throwable exception + */ + private List getGenericItemRevision(final TcSession session) throws InvalidUserInputException { + if (!AbstractGenericRevision.isGenericRevision(genericId)) { + throw new InvalidUserInputException(UserInputErrorEnum.GENERIC_DOES_NOT_EXIST_OR_ENTRY_EFFECTIVITY_IS_NOT_COMPATIBLE_WITH_THE_GENERIC); + } + + List genericRevisions = new ItemRevisionQuery(session).searchID(genericId).findAll(); + + // Keep only the ItemRevision whose end item is the Product + List checkedGenerics = ObjectInfoHelper.getRevisionWithSameEndItem(session, genericRevisions, productUnit.getProductID()); + genericRevisions.clear(); + + // Compare effectivities + List results = ObjectInfoHelper.getRevisionWithHighestRange(session, checkedGenerics, productUnit.getUnitStr()); + checkedGenerics.clear(); + return results; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/UnitRevisionChecker.java b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/UnitRevisionChecker.java new file mode 100644 index 0000000..c865811 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/reports/parameters/checker/UnitRevisionChecker.java @@ -0,0 +1,131 @@ +package com.capgemini.reports.reports.parameters.checker; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.reports.parameters.IChecker; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.teamcenter.ObjectInfoLoader; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Effectivity; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.ReleaseStatus; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; + +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.EFFECTIVITY; + +/** + * This class checks if a given UnitRevision is valid for a R20 report.
    + * It assumes that the Product and the unit exist (using a {@link ProductUnitChecker}.
    + * It fails if the unit does not have an effectivity matching the product ID. + */ +@Slf4j +public class UnitRevisionChecker implements IChecker { + + @Getter(value = AccessLevel.PROTECTED) + private final ProductUnit productUnit; + + /** + * Simple constructor. + * + * @param productUnit the {@link ProductUnit Product and the Unit} that need to be checked. + */ + public UnitRevisionChecker(final ProductUnit productUnit) { + this.productUnit = productUnit; + } + + @Override + public final void check(final TcSession session) throws InvalidUserInputException { + checkUnits(session); + } + + protected List checkUnits(final TcSession session) throws InvalidUserInputException { + String productID = productUnit.getProductID(); + + // Parse user input + productUnit.parseUserUnit(); + int userUnit = productUnit.getUnit(); + + // Get existing units in Database + List units = checkUnitsOfProduct(session); // Fails if none found + + // Check if the user-input Unit exists in the list returned by Tc + // No TcEffectivity could be found with matching end_item ID and a matching unit range: the check has FAILED, let's throw the correct Exception to explain Why + return checkUnitsOfProductInRange(session, productID, userUnit, units); + } + + private List checkUnitsOfProduct(final TcSession session) throws InvalidUserInputException { + try { + List theUnits = new ObjectInfoLoader(session).getUnitsOfProduct(productUnit); + if (theUnits.isEmpty()) { + throw unitNotAssociatedToProduct(); + } + return theUnits; + } catch (NotFoundException e) { + throw new InvalidUserInputException(UserInputErrorEnum.PRODUCT_AND_UNIT_DOES_NOT_EXIST, e); + } + } + + private List checkUnitsOfProductInRange(final TcSession session, final String productID, final int userUnit, final List existingUnits) + throws InvalidUserInputException { + List unitsInRange = new ArrayList<>(); + for (ItemRevision existingTcUnit : existingUnits) { + session.loadProperties(existingTcUnit, "release_status_list"); + ReleaseStatus[] releaseStatuses = existingTcUnit.get_release_status_list(); + session.loadProperties(releaseStatuses); + if (unitHasEffectivityInRange(session, releaseStatuses, productID, userUnit)) { + unitsInRange.add(existingTcUnit); + } + } + if (unitsInRange.isEmpty()) { + throw unitNotAssociatedToProduct(); + } else { + return unitsInRange; + } + } + + private boolean unitHasEffectivityInRange(final TcSession session, final ReleaseStatus[] releaseStatusList, final String productID, int userUnit) { + for (ReleaseStatus releaseStatus : releaseStatusList) { + if (!EFFECTIVITY.equals(releaseStatus.get_name())) { + continue; // skip + } + session.loadProperties(releaseStatus, "effectivities"); + ModelObject[] effectivities = releaseStatus.get_effectivities(); + session.loadProperties(effectivities); + for (ModelObject effectivityMO : effectivities) { + Effectivity effectivity = (Effectivity) effectivityMO; + session.loadProperties(effectivity, "end_item"); + Item endItem = effectivity.get_end_item(); + session.loadProperties(endItem); + if (endItem.get_item_id().equals(productID) && sameUnit(effectivity.get_unit_range_text(), userUnit)) { + // This Unit Revision has an effectivity with a matching end item and unit range! the test is PASSED + return true; + } + } + } + return false; + } + + protected InvalidUserInputException unitNotAssociatedToProduct() { + UserInputErrorEnum productAndUnitDoesNotExist = UserInputErrorEnum.PRODUCT_AND_UNIT_DOES_NOT_EXIST; + log.error(productAndUnitDoesNotExist.getMsgEn()); + return new InvalidUserInputException(productAndUnitDoesNotExist); + } + + protected InvalidUserInputException errorMessage() { + UserInputErrorEnum productAndUnitDoesNotExist = UserInputErrorEnum.PRODUCT_AND_UNIT_DOES_NOT_EXIST; + log.error(productAndUnitDoesNotExist.getMsgEn()); + return new InvalidUserInputException(productAndUnitDoesNotExist); + } + + private boolean sameUnit(final String tcUnitStr, final int userUnit) { + return Integer.valueOf(tcUnitStr) == userUnit; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/AbstractSnecmaObject.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/AbstractSnecmaObject.java new file mode 100644 index 0000000..ca0363e --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/AbstractSnecmaObject.java @@ -0,0 +1,352 @@ +package com.capgemini.reports.snecmaobjects; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.object.pom.status.TcReleaseStatus; +import com.capgemini.framework.teamcenter.resolution.filtering.ITcTypeFilter; +import com.capgemini.reports.documentationobjects.AbstractDoc; +import com.capgemini.reports.documentationobjects.DocFactory; +import com.capgemini.reports.releasestatus.RevisionSelector; +import com.capgemini.reports.releasestatus.RevisionStatusAndDate; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Form; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.ReleaseStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static com.capgemini.framework.teamcenter.TeamcenterObjectProperties.TC_IS_REPRESENTED_BY; +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.*; + +/** + * Abstract class which centralize the methods of all the SnecmaObject. + */ +public abstract class AbstractSnecmaObject implements ISnecmaObject { + private static final long serialVersionUID = -9057538534616767099L; + protected final TcSession session; + protected final ItemRevision itemRevision; + + private Form itemMasterForm; + private List statuses; + private Form itemMasterFormRev; + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSnecmaObject.class); + + public AbstractSnecmaObject(final TcSession session, final ItemRevision itemRevision) { + this.session = session; + this.itemRevision = itemRevision; + } + + @Override + public String getType() { + return itemRevision.getTypeObject().getName(); + } + + @Override + public String getItemId() { + return itemRevision.get_item_id(); + } + + @Override + public String getRevisionId() { + return itemRevision.get_item_revision_id(); + } + + @Override + public String getName() { + return itemRevision.get_object_name(); + } + + protected Form getMasterForm() { + if (itemMasterForm == null) { + session.loadProperties(itemRevision, "items_tag"); + Item item = itemRevision.get_items_tag(); + session.loadProperties(item, "item_master_tag"); + itemMasterForm = item.get_item_master_tag(); + session.loadProperties(itemMasterForm); + } + return itemMasterForm; + } + + protected Form getMasterFormRev() { + if (itemMasterFormRev == null) { + itemMasterFormRev = itemRevision.get_item_master_tag(); + session.loadProperties(itemMasterFormRev); + } + return itemMasterFormRev; + } + + /** + * Method to get the modelObject representing the 'Spare Part' Form if it existed. + * Else return null + * */ + public ModelObject getSparePartsForm() { + session.loadProperties(itemRevision, "IMAN_specification"); + ModelObject[] formArray = itemRevision.get_IMAN_specification(); + session.loadProperties(formArray); + for (ModelObject form : formArray) { + if (form != null && "Spare Parts".equals(form.getTypeObject().getName())) { + return form; + } + } + return null; + } + + public boolean hasStatus(final StatusEnum... statuses) { + for (TcReleaseStatus releaseStatus : getStatusList()) { + if (releaseStatus.isOneOf(statuses)) { + return true; + } + } + return false; + } + + public List getStatusList() { + if (statuses == null) { + statuses = new ArrayList<>(); + session.loadProperties(itemRevision, "release_status_list"); + ReleaseStatus[] releaseStatuses = itemRevision.get_release_status_list(); + session.loadProperties(releaseStatuses); + for (ReleaseStatus releaseStatus : releaseStatuses) { + TcReleaseStatus tcReleaseStatus = new TcReleaseStatus(session, releaseStatus); + statuses.add(tcReleaseStatus); + } + } + return statuses; + } + + public List getDefinitionDocumentsOfTypes(final ITcTypeFilter typesFilter, final Map docCache) { + List definitionDocuments = new ArrayList<>(); + session.loadProperties(itemRevision, PV_DEFINITION_DOCS); + ModelObject[] definitionDocObjects = itemRevision.getPropertyObject(PV_DEFINITION_DOCS).getModelObjectArrayValue(); + session.loadProperties(definitionDocObjects); + for (ModelObject definitionDocObject : definitionDocObjects) { + String docType = definitionDocObject.getTypeObject().getName(); + if (typesFilter.isIncluded(docType)) { + definitionDocuments.add(getAbstractDoc((ItemRevision) definitionDocObject, docCache)); + } + } + + return definitionDocuments; + } + + public List getRepresentedDocumentsOfTypes(final ITcTypeFilter typesFilter, final Map docCache) { + List representedDocuments = new ArrayList<>(); + session.loadProperties(itemRevision, TC_IS_REPRESENTED_BY); + ModelObject[] representedDocObjects = itemRevision.getPropertyObject(TC_IS_REPRESENTED_BY).getModelObjectArrayValue(); + session.loadProperties(representedDocObjects); + for (ModelObject representedDocObject : representedDocObjects) { + String docType = representedDocObject.getTypeObject().getName(); + if (typesFilter.isIncluded(docType)) { + representedDocuments.add(getAbstractDoc((ItemRevision) representedDocObject, docCache)); + } + } + + return representedDocuments; + } + + /** + * Returns all the ChangeRequests of the CR pseudo-folder as a list of ModelObjects + */ + public List getCRPseudoFolderContent() { + List crRelatedList = new ArrayList<>(); + session.loadProperties(itemRevision, PV4_RUNTIME_CR_RELATED); + ModelObject[] crRelatedArray = itemRevision.getPropertyObject(PV4_RUNTIME_CR_RELATED).getModelObjectArrayValue(); + session.loadProperties(crRelatedArray); + for (ModelObject cr : crRelatedArray) { + crRelatedList.add(cr); + } + return crRelatedList; + } + + /** + * Returns all the ChangeNotices of the CN pseudo-folder as a list of ModelObjects + */ + public List getCNPseudoFolderContent() { + List cnRelatedList = new ArrayList<>(); + session.loadProperties(itemRevision, PV4_RUNTIME_CN_RELATED); + ModelObject[] cnRelatedArray = itemRevision.getPropertyObject(PV4_RUNTIME_CN_RELATED).getModelObjectArrayValue(); + session.loadProperties(cnRelatedArray); + for (ModelObject cr : cnRelatedArray) { + cnRelatedList.add(cr); + } + return cnRelatedList; + } + + /** + * Returns all the Reference documents. + */ + public List getReferenceDocumentsOfTypes(final ITcTypeFilter typesFilter, final RevisionSelector revisionSelector, final Map docCache) { + List referencedDocuments = new ArrayList<>(); + session.loadProperties(itemRevision, PV_REFERENCE_DOCS); + ModelObject[] referencedDocObjects = itemRevision.getPropertyObject(PV_REFERENCE_DOCS).getModelObjectArrayValue(); + session.loadProperties(referencedDocObjects); + for (ModelObject representedDocObject : referencedDocObjects) { + String docType = representedDocObject.getTypeObject().getName(); + if (typesFilter.isIncluded(docType)) { + referencedDocuments.add(getAbstractDoc(revisionSelector, (Item) representedDocObject, docCache)); + } + } + return referencedDocuments; + } + + private AbstractDoc getAbstractDoc(final RevisionSelector revisionSelector, final Item docItem, final Map docCache) { + AbstractDoc cachedDoc = docCache.get(docItem.getUid()); + if (cachedDoc == null) { + RevisionStatusAndDate revisionStatusAndDate = revisionSelector.selectRevision(session, docItem); + AbstractDoc abstractDoc = DocFactory.build(session, revisionStatusAndDate.getItemRevision()); + docCache.put(docItem.getUid(), abstractDoc); + return abstractDoc; + } else { + return cachedDoc; + } + } + + private AbstractDoc getAbstractDoc(final ItemRevision docRev, final Map docCache) { + AbstractDoc cachedDoc = docCache.get(docRev.getUid()); + if (cachedDoc == null) { + AbstractDoc abstractDoc = DocFactory.build(session, docRev); + docCache.put(docRev.getUid(), abstractDoc); + return abstractDoc; + } else { + return cachedDoc; + } + } + + public String getCRPseudoFolderContentAsString() { + StringBuilder stringBuilder = new StringBuilder(); + try { + List CRList = getCRPseudoFolderContent(); + for (ModelObject CR : CRList) { + if (stringBuilder.length() != 0) { + stringBuilder.append(";"); + } + stringBuilder.append(CR.getPropertyObject(ITEM_ID).getStringValue()); + } + } catch (Exception e) { + LOGGER.debug("Error during Searching CR of component Id [{}] Revision [{}] : [{}]", getItemId(), getRevisionId(), e.getMessage()); + } + return stringBuilder.toString(); + } + + public String getCNPseudoFolderContentAsString() { + StringBuilder stringBuilder = new StringBuilder(); + try { + List CNList = getCNPseudoFolderContent(); + for (ModelObject CN : CNList) { + if (stringBuilder.length() != 0) { + stringBuilder.append(";"); + } + stringBuilder.append(CN.getPropertyObject(ITEM_ID).getStringValue()); + } + } catch (Exception e) { + LOGGER.debug("Error during Searching CN of component Id [{}] Revision [{}] : [{}]", getItemId(), getRevisionId(), e.getMessage()); + } + return stringBuilder.toString(); + } + + /** + * Return true if it is a Admin. + * + * @return the boolean + */ + @Override + public boolean isAdmin() { + return false; + } + + /** + * Return true if it is a Generic. + * + * @return the boolean + */ + @Override + public boolean isGeneric() { + return false; + } + + + /** + * Return true if it is a Super Model. + * + * @return the boolean + */ + @Override + public boolean isSuperModel() { + return false; + } + + /** + * Return true if it is a Part. + * + * @return the boolean + */ + @Override + public boolean isPart() { + return false; + } + + /** + * Return true if it is a RF. + * + * @return the boolean + */ + @Override + public boolean isRF() { + return false; + } + + /** + * Return true if it is a RF Generic. + * + * @return the boolean + */ + @Override + public boolean isRFGeneric() { + return false; + } + + /** + * Return true if it is a RF Part or RF Part Assemb. + * + * @return the boolean + */ + @Override + public boolean isRFPartOrPartAssemb() { + return false; + } + + /** + * Return true if it is a MockUp. + * + * @return the boolean + */ + @Override + public boolean isMockup() { + return false; + } + + /** + * Return true if it is a Product. + * + * @return the boolean + */ + @Override + public boolean isProduct() { + return false; + } + + @Override + public boolean isDescriptif() { + return false; + } + + @Override + public String toString() { + return getType() + " with ID= " + getItemId() + " with REVISION= " + getRevisionId(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/ISnecmaObject.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/ISnecmaObject.java new file mode 100644 index 0000000..7e65fdb --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/ISnecmaObject.java @@ -0,0 +1,121 @@ +package com.capgemini.reports.snecmaobjects; + +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; + +import java.io.Serializable; + +/** + * Interface representing all the objects. + */ +public interface ISnecmaObject extends Serializable { + + /** + * All the SnecmaObjects must accept the Receptor visitor to make the different reports. + */ + T accept(final IReceptorVisitor aReceptorVisitor); + + /** + * All the SnecmaObjects must accept the Component visitor to make the different reports. + */ + T accept(final IComponentVisitor aComponentVisitor); + + /** + * Getter for the type of the SnecmaObject. + * + * @return the type + */ + String getType(); + + /** + * Getter for the Name of the SnecmaObject. + * + * @return the Name + */ + String getName(); + + /** + * Getter for the Revision of the SnecmaObject. + * + * @return the Revision + */ + String getRevisionId(); + + /** + * Getter for the Id of the SnecmaObject. + * + * @return the Id + */ + String getItemId(); + + /** + * Return true if it is a Admin. + * + * @return the boolean + */ + boolean isAdmin(); + + /** + * Return true if it is a Generic. + * + * @return the boolean + */ + boolean isGeneric(); + + /** + * Return true if it is a SuperModel. + * + * @return the boolean + */ + boolean isSuperModel(); + + /** + * Return true if it is a Part. + * + * @return the boolean + */ + boolean isPart(); + + /** + * Return true if it is a RF. + * + * @return the boolean + */ + boolean isRF(); + + /** + * Return true if it is a RF Generic. + * + * @return the boolean + */ + boolean isRFGeneric(); + + /** + * Return true if it is a RF Part or a RF Part Assemb. + * + * @return the boolean + */ + boolean isRFPartOrPartAssemb(); + + /** + * Return true if it is a Product. + * + * @return the boolean + */ + boolean isProduct(); + + /** + * Return true if it is a Descriptif. + * + * @return the boolean + */ + boolean isDescriptif(); + + /** + * Return true if it is a MockUp. + * + * @return the boolean + */ + boolean isMockup(); + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/SnecmaObjectFactory.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/SnecmaObjectFactory.java new file mode 100644 index 0000000..d28a783 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/SnecmaObjectFactory.java @@ -0,0 +1,96 @@ +package com.capgemini.reports.snecmaobjects; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.exceptions.NotSupportedException; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAGRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision; +import com.capgemini.reports.snecmaobjects.generic.*; +import com.capgemini.reports.snecmaobjects.mockup.MockupRevision; +import com.capgemini.reports.snecmaobjects.part.*; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartAssembRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartRevision; +import com.capgemini.reports.snecmaobjects.supermodel.SuperModelRevision; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.*; + +/** + * Factory used for create a structured SnecmaObject (set as null by default). + */ +public class SnecmaObjectFactory { + + protected SnecmaObjectFactory() { + // Nothing to do, just making this private + } + + /** + * Build an object from an {@link Item}. + */ + public static AbstractGeneric build(final TcSession session, final Item item) throws NotSupportedException { + switch (item.getTypeObject().getName()) { + case GENERIC: + return new Generic(session, item); + case GENERIC_ASSEMB: + return new GenericAssemb(session, item); + default: + throw new NotSupportedException("Expected ObjectType was not created, 'type' property was not available!"); + } + } + + /** + * Factory which create the structure of the SnecmaObjects from an {@link ItemRevision}. + */ + public static AbstractSnecmaObject build(final TcSession session, final ItemRevision itemRevision) + throws NotSupportedException { + switch (itemRevision.getTypeObject().getName()) { + case ALTERNATE_REVISION: + return new AlternateRevision(session, itemRevision); + case DESCRIPTIF_REVISION: + return new DescriptifRevision(session, itemRevision); + case DET_REVISION: + return new DETRevision(session, itemRevision); + case GENERIC_ASSEMB_REVISION: + return new GenericAssembRevision(session, itemRevision); + case GENERIC_REVISION: + return new GenericRevision(session, itemRevision); + case SUPERMODEL_REVISION: + return new SuperModelRevision(session, itemRevision); + case MOCKUP_REVISION: + return new MockupRevision(session, itemRevision); + case PART_AERO_REVISION: + return new PartAeroRevision(session, itemRevision); + case PART_ASSEMB_REVISION: + return new PartAssembRevision(session, itemRevision); + case PART_MAT_REVISION: + return new PartMatRevision(session, itemRevision); + case PART_NO_AERO_REVISION: + return new PartNoAeroRevision(session, itemRevision); + case PRODUCT_REVISION: + return new ProductRevision(session, itemRevision); + case RF_ADMIN_AG_REVISION: + return new RFAdminAGRevision(session, itemRevision); + case RF_ADMIN_AP_REVISION: + return new RFAdminAPRevision(session, itemRevision); + case RF_ADMIN_A_REVISION: + return new RFAdminARevision(session, itemRevision); + case RF_ADMIN_REVISION: + return new RFAdminRevision(session, itemRevision); + case RF_GENERIC_REVISION: + return new RFGenericRevision(session, itemRevision); + case RF_PART_ASSEMB_REVISION: + return new RFPartAssembRevision(session, itemRevision); + case RF_PART_REVISION: + return new RFPartRevision(session, itemRevision); + case STANDARD_REVISION: + return new StandardRevision(session, itemRevision); + default: + throw new NotSupportedException("Expected ObjectType was not created, 'type' property was not available!"); + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/admin/AbstractAdmin.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/admin/AbstractAdmin.java new file mode 100644 index 0000000..5b77bfe --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/admin/AbstractAdmin.java @@ -0,0 +1,22 @@ +package com.capgemini.reports.snecmaobjects.admin; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.AbstractSnecmaObject; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +/** + * Abstract class representing all the Admin. + */ +public abstract class AbstractAdmin extends AbstractSnecmaObject { + private static final long serialVersionUID = -2526585943770080825L; + + public AbstractAdmin(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + @Override + public boolean isAdmin() { + return true; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/admin/RFAdminAGRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/admin/RFAdminAGRevision.java new file mode 100644 index 0000000..75937ec --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/admin/RFAdminAGRevision.java @@ -0,0 +1,49 @@ +package com.capgemini.reports.snecmaobjects.admin; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_TRANSFERT_LIEN_LOGISTI; +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_TRANSFERT_LIEN_MONTAGE; +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.RF_ADMIN_AG_REVISION; + +/** + * Class representing a RFAdminAGRevision. + */ +public class RFAdminAGRevision extends AbstractAdmin { + private static final long serialVersionUID = -5970076629996941060L; + + public RFAdminAGRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public String getTransfertLienLogisti() { + return getMasterFormRev().getPropertyObject(PV_TRANSFERT_LIEN_LOGISTI).getStringValue(); + } + + public String getTransfertLienMontage() { + return getMasterFormRev().getPropertyObject(PV_TRANSFERT_LIEN_MONTAGE).getStringValue(); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public boolean isSuperModel() { + return false; + } + + @Override + public String toString() { + return RF_ADMIN_AG_REVISION + " " + this.getItemId(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/admin/RFAdminAPRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/admin/RFAdminAPRevision.java new file mode 100644 index 0000000..ea0cbed --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/admin/RFAdminAPRevision.java @@ -0,0 +1,53 @@ +package com.capgemini.reports.snecmaobjects.admin; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.*; +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.RF_ADMIN_AP_REVISION; + +/** + * Class representing a RFAdminAPRevision. + */ +public class RFAdminAPRevision extends AbstractAdmin { + private static final long serialVersionUID = 3507333355590338363L; + + public RFAdminAPRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + + public String getSuiviMontage() { + return getMasterFormRev().getPropertyObject(PV_SUIVI_MONTAGE).getStringValue(); + } + + public String getTransfertLienLogisti() { + return getMasterFormRev().getPropertyObject(PV_TRANSFERT_LIEN_LOGISTI).getStringValue(); + } + + public String getTransfertLienMontage() { + return getMasterFormRev().getPropertyObject(PV_TRANSFERT_LIEN_MONTAGE).getStringValue(); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public boolean isSuperModel() { + return false; + } + + @Override + public String toString() { + return RF_ADMIN_AP_REVISION + " " + this.getItemId(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/admin/RFAdminARevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/admin/RFAdminARevision.java new file mode 100644 index 0000000..70447f1 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/admin/RFAdminARevision.java @@ -0,0 +1,58 @@ +package com.capgemini.reports.snecmaobjects.admin; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.*; + +/** Class representing a RFAdminARevision. */ +public class RFAdminARevision extends AbstractAdmin { + private static final long serialVersionUID = 8090505555455825143L; + + public RFAdminARevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public String getResponsableRepere() { + return getMasterFormRev().getPropertyObject(PV_RESPONSABLE_REPERE).getStringValue(); + } + + public String getSuiviMontage() { + return getMasterFormRev().getPropertyObject(PV_SUIVI_MONTAGE).getStringValue(); + } + + public String getTransfertLienLogisti() { + return getMasterFormRev().getPropertyObject(PV_TRANSFERT_LIEN_LOGISTI).getStringValue(); + } + + public String getTransfertLienMontage() { + return getMasterFormRev().getPropertyObject(PV_TRANSFERT_LIEN_MONTAGE).getStringValue(); + } + + public String getMaqIntExt() { + return getMasterFormRev().getPropertyObject(PV_MAQ_INT_EXT).getStringValue(); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public boolean isSuperModel() { + return false; + } + + @Override + public String toString() { + return SnecmaObjectTypes.RF_ADMIN_A_REVISION + " " + this.getItemId(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/admin/RFAdminRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/admin/RFAdminRevision.java new file mode 100644 index 0000000..a5de2a2 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/admin/RFAdminRevision.java @@ -0,0 +1,93 @@ +package com.capgemini.reports.snecmaobjects.admin; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.*; + +public class RFAdminRevision extends AbstractAdmin { + private static final long serialVersionUID = 4788588575480262344L; + + public RFAdminRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public String getResponsableRepere() { + return getMasterFormRev().getPropertyObject(PV_RESPONSABLE_REPERE).getStringValue(); + } + + public String getFrontiereAvion() { + return getMasterFormRev().getPropertyObject(PV_FRONTIERE_AVION).getStringValue(); + } + + public String getFrontiereCooperant() { + return getMasterFormRev().getPropertyObject(PV_FRONTIERE_COOPERANT).getStringValue(); + } + + public String getMaqIntExt() { + return getMasterFormRev().getPropertyObject(PV_MAQ_INT_EXT).getStringValue(); + } + + public String getGeometriePieceRigide() { + return getMasterFormRev().getPropertyObject(PV_GEOMETRIE_PIECE_RIGIDE).getStringValue(); + } + + public String getGeometrieSimplifiee() { + return getMasterFormRev().getPropertyObject(PV_GEOMETRIE_SIMPLIFIEE).getStringValue(); + } + + public String getTraceAxiale() { + return getMasterFormRev().getPropertyObject(PV_TRACE_AXIALE).getStringValue(); + } + + public String getEnveloppeCinematique() { + return getMasterFormRev().getPropertyObject(PV_ENVELOPPE_CINEMATIQUE).getStringValue(); + } + + public String getEnveloppeMaintenance() { + return getMasterFormRev().getPropertyObject(PV_ENVELOPPE_MAINTENANCE).getStringValue(); + } + + public String getEnveloppeMontage() { + return getMasterFormRev().getPropertyObject(PV_ENVELOPPE_MONTAGE).getStringValue(); + } + + public String getInterfaceRfAdmin() { + return getMasterFormRev().getPropertyObject(PV_INTERFACE_RF_ADMIN).getStringValue(); + } + + public String getProjetMoteur() { + return getMasterFormRev().getPropertyObject(PV_PROJET_MOTEUR).getStringValue(); + } + + public String getMaqEchangeable() { + return getMasterFormRev().getPropertyObject(PV_MAQ_ECHANGEABLE).getStringValue(); + } + + public String getWorkpackage() { + return getMasterFormRev().getPropertyObject(PV_WORKPACKAGE).getStringValue(); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public boolean isSuperModel() { + return false; + } + + @Override + public String toString() { + return SnecmaObjectTypes.RF_ADMIN_REVISION + " " + this.getItemId(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/descriptif/DescriptifRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/descriptif/DescriptifRevision.java new file mode 100644 index 0000000..78bd5fe --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/descriptif/DescriptifRevision.java @@ -0,0 +1,37 @@ +package com.capgemini.reports.snecmaobjects.descriptif; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.AbstractSnecmaObject; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +/** + * Class representing a DescriptifRevision. + */ +public class DescriptifRevision extends AbstractSnecmaObject { + private static final long serialVersionUID = 7170967703658857854L; + + public DescriptifRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public boolean isSuperModel() { + return false; + } + + @Override + public boolean isDescriptif() { + return true; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/generic/AbstractGeneric.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/generic/AbstractGeneric.java new file mode 100644 index 0000000..e18783e --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/generic/AbstractGeneric.java @@ -0,0 +1,42 @@ +package com.capgemini.reports.snecmaobjects.generic; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.teamcenter.soa.client.model.strong.Item; + +public class AbstractGeneric implements Comparable { + private final TcSession session; + private final Item item; + + public AbstractGeneric(final TcSession session, final Item item) { + this.session = session; + this.item = item; + } + + public String getItemId() { + return item.get_item_id(); + } + + + public String getName() { + return item.get_object_name(); + } + + public String getType() { + return item.getTypeObject().getName(); + } + + @Override + public int compareTo(final AbstractGeneric other) { + return this.getItemId().compareTo(other.getItemId()); + } + + @Override + public boolean equals(final Object obj) { + return this == obj || obj instanceof AbstractGeneric && item.equals(((AbstractGeneric) obj).item); + } + + @Override + public int hashCode() { + return item.hashCode(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/generic/AbstractGenericRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/generic/AbstractGenericRevision.java new file mode 100644 index 0000000..0907276 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/generic/AbstractGenericRevision.java @@ -0,0 +1,59 @@ +package com.capgemini.reports.snecmaobjects.generic; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.AbstractSnecmaObject; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.EqualsAndHashCode; + +import java.util.regex.Pattern; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_DESIGNATION_EN; +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_RESPONSABLE_CONCEPTION; + + +/** + * Abstract Class representing a Generic. + */ +@EqualsAndHashCode(callSuper = true) +public abstract class AbstractGenericRevision extends AbstractSnecmaObject implements Comparable { + private static final long serialVersionUID = -190379543546189856L; + + /** + * This pattern identify a {@link GenericRevision} id. + **/ + private static final Pattern REGEX_PATTERN_FOR_GENERIC_REVISION = Pattern.compile("^[A-Z]"); + + public AbstractGenericRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + /** + * Return true if the id correspond to a {@link GenericRevision} id.
    + */ + public static boolean isGenericRevision(final String genId) { + return REGEX_PATTERN_FOR_GENERIC_REVISION.matcher(genId).find(); + } + + public String getDesignationEN() { + return getMasterFormRev().getPropertyObject(PV_DESIGNATION_EN).getStringValue(); + } + + public String getResponsableConception() { + return getMasterFormRev().getPropertyObject(PV_RESPONSABLE_CONCEPTION).getStringValue(); + } + + @Override + public int compareTo(final AbstractGenericRevision other) { + int compareID = this.getItemId().compareTo(other.getItemId()); + if (compareID != 0) { + return compareID; // Different ID + } else { + return this.getRevisionId().compareTo(other.getRevisionId()); + } + } + + @Override + public boolean isGeneric() { + return true; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/generic/Generic.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/generic/Generic.java new file mode 100644 index 0000000..a982731 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/generic/Generic.java @@ -0,0 +1,11 @@ +package com.capgemini.reports.snecmaobjects.generic; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.teamcenter.soa.client.model.strong.Item; + +public class Generic extends AbstractGeneric { + + public Generic(final TcSession session, final Item item) { + super(session, item); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/generic/GenericAssemb.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/generic/GenericAssemb.java new file mode 100644 index 0000000..f53dc01 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/generic/GenericAssemb.java @@ -0,0 +1,11 @@ +package com.capgemini.reports.snecmaobjects.generic; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.teamcenter.soa.client.model.strong.Item; + +public class GenericAssemb extends AbstractGeneric { + + public GenericAssemb(final TcSession session, final Item item) { + super(session, item); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/generic/GenericAssembRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/generic/GenericAssembRevision.java new file mode 100644 index 0000000..dd2a9b2 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/generic/GenericAssembRevision.java @@ -0,0 +1,39 @@ +package com.capgemini.reports.snecmaobjects.generic; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +/** + * Class representing a GenericAssembRevision. + */ +public class GenericAssembRevision extends AbstractGenericRevision { + private static final long serialVersionUID = 74761594141269461L; + + public GenericAssembRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public boolean isSuperModel() { + return false; + } + + @Override + public String toString() { + return SnecmaObjectTypes.GENERIC_ASSEMB_REVISION + " " + this.getItemId(); + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/generic/GenericRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/generic/GenericRevision.java new file mode 100644 index 0000000..1949608 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/generic/GenericRevision.java @@ -0,0 +1,32 @@ +package com.capgemini.reports.snecmaobjects.generic; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +/** + * Class representing a RFAdminAGRevision. + */ +public class GenericRevision extends AbstractGenericRevision { + private static final long serialVersionUID = 4530714427862196578L; + + public GenericRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public String toString() { + return getType() + " " + this.getItemId(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/mockup/MockupRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/mockup/MockupRevision.java new file mode 100644 index 0000000..5a21981 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/mockup/MockupRevision.java @@ -0,0 +1,42 @@ +package com.capgemini.reports.snecmaobjects.mockup; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.AbstractSnecmaObject; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_COHERENCE_CONTROL; + +/** Class representing a MockupRevision. */ +public class MockupRevision extends AbstractSnecmaObject { + private static final long serialVersionUID = 5130249672177145816L; + + public MockupRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public String getCoherenceControl() { + return getMasterFormRev().getPropertyObject(PV_COHERENCE_CONTROL).getStringValue(); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public boolean isSuperModel() { + return false; + } + + @Override + public boolean isMockup() { + return true; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/AbstractAltOrDetRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/AbstractAltOrDetRevision.java new file mode 100644 index 0000000..4526fc2 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/AbstractAltOrDetRevision.java @@ -0,0 +1,52 @@ +package com.capgemini.reports.snecmaobjects.part; + + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.ISnecmaObject; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import java.util.ArrayList; +import java.util.List; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_FOURNISSEURS; + +/** + * Class representing a AlternateRevision or a DETRevision. + */ +public abstract class AbstractAltOrDetRevision extends AbstractPart { + private static final long serialVersionUID = -1534372886540642285L; + private final List pseudoFolder = new ArrayList<>(); + + public AbstractAltOrDetRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public String[] getLstFournisseurs() { + return itemRevision.getPropertyObject(PV_FOURNISSEURS).getStringArrayValue(); + } + + /** + * Adds a {@link ISnecmaObject} to the list of elements found in the pseudo-folder. + */ + public void addInPseudoFolder(final AbstractPart obj) { + pseudoFolder.add(obj); + } + + public void clearPseudoFolder() { + this.pseudoFolder.clear(); + } + + public List getPseudoFolder() { + return pseudoFolder; + } + + @Override + public String toString() { + String superString = super.toString(); + if (pseudoFolder.isEmpty()) { + return superString; + } else { + return superString + ", pseudoFolder with " + pseudoFolder.size() + " elements"; + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/AbstractPart.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/AbstractPart.java new file mode 100644 index 0000000..f15b5af --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/AbstractPart.java @@ -0,0 +1,320 @@ +package com.capgemini.reports.snecmaobjects.part; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.releasestatus.RevisionStatusAndDate; +import com.capgemini.reports.snecmaobjects.AbstractSnecmaObject; +import com.capgemini.reports.teamcenter.ObjectInfoHelper; +import com.google.common.base.Joiner; +import com.google.common.base.Optional; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.*; + +/** + * Abstract Class representing a Part. + */ +@Slf4j +public abstract class AbstractPart extends AbstractSnecmaObject { + private static final long serialVersionUID = 3469538869012990375L; + + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractPart.class); + + public AbstractPart(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + /** + * Return the list of the definition documents of a Part.
    + * Via the pseudofolder "Documents de définition". + */ + public static List returnDefinitionDocuments(final TcSession session, final ItemRevision partRev) { + List listDefinitionDoc = new ArrayList<>(); + session.loadProperties(partRev, PV_DEFINITION_DOCS); + ModelObject[] definitionDocObjects = partRev.getPropertyObject(PV_DEFINITION_DOCS).getModelObjectArrayValue(); + session.loadProperties(definitionDocObjects); + for (ModelObject definitionDocObject : definitionDocObjects) { + if (definitionDocObject == null) { + log.warn("A Null ModelObject was obtained from the pseudo-folder '_PV_definition_docs' of a Part."); + continue; + } + listDefinitionDoc.add((ItemRevision) definitionDocObject); + } + return listDefinitionDoc; + } + + /** + * Return the list of the reference documents of a Part.
    + * Via the pseudofolder "Documents de référence". + */ + public static List returnReferenceDocuments(final TcSession session, final ItemRevision partRev) { + List listReferenceDoc = new ArrayList<>(); + session.loadProperties(partRev, PV_REFERENCE_DOCS); + ModelObject[] referenceDocObjects = partRev.getPropertyObject(PV_REFERENCE_DOCS).getModelObjectArrayValue(); + session.loadProperties(referenceDocObjects); + for (ModelObject referenceDocObject : referenceDocObjects) { + if (referenceDocObject == null) { + log.warn("A Null ModelObject was obtained from the pseudo-folder '_PV_reference_docs' of a Part."); + continue; + } + listReferenceDoc.add((Item) referenceDocObject); + } + return listReferenceDoc; + } + + /** + * Return the list of the represented documents of a Part.
    + * Via the pseudofolder "Represented by". + */ + public static List returnRepresentedDocuments(final TcSession session, final ItemRevision partRev) { + List listRepresentedDoc = new ArrayList<>(); + session.loadProperties(partRev, TC_IS_REPRESENTED_BY); + ModelObject[] representedDocObjects = partRev.getPropertyObject(TC_IS_REPRESENTED_BY).getModelObjectArrayValue(); + session.loadProperties(representedDocObjects); + for (ModelObject representedDocObject : representedDocObjects) { + if (representedDocObject == null) { + log.warn("A Null ModelObject was obtained from the pseudo-folder 'TC_Is_Represented_By' of a Part."); + continue; + } + listRepresentedDoc.add((ItemRevision) representedDocObject); + } + return listRepresentedDoc; + } + + public String getDesignationEN() { + return getMasterFormRev().getPropertyObject(PV_DESIGNATION_EN).getStringValue(); + } + + public String getRefCompleteConcepteur() { + return getMasterFormRev().getPropertyObject(PV_REF_COMPLETE_CONCEPTEUR).getStringValue(); + } + + public String getRefTransposeeSnecma() { + return getMasterFormRev().getPropertyObject(PV_REF_TRANSPO_SNECMA).getStringValue(); + } + + public String getResponsableConception() { + return getMasterFormRev().getPropertyObject(PV_RESPONSABLE_CONCEPTION).getStringValue(); + } + + public String getClassement() { + return getMasterFormRev().getPropertyObject(PV_CLASSEMENT).getStringValue(); + } + + public String getSuiviUtilisation() { + return getMasterFormRev().getPropertyObject(PV_SUIVI_UTILISATION).getStringValue(); + } + + public String getSuiviDureeVie() { + return getMasterFormRev().getPropertyObject(PV_SUIVI_DUREE_VIE).getStringValue(); + } + + public double getDureeVie() { + return getMasterFormRev().getPropertyObject(PV_DUREE_VIE).getIntValue(); + } + + public String getUniteDureeVie() { + return getMasterFormRev().getPropertyObject(PV_UNITE_DUREE_VIE).getStringValue(); + } + + public Double getMass() { + return getMasterFormRev().getPropertyObject(PV_MASSE_INDICATIVE).getDoubleValue(); + } + + public String getMassUnit() { + return getMasterFormRev().getPropertyObject(PV_UNITE_MASSE).getStringValue(); + } + + public String getDocumentControle() { + return getMasterFormRev().getPropertyObject(PV_DOCUMENT_CONTROLE).getStringValue(); + } + + public String getRefAssociee() { + return getMasterFormRev().getPropertyObject(PV_REF_ASSOCIEE).getStringValue(); + } + + public String getSuiviDeveloppement() { + return getMasterFormRev().getPropertyObject(PV_SUIVI_DEVELOPPEMENT).getStringValue(); + } + + public String getTypeProduit() { + return getMasterFormRev().getPropertyObject(PV_TYPE_PRODUIT).getStringValue(); + } + + public String getExpirationDate() { + session.loadProperties(getMasterFormRev(), PV4_EXPIRATION_DATE); + return getMasterFormRev().getPropertyObject(PV4_EXPIRATION_DATE).getStringValue(); + } + + public String getMotClefEN() { + String value = ""; + if(getSparePartsForm() != null) { + session.loadProperties(getSparePartsForm(), PV_MOT_CLEF_EN); + value = getSparePartsForm().getPropertyObject(PV_MOT_CLEF_EN).getStringValue(); + } + return value; + } + + public String getMotClefFR() { + String value = ""; + if(getSparePartsForm() != null) { + session.loadProperties(getSparePartsForm(), PV_MOT_CLEF_FR); + value = getSparePartsForm().getPropertyObject(PV_MOT_CLEF_FR).getStringValue(); + } + return value; + } + + @Override + public boolean isPart() { + return true; + } + + /** + * This method is specific to R19 report + * It gets DocNorms from "Documents de référence" pseudo-folder of the part. + * It checks the value of pv_type_doc_norm properties and returns the pv_id_origine (or item_id if not found) + * of all DMD type docs separated by a coma + **/ + public String getDMD() { + LOGGER.debug("Entering getDMD method"); + List DMDList = new ArrayList<>(); + // Get content of "Documents de référence" pseudo-folder + List documents = returnReferenceDocuments(session, itemRevision); + LOGGER.debug("Number of reference documents : {}", documents.size()); + if (!documents.isEmpty()) { + for (Item docItem : documents) { + if (docItem == null) { + continue; + } + String docType = docItem.getTypeObject().getName(); + String docId = docItem.get_item_id(); + LOGGER.debug("Processing document : {} of type {}", docId, docType); + if (SnecmaObjectTypes.DOC_NORM.equals(docType)) { + // Get the last revision of the DocNorm and check content of pv_type_doc_norm attribute from his master form rev + ItemRevision docNormRevision = getDocNormLastRevision(session, docItem); + if(docNormRevision != null) { + session.loadProperties(docNormRevision, "IMAN_master_form_rev"); + ModelObject[] masterForm = docNormRevision.getPropertyObject("IMAN_master_form_rev").getModelObjectArrayValue(); + session.loadProperties(masterForm, PV_ID_ORIGINE, PV_TYPE_DOC_NORM); + if (masterForm == null || masterForm.length == 0) { + LOGGER.warn("Error while retrieving master form on document {} this document will be ignored.", docId); + continue; + } + String typeDocNorm = masterForm[0].getPropertyObject(PV_TYPE_DOC_NORM).getStringValue(); + LOGGER.debug("pv_type_doc_norm attribute value of doc {} : {}", docId, typeDocNorm); + if (typeDocNorm.contains(DMD_VALUE_OF_TYPE_DOCNORM)) { + LOGGER.debug("PV_ID_ORIGINE attribute value of doc {} : {}", docId, masterForm[0].getPropertyObject(PV_ID_ORIGINE).getStringValue()); + if (masterForm[0].getPropertyObject(PV_ID_ORIGINE) == null || masterForm[0].getPropertyObject(PV_ID_ORIGINE).getStringValue().isEmpty() || masterForm[0].getPropertyObject(PV_ID_ORIGINE).getStringValue() == "") { + LOGGER.debug("docId added to list"); + DMDList.add(docId); + } else { + LOGGER.debug("PV_ID_ORIGINE added to list"); + DMDList.add(masterForm[0].getPropertyObject(PV_ID_ORIGINE).getStringValue()); + } + } + } + } + } + } + LOGGER.debug("DMDList : {}", DMDList); + return Joiner.on(",").join(DMDList); + } + + /** + * This method is specific to R19 report + * It gets DocNorms from "Documents de référence" pseudo-folder of the part. + * It checks the value of pv_type_doc_norm properties and returns the pv_id_origine (or item_id if not found) + * of all DMF type docs separated by a coma + **/ + public String getDMF() { + LOGGER.debug("Entering getDMF method"); + List DMFList = new ArrayList<>(); + // Get content of "Documents de référence" pseudo-folder + List documents = returnReferenceDocuments(session, itemRevision); + LOGGER.debug("Number of reference documents : {}", documents.size()); + if (!documents.isEmpty()) { + for (Item docItem : documents) { + if (docItem == null) { + continue; + } + String docType = docItem.getTypeObject().getName(); + String docId = docItem.get_item_id(); + LOGGER.debug("Processing document : {} of type {}", docId, docType); + if (SnecmaObjectTypes.DOC_NORM.equals(docType)) { + // Get the last revision of the DocNorm and check content of pv_type_doc_norm attribute from his master form rev + ItemRevision docNormRevision = getDocNormLastRevision(session, docItem); + if(docNormRevision != null) { + session.loadProperties(docNormRevision, "IMAN_master_form_rev"); + ModelObject[] masterForm = docNormRevision.getPropertyObject("IMAN_master_form_rev").getModelObjectArrayValue(); + session.loadProperties(masterForm, PV_ID_ORIGINE, PV_TYPE_DOC_NORM); + if (masterForm == null || masterForm.length == 0) { + LOGGER.warn("Error while retrieving master form on document {} this document will be ignored.", docId); + continue; + } + String typeDocNorm = masterForm[0].getPropertyObject(PV_TYPE_DOC_NORM).getStringValue(); + LOGGER.debug("pv_type_doc_norm attribute value of doc {} : {}", docId, typeDocNorm); + if (typeDocNorm.contains(DMF_VALUE_OF_TYPE_DOCNORM)) { + LOGGER.debug("PV_ID_ORIGINE attribute value of doc {} : {}", docId, masterForm[0].getPropertyObject(PV_ID_ORIGINE).getStringValue()); + if (masterForm[0].getPropertyObject(PV_ID_ORIGINE) == null || masterForm[0].getPropertyObject(PV_ID_ORIGINE).getStringValue().isEmpty() || masterForm[0].getPropertyObject(PV_ID_ORIGINE).getStringValue() == "") { + LOGGER.debug("docId added to list"); + DMFList.add(docId); + } else { + LOGGER.debug("PV_ID_ORIGINE added to list"); + DMFList.add(masterForm[0].getPropertyObject(PV_ID_ORIGINE).getStringValue()); + } + } + } + } + } + } + LOGGER.debug("DMFList : {}", DMFList); + return Joiner.on(",").join(DMFList); + } + + /** + * This method determine the last revision of a docNorm/docNormStandard. + * + * @param session A TcSession instance + * @param docItem The id of the document + * @return ItemRevision object representing the revision of the document + **/ + private ItemRevision getDocNormLastRevision(final TcSession session, final Item docItem) { + // Retrieve the revisions + ModelObject[] revisions = docItem.get_revision_list(); + session.loadProperties(revisions); + LOGGER.debug("Doc {} : number of rev in revision_list attribute = {}", docItem.get_item_id(), revisions.length); + // Convert the List of ModelObject to a List of ItemRevision + List listOfDocNormRev = new ArrayList<>(); + for(ModelObject rev : revisions) { + if(rev != null) { + listOfDocNormRev.add((ItemRevision) rev); + } else { + LOGGER.warn("The revision object returned by TC for Doc {} is null. It will be ignored in DMD and DMF columns.", docItem.get_item_id()); + } + } + + // Try to get the revision with the latest release date + if(listOfDocNormRev.size() > 0) { + Optional selectedDocRev = ObjectInfoHelper.getRevisionFromStatusWithMostRecentReleaseDate(session, listOfDocNormRev, Calendar.getInstance(), StatusEnum.PUBLISHED, StatusEnum.FROZEN); + if (selectedDocRev.isPresent()) { + return selectedDocRev.get(); + } else { + // If no release date found, get the revision with latest modification date + RevisionStatusAndDate revAndStatus = ObjectInfoHelper.getRevisionAndStatusWithMostRecentModificationDate(listOfDocNormRev, Calendar.getInstance()); + return revAndStatus.getItemRevision(); + } + } else { + return null; + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/AlternateRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/AlternateRevision.java new file mode 100644 index 0000000..de5b918 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/AlternateRevision.java @@ -0,0 +1,52 @@ +package com.capgemini.reports.snecmaobjects.part; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.*; +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.ALTERNATE_REVISION; + +/** + * Class representing a AlternateRevision. + */ +public class AlternateRevision extends AbstractAltOrDetRevision { + private static final long serialVersionUID = 6488368187302297526L; + + public AlternateRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public String getTypeAlt1() { + return getMasterFormRev().getPropertyObject(PV_TYPE_ALTERNATIVE_1).getStringValue(); + } + + public String getTypeAlt2() { + return getMasterFormRev().getPropertyObject(PV_TYPE_ALTERNATIVE_2).getStringValue(); + } + + public String getObturation() { + return getMasterFormRev().getPropertyObject(PV_OBTURATION).getStringValue(); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public boolean isSuperModel() { + return false; + } + + @Override + public String toString() { + return ALTERNATE_REVISION + " " + this.getItemId(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/DETRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/DETRevision.java new file mode 100644 index 0000000..b7b107a --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/DETRevision.java @@ -0,0 +1,50 @@ +package com.capgemini.reports.snecmaobjects.part; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.*; +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.DET_REVISION; + +public class DETRevision extends AbstractAltOrDetRevision { + private static final long serialVersionUID = -7225493417867464752L; + + public DETRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public String getTypeDet1() { + return getMasterFormRev().getPropertyObject(PV_TYPE_DET_1).getStringValue(); + } + + + public String getTypeDet2() { + return getMasterFormRev().getPropertyObject(PV_TYPE_DET_2).getStringValue(); + } + + public String getObturation() { + return getMasterFormRev().getPropertyObject(PV_OBTURATION).getStringValue(); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public boolean isSuperModel() { + return false; + } + + @Override + public String toString() { + return DET_REVISION + " " + this.getItemId(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/PartAeroRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/PartAeroRevision.java new file mode 100644 index 0000000..60daaf4 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/PartAeroRevision.java @@ -0,0 +1,60 @@ +package com.capgemini.reports.snecmaobjects.part; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.*; + +/** + * Class representing a PartAeroRevision. + */ +public class PartAeroRevision extends AbstractPart { + private static final long serialVersionUID = -3486163177030124825L; + + public PartAeroRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public String getTypeAero1() { + return getMasterFormRev().getPropertyObject(PV_TYPE_PART_AERO_1).getDisplayableValue(); + } + + public String getTypeAero2() { + return getMasterFormRev().getPropertyObject(PV_TYPE_PART_AERO_2).getDisplayableValue(); + } + + public String getTypeAero3() { + return getMasterFormRev().getPropertyObject(PV_TYPE_PART_AERO_3).getDisplayableValue(); + } + + public String getObturation() { + return getMasterFormRev().getPropertyObject(PV_OBTURATION).getStringValue(); + } + + public String[] getLstFournisseurs() { + return itemRevision.getPropertyObject(PV_FOURNISSEURS).getStringArrayValue(); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public boolean isSuperModel() { + return false; + } + + @Override + public String toString() { + return SnecmaObjectTypes.PART_AERO_REVISION + " " + this.getItemId(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/PartAssembRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/PartAssembRevision.java new file mode 100644 index 0000000..19bfc4e --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/PartAssembRevision.java @@ -0,0 +1,49 @@ +package com.capgemini.reports.snecmaobjects.part; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_TYPE_PART_MONTAGE_1; +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_TYPE_PART_MONTAGE_2; +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.PART_ASSEMB_REVISION; + +/** + * Class representing a PartAssembRevision. + */ +public class PartAssembRevision extends AbstractPart { + private static final long serialVersionUID = -296424509222476913L; + + public PartAssembRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public String getTypePartMontage1() { + return getMasterFormRev().getPropertyObject(PV_TYPE_PART_MONTAGE_1).getStringValue(); + } + + public String getTypePartMontage2() { + return getMasterFormRev().getPropertyObject(PV_TYPE_PART_MONTAGE_2).getStringValue(); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public boolean isSuperModel() { + return false; + } + + @Override + public String toString() { + return PART_ASSEMB_REVISION + " " + this.getItemId(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/PartMatRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/PartMatRevision.java new file mode 100644 index 0000000..fd6a3d5 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/PartMatRevision.java @@ -0,0 +1,49 @@ +package com.capgemini.reports.snecmaobjects.part; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_CLASSEMENT_MATIERE; +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_FOURNISSEURS; + +/** + * Class representing a PartMatRevision. + */ +public class PartMatRevision extends AbstractPart { + private static final long serialVersionUID = -3225565405583804909L; + + public PartMatRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public String getClassementMat() { + return getMasterFormRev().getPropertyObject(PV_CLASSEMENT_MATIERE).getStringValue(); + } + + public String[] getLstFournisseurs() { + return itemRevision.getPropertyObject(PV_FOURNISSEURS).getStringArrayValue(); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public boolean isSuperModel() { + return false; + } + + @Override + public String toString() { + return SnecmaObjectTypes.PART_MAT_REVISION + " " + this.getItemId(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/PartNoAeroRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/PartNoAeroRevision.java new file mode 100644 index 0000000..063826e --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/PartNoAeroRevision.java @@ -0,0 +1,44 @@ +package com.capgemini.reports.snecmaobjects.part; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_TYPE_PART_NON_AERO; + +/** + * Class representing a PartNoAeroRevision. + */ +public class PartNoAeroRevision extends AbstractPart { + private static final long serialVersionUID = 6898634008256898679L; + + public PartNoAeroRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public String getTypeNoAero() { + return getMasterFormRev().getPropertyObject(PV_TYPE_PART_NON_AERO).getStringValue(); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public boolean isSuperModel() { + return false; + } + + @Override + public String toString() { + return SnecmaObjectTypes.PART_NO_AERO_REVISION + " " + this.getItemId(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/StandardRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/StandardRevision.java new file mode 100644 index 0000000..96f85fa --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/part/StandardRevision.java @@ -0,0 +1,49 @@ +package com.capgemini.reports.snecmaobjects.part; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_FOURNISSEURS; +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_TYPE_STANDARD; +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.STANDARD_REVISION; + +/** + * Class representing a StandardRevision. + */ +public class StandardRevision extends AbstractPart { + private static final long serialVersionUID = 3254104726494033602L; + + public StandardRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public String[] getLstFournisseurs() { + return itemRevision.getPropertyObject(PV_FOURNISSEURS).getStringArrayValue(); + } + + public String getTypeStandard() { + return getMasterFormRev().getPropertyObject(PV_TYPE_STANDARD).getStringValue(); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public boolean isSuperModel() { + return false; + } + + @Override + public String toString() { + return STANDARD_REVISION + " " + this.getItemId(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/product/ProductRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/product/ProductRevision.java new file mode 100644 index 0000000..2489f9e --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/product/ProductRevision.java @@ -0,0 +1,85 @@ +package com.capgemini.reports.snecmaobjects.product; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.changeobjects.UnitRevision; +import com.capgemini.reports.snecmaobjects.AbstractSnecmaObject; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.EqualsAndHashCode; + +import java.util.ArrayList; +import java.util.List; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.*; +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.PRODUCT_REVISION; +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.UNIT_REVISION; + +/** + * Class representing a ProductRevision. + */ +@EqualsAndHashCode(callSuper = true) +public class ProductRevision extends AbstractSnecmaObject { + private static final long serialVersionUID = 9116577158989990064L; + + public ProductRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + public String getDesignationEN() { + return getMasterFormRev().getPropertyObject(PV_DESIGNATION_EN).getStringValue(); + } + + public String getTypeProduit() { + session.loadProperties(getMasterFormRev(),PV_TYPE_PRODUIT); + return getMasterFormRev().getPropertyObject(PV_TYPE_PRODUIT).getStringValue(); + } + + public String getProductLine() { + return getMasterFormRev().getPropertyObject(PV_LIGNE_PRODUIT).getStringValue(); + } + + public String getDomain() { + return getMasterFormRev().getPropertyObject(PV_DOMAINE).getStringValue(); + } + + public List getUnits() { + List units = new ArrayList<>(); + session.loadProperties(itemRevision, PV_UNIT); + ModelObject[] unitsArray = itemRevision.getPropertyObject(PV_UNIT).getModelObjectArrayValue(); + session.loadProperties(unitsArray); + for (ModelObject unit : unitsArray) { + ItemRevision currentItemRev = (ItemRevision) unit; + if (UNIT_REVISION.equals(currentItemRev.getTypeObject().getName())) { + units.add(UnitRevision.build(session, currentItemRev)); + } + } + return units; + } + + @Override + public boolean isProduct() { + return true; + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public boolean isSuperModel() { + return false; + } + + @Override + public String toString() { + return PRODUCT_REVISION + " " + this.getItemId() + "/" + this.getRevisionId(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/rf/AbstractRF.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/rf/AbstractRF.java new file mode 100644 index 0000000..4ea9bee --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/rf/AbstractRF.java @@ -0,0 +1,27 @@ +package com.capgemini.reports.snecmaobjects.rf; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.AbstractSnecmaObject; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_EQUIVALENT_SNS_SIN; + +/** + * Abstract Class representing a RF. + */ +public abstract class AbstractRF extends AbstractSnecmaObject { + private static final long serialVersionUID = 4005615321655255506L; + + public AbstractRF(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + @Override + public boolean isRF() { + return true; + } + + public String getEquivalentSnsSin() { + return getMasterForm().getPropertyObject(PV_EQUIVALENT_SNS_SIN).getStringValue(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/rf/RFGenericRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/rf/RFGenericRevision.java new file mode 100644 index 0000000..f7c40ce --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/rf/RFGenericRevision.java @@ -0,0 +1,44 @@ +package com.capgemini.reports.snecmaobjects.rf; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.RF_GENERIC_REVISION; + +/** + * Class representing a RFGenericRevision. + */ +public class RFGenericRevision extends AbstractRF { + private static final long serialVersionUID = 7484003347817912302L; + + public RFGenericRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public boolean isSuperModel() { + return false; + } + + @Override + public boolean isRFGeneric() { + return true; + } + + @Override + public String toString() { + return RF_GENERIC_REVISION + " " + this.getItemId(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/rf/RFPartAssembRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/rf/RFPartAssembRevision.java new file mode 100644 index 0000000..bac6e7b --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/rf/RFPartAssembRevision.java @@ -0,0 +1,44 @@ +package com.capgemini.reports.snecmaobjects.rf; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.RF_PART_ASSEMB_REVISION; + +/** + * Class representing a RFPartAssembRevision. + */ +public class RFPartAssembRevision extends AbstractRF { + private static final long serialVersionUID = -7546817776977631474L; + + public RFPartAssembRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public boolean isSuperModel() { + return false; + } + + @Override + public boolean isRFPartOrPartAssemb() { + return true; + } + + @Override + public String toString() { + return RF_PART_ASSEMB_REVISION + " " + this.getItemId(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/rf/RFPartRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/rf/RFPartRevision.java new file mode 100644 index 0000000..b42b1d7 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/rf/RFPartRevision.java @@ -0,0 +1,44 @@ +package com.capgemini.reports.snecmaobjects.rf; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.RF_PART_REVISION; + +/** + * Class representing a RFPartRevision. + */ +public class RFPartRevision extends AbstractRF { + private static final long serialVersionUID = -4115692852905919108L; + + public RFPartRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public boolean isSuperModel() { + return false; + } + + @Override + public String toString() { + return RF_PART_REVISION + " " + this.getItemId(); + } + + @Override + public boolean isRFPartOrPartAssemb() { + return true; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/supermodel/AbstractSuperModel.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/supermodel/AbstractSuperModel.java new file mode 100644 index 0000000..aa4e3fb --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/supermodel/AbstractSuperModel.java @@ -0,0 +1,42 @@ +package com.capgemini.reports.snecmaobjects.supermodel; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.teamcenter.soa.client.model.strong.Item; + +public class AbstractSuperModel implements Comparable { + private final TcSession session; + private final Item item; + + public AbstractSuperModel(final TcSession session, final Item item) { + this.session = session; + this.item = item; + } + + public String getItemId() { + return item.get_item_id(); + } + + + public String getName() { + return item.get_object_name(); + } + + public String getType() { + return item.getTypeObject().getName(); + } + + @Override + public int compareTo(final com.capgemini.reports.snecmaobjects.supermodel.AbstractSuperModel other) { + return this.getItemId().compareTo(other.getItemId()); + } + + @Override + public boolean equals(final Object obj) { + return this == obj || obj instanceof com.capgemini.reports.snecmaobjects.supermodel.AbstractSuperModel && item.equals(((com.capgemini.reports.snecmaobjects.supermodel.AbstractSuperModel) obj).item); + } + + @Override + public int hashCode() { + return item.hashCode(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/supermodel/AbstractSuperModelRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/supermodel/AbstractSuperModelRevision.java new file mode 100644 index 0000000..7b9490c --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/supermodel/AbstractSuperModelRevision.java @@ -0,0 +1,59 @@ +package com.capgemini.reports.snecmaobjects.supermodel; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.AbstractSnecmaObject; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.EqualsAndHashCode; + +import java.util.regex.Pattern; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_DESIGNATION_EN; +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_RESPONSABLE_CONCEPTION; + + +/** + * Abstract Class representing a SuperModel. + */ +@EqualsAndHashCode(callSuper = true) +public abstract class AbstractSuperModelRevision extends AbstractSnecmaObject implements Comparable { + private static final long serialVersionUID = -190379543546189856L; + + /** + * This pattern identify a {@link SuperModelRevision} id. + **/ + private static final Pattern REGEX_PATTERN_FOR_GENERIC_REVISION = Pattern.compile("^[A-Z]"); + + public AbstractSuperModelRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + /** + * Return true if the id correspond to a {@link SuperModelRevision} id.
    + */ + public static boolean isSuperModelRevision(final String genId) { + return REGEX_PATTERN_FOR_GENERIC_REVISION.matcher(genId).find(); + } + + public String getDesignationEN() { + return getMasterFormRev().getPropertyObject(PV_DESIGNATION_EN).getStringValue(); + } + + public String getResponsableConception() { + return getMasterFormRev().getPropertyObject(PV_RESPONSABLE_CONCEPTION).getStringValue(); + } + + @Override + public int compareTo(final com.capgemini.reports.snecmaobjects.supermodel.AbstractSuperModelRevision other) { + int compareID = this.getItemId().compareTo(other.getItemId()); + if (compareID != 0) { + return compareID; // Different ID + } else { + return this.getRevisionId().compareTo(other.getRevisionId()); + } + } + + @Override + public boolean isSuperModel() { + return true; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/supermodel/SuperModel.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/supermodel/SuperModel.java new file mode 100644 index 0000000..79d8228 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/supermodel/SuperModel.java @@ -0,0 +1,12 @@ +package com.capgemini.reports.snecmaobjects.supermodel; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.generic.AbstractGeneric; +import com.teamcenter.soa.client.model.strong.Item; + +public class SuperModel extends AbstractGeneric { + + public SuperModel(final TcSession session, final Item item) { + super(session, item); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/supermodel/SuperModelRevision.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/supermodel/SuperModelRevision.java new file mode 100644 index 0000000..56de49c --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/supermodel/SuperModelRevision.java @@ -0,0 +1,33 @@ +package com.capgemini.reports.snecmaobjects.supermodel; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor; +import com.capgemini.reports.snecmaobjects.visitor.IReceptorVisitor; +import com.teamcenter.soa.client.model.strong.ItemRevision; + + +/** + * Class representing a SuperModelRevision. + */ +public class SuperModelRevision extends AbstractSuperModelRevision { + private static final long serialVersionUID = 4530714427862196578L; + + public SuperModelRevision(final TcSession session, final ItemRevision itemRevision) { + super(session, itemRevision); + } + + @Override + public T accept(final IReceptorVisitor aReceptorVisitor) { + return aReceptorVisitor.visitReceptor(this); + } + + @Override + public T accept(final IComponentVisitor aComponentVisitor) { + return aComponentVisitor.visitComponent(this); + } + + @Override + public String toString() { + return getType() + " " + this.getItemId(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/visitor/IComponentVisitor.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/visitor/IComponentVisitor.java new file mode 100644 index 0000000..61862f4 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/visitor/IComponentVisitor.java @@ -0,0 +1,206 @@ +package com.capgemini.reports.snecmaobjects.visitor; + +import com.capgemini.reports.snecmaobjects.admin.RFAdminAGRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericAssembRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.mockup.MockupRevision; +import com.capgemini.reports.snecmaobjects.part.*; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartAssembRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartRevision; +import com.capgemini.reports.snecmaobjects.supermodel.SuperModelRevision; + +import java.io.Serializable; + +/** + * Interface representing the Component behaviour of a SnecmaObject. + * + * @param produced output type + */ +public interface IComponentVisitor extends Serializable { + + /** + * Visitor which can used the ¨ProductRevision Component properties to make a chosen report. + * + * @param aProductRev ProductRevision + * @return T + * + */ + T visitComponent(final ProductRevision aProductRev); + + /** + * Visitor which can used the GenericRevision Component properties to make a chosen report. + * + * @param aGenericRev GenericRevision + * @return T + * + */ + T visitComponent(final GenericRevision aGenericRev); + + /** + * Visitor which can used the ¨SuperModelRevision Component properties to make a chosen report. + * + * @param aSuperModelRev ProductRevision + * @return T + * + */ + T visitComponent(final SuperModelRevision aSuperModelRev); + + /** + * Visitor which can used the GenericAssembRevision Component properties to make a chosen report. + * + * @param aGenericAssembRev GenericAssembRevision + * @return T + * + */ + T visitComponent(final GenericAssembRevision aGenericAssembRev); + + /** + * Visitor which can used the AlternateRevision Component properties to make a chosen report. + * + * @param aAlternateRev AlternateRevision + * @return T + * + */ + T visitComponent(final AlternateRevision aAlternateRev); + + /** + * Visitor which can used the DETRevision Component properties to make a chosen report. + * + * @param aDetRev DETRevision + * @return T + * + */ + T visitComponent(final DETRevision aDetRev); + + /** + * Visitor which can used the PartAeroRevision Component properties to make a chosen report. + * + * @param aPartAeroRev PartAeroRevision + * @return T + * + */ + T visitComponent(final PartAeroRevision aPartAeroRev); + + /** + * Visitor which can used the PartNoAeroRevision Component properties to make a chosen report. + * + * @param aPartNoAeroRev PartNoAeroRevision + * @return T + * + */ + T visitComponent(final PartNoAeroRevision aPartNoAeroRev); + + /** + * Visitor which can used the PartAssembRevision Component properties to make a chosen report. + * + * @param aPartAssembRev PartAssembRevision + * @return T + * + */ + T visitComponent(final PartAssembRevision aPartAssembRev); + + /** + * Visitor which can used the PartMatRevision Component properties to make a chosen report. + * + * @param aPartMatRev PartMatRevision + * @return T + * + */ + T visitComponent(final PartMatRevision aPartMatRev); + + /** + * Visitor which can used the StandardRevision Component properties to make a chosen report. + * + * @param aStandardRev StandardRevision + * @return T + * + */ + T visitComponent(final StandardRevision aStandardRev); + + /** + * Visitor which can used the RFGenericRevision Component properties to make a chosen report. + * + * @param aRfGenericRev RFGenericRevision + * @return T + * + */ + T visitComponent(final RFGenericRevision aRfGenericRev); + + /** + * Visitor which can used the RFPartAssembRevision Component properties to make a chosen report. + * + * @param aRfPartAssembRev RFPartAssembRevision + * @return T + * + */ + T visitComponent(final RFPartAssembRevision aRfPartAssembRev); + + /** + * Visitor which can used the RFPartRevision Component properties to make a chosen report. + * + * @param aRfPartRev RFPartRevision + * @return T + * + */ + T visitComponent(final RFPartRevision aRfPartRev); + + /** + * Visitor which can used the RFAdminRevision Component properties to make a chosen report. + * + * @param aRfAdminRev RFAdminRevision + * @return T + * + */ + T visitComponent(final RFAdminRevision aRfAdminRev); + + /** + * Visitor which can used the RFAdminARevision Component properties to make a chosen report. + * + * @param aRfAdminARev RFAdminARevision + * @return T + * + */ + T visitComponent(final RFAdminARevision aRfAdminARev); + + /** + * Visitor which can used the RFAdminAPRevision Component properties to make a chosen report. + * + * @param aRfAdminAPRev RFAdminAPRevision + * @return T + * + */ + T visitComponent(final RFAdminAPRevision aRfAdminAPRev); + + /** + * Visitor which can used the RFAdminAGRevision Component properties to make a chosen report. + * + * @param aRfAdminAGRev RFAdminAGRevision + * @return T + * + */ + T visitComponent(final RFAdminAGRevision aRfAdminAGRev); + + /** + * Visitor which can used the MockupRevision Receptor properties to make a chosen report. + * + * @param aMockupRev MockupRevision + * @return T + * + */ + T visitComponent(final MockupRevision aMockupRev); + + /** + * Visitor which can used the DescriptifRevision Receptor properties to make a chosen report. + * + * @param aDescriptifRev DescriptifRevision + * @return T + * + */ + T visitComponent(final DescriptifRevision aDescriptifRev); +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/visitor/IReceptorVisitor.java b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/visitor/IReceptorVisitor.java new file mode 100644 index 0000000..26b58fe --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/snecmaobjects/visitor/IReceptorVisitor.java @@ -0,0 +1,220 @@ +package com.capgemini.reports.snecmaobjects.visitor; + +import com.capgemini.reports.snecmaobjects.admin.RFAdminAGRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision; +import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision; +import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericAssembRevision; +import com.capgemini.reports.snecmaobjects.generic.GenericRevision; +import com.capgemini.reports.snecmaobjects.mockup.MockupRevision; +import com.capgemini.reports.snecmaobjects.part.*; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartAssembRevision; +import com.capgemini.reports.snecmaobjects.rf.RFPartRevision; +import com.capgemini.reports.snecmaobjects.supermodel.SuperModelRevision; + +import java.io.Serializable; + +/** + * Interface representing the Receptor behaviour of a SnecmaObject. + * + * @param produced output type + */ +public interface IReceptorVisitor extends Serializable { + + /** + * Visitor which can used the ProductRevision Receptor properties to make a chosen report. + * + * @param aProductRev ProductRevision + * @return T + * + */ + T visitReceptor(final ProductRevision aProductRev); + + /** + * Visitor which can used the GenericRevision Receptor properties to make a chosen report. + * + * @param aGenericRev GenericRevision + * @return T + * + */ + T visitReceptor(final GenericRevision aGenericRev); + + /** + * Visitor which can used the GenericAssembRevision Receptor properties to make a chosen report. + * + * @param aGenericAssembRev GenericAssembRevision + * @return T + * + */ + T visitReceptor(final GenericAssembRevision aGenericAssembRev); + + + /** + * Visitor which can used the GenericRevision Receptor properties to make a chosen report. + * + * @param aSuperModelRev GenericRevision + * @return T + * + */ + T visitReceptor(final SuperModelRevision aSuperModelRev); + + /** + * Visitor which can used the AlternateRevision Receptor properties to make a chosen report. + * + * @param aAlternateRev AlternateRevision + * @return T + * + */ + T visitReceptor(final AlternateRevision aAlternateRev); + + /** + * Visitor which can used the SuperModelRevision Receptor properties to make a chosen report. + * + // * @param aSuperModelRev SuperModelRevision + * @return T + * + */ + // T visitReceptor(final SuperModelRevision aSuperModelRev); + + + + /** + * Visitor which can used the DETRevision Receptor properties to make a chosen report. + * + * @param aDetRev DETRevision + * @return T + * + */ + T visitReceptor(final DETRevision aDetRev); + + /** + * Visitor which can used the PartAeroRevision Receptor properties to make a chosen report. + * + * @param aPartAeroRev PartAeroRevision + * @return T + * + */ + T visitReceptor(final PartAeroRevision aPartAeroRev); + + /** + * Visitor which can used the PartNoAeroRevision Receptor properties to make a chosen report. + * + * @param aPartNoAeroRev PartNoAeroRevision + * @return T + * + */ + T visitReceptor(final PartNoAeroRevision aPartNoAeroRev); + + /** + * Visitor which can used the PartAssembRevision Receptor properties to make a chosen report. + * + * @param aPartAssembRev PartAssembRevision + * @return T + * + */ + T visitReceptor(final PartAssembRevision aPartAssembRev); + + /** + * Visitor which can used the PartMatRevision Receptor properties to make a chosen report. + * + * @param aPartMatRev PartMatRevision + * @return T + * + */ + T visitReceptor(final PartMatRevision aPartMatRev); + + /** + * Visitor which can used the StandardRevision Receptor properties to make a chosen report. + * + * @param aStandardRev StandardRevision + * @return T + * + */ + T visitReceptor(final StandardRevision aStandardRev); + + /** + * Visitor which can used the RFGenericRevision Receptor properties to make a chosen report. + * + * @param aRfGenericRev RFGenericRevision + * @return T + * + */ + T visitReceptor(final RFGenericRevision aRfGenericRev); + + /** + * Visitor which can used the RFPartAssembRevision Receptor properties to make a chosen report. + * + * @param aRfPartAssembRev RFPartAssembRevision + * @return T + * + */ + T visitReceptor(final RFPartAssembRevision aRfPartAssembRev); + + /** + * Visitor which can used the RFPartRevision Receptor properties to make a chosen report. + * + * @param aRfPartRev RFPartRevision + * @return T + * + */ + T visitReceptor(final RFPartRevision aRfPartRev); + + /** + * Visitor which can used the RFAdminRevision Receptor properties to make a chosen report. + * + * @param aRfAdminRev RFAdminRevision + * @return T + * + */ + T visitReceptor(final RFAdminRevision aRfAdminRev); + + /** + * Visitor which can used the RFAdminARevision Receptor properties to make a chosen report. + * + * @param aRfAdminARev RFAdminARevision + * @return T + * + */ + T visitReceptor(final RFAdminARevision aRfAdminARev); + + /** + * Visitor which can used the RFAdminAPRevision Receptor properties to make a chosen report. + * + * @param aRfAdminAPRev RFAdminAPRevision + * @return T + * + */ + T visitReceptor(final RFAdminAPRevision aRfAdminAPRev); + + /** + * Visitor which can used the RFAdminAGRevision Receptor properties to make a chosen report. + * + * @param aRfAdminAGRev RFAdminAGRevision + * @return T + * + */ + T visitReceptor(final RFAdminAGRevision aRfAdminAGRev); + + /** + * Visitor which can used the MockupRevision Receptor properties to make a chosen report. + * + * @param aMockupRev MockupRevision + * @return T + * + */ + T visitReceptor(final MockupRevision aMockupRev); + + /** + * Visitor which can used the DescriptifRevision Receptor properties to make a chosen report. + * + * @param aDescriptifRev DescriptifRevision + * @return T + * + */ + T visitReceptor(final DescriptifRevision aDescriptifRev); + + T emptyRf(); +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/ObjectInfoHelper.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/ObjectInfoHelper.java new file mode 100644 index 0000000..92b76c7 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/ObjectInfoHelper.java @@ -0,0 +1,687 @@ +package com.capgemini.reports.teamcenter; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.object.SnecmaObjectProperties; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum.AbstractStatusFilter; +import com.capgemini.framework.teamcenter.object.pom.status.TcReleaseStatus; +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import com.capgemini.reports.ItemRevisionComparator; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.releasestatus.RevisionStatusAndDate; +import com.google.common.base.Optional; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Effectivity; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.ReleaseStatus; +import lombok.extern.slf4j.Slf4j; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_ALTERNATIVE; +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.EFFECTIVITY; + +/** + * This class is able to obtain specific data from some objects in Teamcenter.
    + * To be used when the information is there, it's just buried in layers of TC objects. This helper class will only help retrieve the data reliably.
    + * Typical usage is to find effectivity status of an ItemRevision, obtain the latest maturity status etc. + */ +@Slf4j +public class ObjectInfoHelper { + + private static final String WITH_UNIT = " with Unit "; + + private static final Pattern EFFECTIVITY_RANGE_UP = Pattern.compile("([\\d]{2,})-([Uu][Pp]|[Ss][Oo])"); // Matches an open-ended range like '50-UP' (note: can also be '50-SO') + private static final Pattern EFFECTIVITY_RANGE_NUMBER = Pattern.compile("([\\d]{2,})-[\\d]{2,}"); // Matches a number range like '95-105' + private static final Pattern EFFECTIVITY_RANGE_ALONE = Pattern.compile("([\\d]{2,})"); // Matches a single number (2+ digits) + + + /** + * Returns a {@link List} of {@link ModelObject}s containing Part (Standard or Part Aero) which are inside + * the pseudo folder of a provided {@link ItemRevision} (Alternate Revision or DET Revision).
    + */ + public static List getPartsInPseudoFolderOfAltOrDetRevision(final TcSession session, final ItemRevision itemRevision) { + String objectType = itemRevision.getTypeObject().getName(); + if (SnecmaObjectTypes.isAltOrDet(objectType)) { + List listItem = new ArrayList<>(); + session.loadProperties(itemRevision, PV_ALTERNATIVE); + ModelObject[] alternatives = itemRevision.getPropertyObject(PV_ALTERNATIVE).getModelObjectArrayValue(); + session.loadProperties(alternatives); + for (ModelObject modelObj : alternatives) { + listItem.add((Item) modelObj); + } + return listItem; + } else { + return new ArrayList<>(); + } + } + + /** + * Returns a {@link List} of {@link ModelObject}s containing whatever are inside the pseudo folder.
    + */ + public static List getModelObjectsInPseudoFolderUnderItemRevision(final TcSession session, final ItemRevision itemRevision, final String propertyPseudoFolder) { + session.loadProperties(itemRevision, propertyPseudoFolder); + ModelObject[] folderObjects = itemRevision.getPropertyObject(propertyPseudoFolder).getModelObjectArrayValue(); + session.loadProperties(folderObjects); + return Arrays.asList(folderObjects); + } + + /** + * Check if Generic or GenericAssemb has an unit less than or equal unitTarget. + */ + public static boolean getClosestGenerics(final TcSession session, final String genericID, final int targetUnit, final List genericsRevision) + throws NotFoundException { + boolean isUnitClosest = false; + + if (genericsRevision.isEmpty()) { + throw new NotFoundException("No unitRevision exists for Generic||Generic Assemb " + genericID + WITH_UNIT + targetUnit); + } + for (ItemRevision genericRevision : genericsRevision) { + session.loadProperties(genericRevision, "release_status_list"); + ReleaseStatus[] releaseStatuses = genericRevision.get_release_status_list(); + session.loadProperties(releaseStatuses); + for (ReleaseStatus status : releaseStatuses) { + isUnitClosest = getInferiorUnitFromEffectivities(session, status, targetUnit); + } + } + + return isUnitClosest; + + } + + /** + * Returns the first TcEffectivity whose name is "effectivity" and whose range starts before the provided unit. + */ + private static boolean getInferiorUnitFromEffectivities(final TcSession session, final ReleaseStatus releaseStatus, final int targetUnit) { + session.loadProperties(releaseStatus, "effectivities"); + ModelObject[] effectivities = releaseStatus.get_effectivities(); + session.loadProperties(effectivities); + for (ModelObject objectEffectivity : effectivities) { + String statusName = releaseStatus.get_name(); + if (!EFFECTIVITY.equals(statusName)) { + continue; + } + Effectivity effectivity = (Effectivity) objectEffectivity; + String effectivityRange = effectivity.get_range_text(); + log.debug("Check is current TcEffectivity range : " + effectivityRange + " is <= " + targetUnit); + if (isInRange(targetUnit, effectivityRange)) { + return true; + } + } + return false; + } + + private static boolean isInRange(final int targetUnit, final String effectivityRange) { + boolean found = false; + if (isEffectivityRangeUP(effectivityRange)) { + if (targetUnit <= getFirstRangeValue(effectivityRange, EFFECTIVITY_RANGE_UP)) { + found = true; + } + } else if (isEffectivityRangeNUMBER(effectivityRange)) { + if (targetUnit <= getFirstRangeValue(effectivityRange, EFFECTIVITY_RANGE_NUMBER)) { + found = true; + } + } else if (isEffectivityRangeALONE(effectivityRange) && targetUnit <= getFirstRangeValue(effectivityRange, EFFECTIVITY_RANGE_ALONE)) { + found = true; + } + return found; + } + + private static boolean equalsRangeStart(final int targetUnit, final String effectivityRange) { + boolean found = false; + if (isEffectivityRangeUP(effectivityRange)) { + if (targetUnit == getFirstRangeValue(effectivityRange, EFFECTIVITY_RANGE_UP)) { + found = true; + } + } else if (isEffectivityRangeNUMBER(effectivityRange)) { + if (targetUnit == getFirstRangeValue(effectivityRange, EFFECTIVITY_RANGE_NUMBER)) { + found = true; + } + } else if (isEffectivityRangeALONE(effectivityRange) && targetUnit == getFirstRangeValue(effectivityRange, EFFECTIVITY_RANGE_ALONE)) { + found = true; + } + return found; + } + + /** + * Returns the first match in the unit range, using the provided pattern. + * + * @param range the Unit range (can be a single unit, an pen range, a closed range etc.) + * @param pattern The patter nto decipher the provided range + * @return the unit number which is the start of the provided range + */ + private static int getFirstRangeValue(final String range, final Pattern pattern) { + String data = ""; + Matcher matcher = pattern.matcher(range); + if (matcher.matches() && matcher.groupCount() >= 1) { + data = matcher.group(1); + } + return Integer.parseInt(data); + } + + private static boolean isEffectivityRangeUP(final String input) { + Matcher matcher = EFFECTIVITY_RANGE_UP.matcher(input); + return matcher.matches(); + } + + private static boolean isEffectivityRangeNUMBER(final String input) { + Matcher matcher = EFFECTIVITY_RANGE_NUMBER.matcher(input); + return matcher.matches(); + } + + private static boolean isEffectivityRangeALONE(final String input) { + Matcher matcher = EFFECTIVITY_RANGE_ALONE.matcher(input); + return matcher.matches(); + } + + /** + * Returns the {@link ItemRevision} with the most recent modification date, of an {@link Item}.
    + * This method requires the last_mod_date property on {@link ItemRevision}. + * + * @param itemsRevisions the List of candidate {@link ItemRevision}s + * @param userDate the limit user date, only modifications before that date will be examined + * @return An Optional containing the most up-to-date ItemRevision, TcReleaseStatus and mod date. The Optional may be empty if not Revisions were provided! + */ + public static RevisionStatusAndDate getRevisionAndStatusWithMostRecentModificationDate(final List itemsRevisions, + final Calendar userDate) { + RevisionStatusAndDate bestYet = null; + for (ItemRevision curItemRevision : itemsRevisions) { + Calendar modDateCurrentItem = curItemRevision.get_last_mod_date(); // Requires the last_mod_date property + if (bestYet == null) { // First pass + bestYet = new RevisionStatusAndDate(modDateCurrentItem, null, curItemRevision); + } else { + if (modDateCurrentItem.after(bestYet.getReleaseDate()) + && (userDate == null || modDateCurrentItem.before(userDate) || sameDay(modDateCurrentItem, userDate))) { + bestYet = new RevisionStatusAndDate(modDateCurrentItem, null, curItemRevision); + } + } + } + return bestYet; + } + + /** + * Returns the {@link ItemRevision} with the most recent modification date, of an {@link Item}.
    + * This method requires the last_mod_date property on {@link ItemRevision}. + * + * @param itemsRevision the List of candidate {@link ItemRevision}s + * @return An Optional containing the most up-to-date ItemRevision, TcReleaseStatus and mod date. The Optional may be empty if not Revisions were provided! + */ + public static RevisionStatusAndDate getLastModDate(final ItemRevision itemsRevision) { + RevisionStatusAndDate bestYet = null; + + Calendar modDateCurrentItem = itemsRevision.get_last_mod_date(); // Requires the last_mod_date property + bestYet = new RevisionStatusAndDate(modDateCurrentItem, null, itemsRevision); + + return bestYet; + } + + private static boolean sameDay(final Calendar cal1, final Calendar cal2) { + return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) && cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR); + } + + /** + * Returns the {@link ItemRevision} whose {@link ReleaseStatus} has the most recent release date, amongst the provided ItemRevisions.
    + * This method requires the date_released property on {@link ItemRevision}.
    + * This method requires the date_released property on {@link ReleaseStatus}.
    + * This method requires the release_status_list property on {@link ItemRevision}, with properties. + * + * @param session + * @param itemsRevisions the List of candidate {@link ItemRevision}s + * @param userDate the limit user date, only items released before that date will be examined. If null, all dates are accepted. + * @param statusFilter A filter on the statuses to examine. Statuses rejected by the filter will not be examined at all. + * @return An {@link Optional} containing the most up-to-date ItemRevision, TcReleaseStatus and release date (or empty, if no status matching the date could be found) + */ + public static Optional getRevisionAndStatusWithMostRecentReleaseDate(final TcSession session, final List itemsRevisions, + final Calendar userDate, final AbstractStatusFilter statusFilter) { + Optional bestYet = Optional.absent(); + for (ModelObject curItemRevision : itemsRevisions) { + List listReleaseStatus = statusFilter.filterStatusOf(session, (ItemRevision) curItemRevision); + for (ReleaseStatus status : listReleaseStatus) { + if (status == null) { + continue; + } + Calendar date = status.get_date_released(); + + if ((userDate == null || date.compareTo(userDate) < 0) + && (!bestYet.isPresent() || bestYet.get().getReleaseDate().compareTo(date) < 0)) { + bestYet = Optional.of(new RevisionStatusAndDate(date, status, (ItemRevision) curItemRevision)); + } + } + } + return bestYet; + } + + /** + * Returns the {@link ItemRevision} whose {@link ReleaseStatus} has the most recent release date, amongst the provided ItemRevisions.
    + * This method requires the date_released property on {@link ItemRevision}.
    + * This method requires the date_released property on {@link ReleaseStatus}.
    + * This method requires the release_status_list property on {@link ItemRevision}, with properties. + * + * @param session + * @param itemsRevisions the List of candidate {@link ItemRevision}s + * @param userDate the limit user date, only items released before that date will be examined. If null, all dates are accepted. + * @param allowedStatus if none are given, all status will be used (except TcEffectivity which is not really a maturity status). If not empty, only the provided statuses will be returned. + * @return An {@link Optional} containing the most up-to-date ItemRevision, TcReleaseStatus and release date (or empty, if no status matching the date could be found) + */ + public static Optional getRevisionAndStatusWithMostRecentReleaseDate(final TcSession session, final List itemsRevisions, + final Calendar userDate, final StatusEnum... allowedStatus) { + AbstractStatusFilter filter = + (allowedStatus == null || allowedStatus.length == 0) ? StatusEnum.forbid(StatusEnum.EFFECTIVITY) : StatusEnum.allow(allowedStatus); // By default, forbid TcEffectivity. + return getRevisionAndStatusWithMostRecentReleaseDate(session, itemsRevisions, userDate, filter); + } + + /** + * Returns the {@link ItemRevision} whose {@link ReleaseStatus} has the most recent release date, amongst the provided ItemRevisions.
    + * This method requires the date_released property on {@link ItemRevision}.
    + * This method requires the date_released property on {@link ReleaseStatus}.
    + * This method requires the release_status_list property on {@link ItemRevision}. + * + * @param session + * @param itemsRevision the List of candidate {@link ItemRevision}s + * @param userDate the limit user date, only Statuses released before that date will be examined. May be null if you want to ignore this + * @param wantedStatus Enumeration of wanted status ({@link StatusEnum}). + * @return an {@link Optional} which may contain the ItemRevision with the latest Release Date that still is before the provided deadline, or nothing if no revision meet the constraints + */ + public static Optional getRevisionFromStatusWithMostRecentReleaseDate(final TcSession session, final List itemsRevision, + final Calendar userDate, final StatusEnum... wantedStatus) { + Optional latest = getRevisionAndStatusWithMostRecentReleaseDate(session, itemsRevision, userDate, wantedStatus); + if (latest.isPresent()) { + return Optional.of(latest.get().getItemRevision()); + } else { + return Optional.absent(); + } + } + /** + * Returns the {@link ItemRevision} whose {@link ReleaseStatus} has the most recent release date, amongst the provided ItemRevisions not cancelled.
    + * This method requires the date_released property on {@link ItemRevision}.
    + * This method requires the date_released property on {@link ReleaseStatus}.
    + * This method requires the release_status_list property on {@link ItemRevision}. + * + * @param session + * @param itemsRevision the List of candidate {@link ItemRevision}s + * @param userDate the limit user date, only Statuses released before that date will be examined. May be null if you want to ignore this + * @return an {@link Optional} which may contain the ItemRevision with the latest Release Date that still is before the provided deadline, or nothing if no revision meet the constraints + */ + public static Optional getRevisionFromStatusWithMostRecentReleaseDateNotCancelled(final TcSession session, final List itemsRevision, + final Calendar userDate) { + AbstractStatusFilter filter = StatusEnum.forbid(StatusEnum.EFFECTIVITY,StatusEnum.OLD_EFFECTIVITY); + Optional bestYet = Optional.absent(); + Optional bestYetNoDefApproved= Optional.absent(); + boolean flagDefApproved=false; + for (ItemRevision curItemRevision : itemsRevision) { + List listReleaseStatus = filter.filterStatusOf(session, (ItemRevision) curItemRevision); + boolean flagCancel = false; + boolean flagDefApprovedCurrent = false; + Optional currentBestYet = Optional.absent(); + for (ReleaseStatus status : listReleaseStatus) { + + if (status == null) { + continue; + } + if (status.get_name().equals(StatusEnum.CANCELLED.getIdentifier())) { + flagCancel = true; + //on a trouvé un flag Cancel on à plus besoin de parcourir le rest des status + break; + } + if (status.get_name().equals(StatusEnum.DEF_APPROVED.getIdentifier())){ + flagDefApprovedCurrent =true; + } + Calendar date = status.get_date_released(); + if ((userDate == null || date.compareTo(userDate) < 0) + && (!bestYet.isPresent() || bestYet.get().getReleaseDate().compareTo(date) < 0)) { + currentBestYet = Optional.of(new RevisionStatusAndDate(date, status, (ItemRevision) curItemRevision)); + } + + } + if (!flagCancel) { + // Cas ou pas de status Def Approved + if (listReleaseStatus.size() == 0) { + if ((!bestYetNoDefApproved.isPresent()) + || bestYetNoDefApproved.get().getReleaseDate().compareTo((curItemRevision).get_last_mod_date()) <= 0) { + bestYetNoDefApproved = Optional.of(getLastModDate(curItemRevision)); + } + } else { + //Cas ou on à trouvé un statut def approved + if (currentBestYet.isPresent()) { + bestYet = currentBestYet; + } + flagDefApproved = flagDefApproved || flagDefApprovedCurrent; + } + } + } + RevisionStatusAndDate lastRevStatDate = null; + if (flagDefApproved == true) { + //return Optional.of(latest.get().getItemRevision()); + lastRevStatDate =bestYet.get(); + } else { + + if(bestYetNoDefApproved.isPresent()){ + lastRevStatDate = bestYetNoDefApproved.get(); + }else{ + //all cancel + return Optional.absent(); + + } + } + return Optional.of(lastRevStatDate.getItemRevision()); + } + /** + * Returns the {@link ReleaseStatus} with the most recent release date, amongst the provided {@link ItemRevision}s.
    + * This method requires the date_released property on {@link ReleaseStatus} + * + * @param itemRevision the entry ItemRevision + * @param forbiddenStatus the enumeration of all the forbidden status + * @return ReleaseStatus the appropriate ReleaseStatus with the most recent date released + */ + public static ReleaseStatus getStatusWithMostRecentReleaseDate(final TcSession session, final ItemRevision itemRevision, final StatusEnum... forbiddenStatus) { + // Retrieve all the ReleaseStatus + List releaseStatusPartRev = new ArrayList<>(); + if (forbiddenStatus.length == 0) { + session.loadProperties(itemRevision, "release_status_list"); + ReleaseStatus[] releaseStatuses = itemRevision.get_release_status_list(); + session.loadProperties(releaseStatuses); + Collections.addAll(releaseStatusPartRev, releaseStatuses); + } else { + releaseStatusPartRev = TcReleaseStatus.getAllStatusExceptSome(session, itemRevision, forbiddenStatus); + } + + // Select the most recent ReleaseStatus + ReleaseStatus selectedRS = null; + Calendar selectedDate = null; + for (ReleaseStatus status : releaseStatusPartRev) { + if (status != null) { + Calendar date = status.get_date_released(); + if (selectedDate == null) { // First pass + selectedRS = status; + selectedDate = date; + } else if (selectedDate.compareTo(date) < 0) { + selectedRS = status; + selectedDate = date; + } + } + } + return selectedRS; + } + + + /** + * Get all the {@link ItemRevision}s whose effectivies are the highest (as long as they stay below the provided rangeRefStr parameter). + * + * @param revisionsList List<{@link ItemRevision}> the list of all the {@link ItemRevision} + * @param rangeRefStr String the limit range + * @return the ItemRevisions, in a {@link List} + */ + public static List getRevisionWithHighestRange(final TcSession session, final List revisionsList, final String rangeRefStr) { + int rangeRef = Integer.parseInt(rangeRefStr); + List results = new ArrayList<>(); // The list of all revisions with the highest range + int resultRange = -1; // THe highest Range + + // Browse all revisions + for (ItemRevision itemRev : revisionsList) { + List effectivityList = TcReleaseStatus.getChosenStatus(session, itemRev, StatusEnum.EFFECTIVITY); + if (effectivityList.isEmpty()) { + continue; + } + int selected = selectHighestRange(session, effectivityList, rangeRef); // Is negative if none are found + if (selected > 0) { + if (selected == resultRange) { + results.add(itemRev); // Same range found, add this ItemRev to the list of items found with same range + } else if (selected > resultRange) { // Closer range found, begin a new list with this ItemRev + results.clear(); + results.add(itemRev); + resultRange = selected; + } + } + } + return results; + } + + /** + * Keep the {@link ItemRevision} in the entry list which have the same end Item Id value as the reference value.
    + * Note on the policy: The property {@code end_item} must be set on the TcEffectivity, and {@code withProperties} set to true + * + * @param revisionsList List<{@link ItemRevision}> - the list of revisions + * @param endItemId {@link String} - the wanted value of the end Item Id + * @return the chosen list + */ + public static List getRevisionWithSameEndItem(final TcSession session, final List revisionsList, final String endItemId) { + List results = new ArrayList<>(); + for (ItemRevision itemRev : revisionsList) { + boolean isSuccess = false; + for (ReleaseStatus releaseStatus : TcReleaseStatus.getChosenStatus(session, itemRev, StatusEnum.EFFECTIVITY)) { + session.loadProperties(releaseStatus, "effectivities"); + ModelObject[] effectivities = releaseStatus.get_effectivities(); + session.loadProperties(effectivities); + for (ModelObject effectivityObject : effectivities) { + Effectivity effectivity = (Effectivity) effectivityObject; + session.loadProperties(effectivity, "end_item"); + Item endItem = effectivity.get_end_item(); + session.loadProperties(endItem); + if (endItemId.equals(SnecmaObjectProperties.getItemIdOrNull(endItem))) { + results.add(itemRev); + isSuccess = true; + break; + } + } + if (isSuccess) { + break; + } + } + } + return results; + } + + /** + * Selects the TcEffectivity with the highest range, returns the range.
    + * If no Effectivities are eligible (none exist or those that exist are below the provided rangeRef) returns -1. + */ + private static int selectHighestRange(final TcSession session, final List effectivityList, final int rangeRef) { + int selected = -1; + // This revision seems to be a legitimate candidate, let's look at its effectivities + for (ReleaseStatus releaseStatus : effectivityList) { + if (releaseStatus == null) { + continue; + } + // TcEffectivity encountered + session.loadProperties(releaseStatus, "effectivities"); + ModelObject[] effectivities = releaseStatus.get_effectivities(); + session.loadProperties(effectivities); + for (ModelObject effectivityObject : effectivities) { + Effectivity effectivity = (Effectivity) effectivityObject; + String rangeItemRev = effectivity.get_range_text(); + String[] splitList = rangeItemRev.split("-"); + int candidate = Integer.parseInt(splitList[0]); + if (candidate <= rangeRef && (selected < 0 || selected < candidate)) { + selected = candidate; + } + } + } + return selected; + } + + /** + * Returns a list of object referencer answering to the specification
    + * Has statuts Def Approved And is the the highest sequence between object have the same item_id and revision_id .
    + * You must give a list objects referencing a document, a list object revision authorized and a list status authorized + */ + + public static List filteringObjectsReferencer(final TcSession session, final List objectsReferencer, final List authorizedTypes) { + List results = new ArrayList<>(); + // getAuthorized types + for (ItemRevision object : objectsReferencer) { + if (authorizedTypes.contains(object.getTypeObject().getName())) { + results.add(object); + } else { + log.info("Rejected unauthorized type={} item_id={}", object.getTypeObject().getName(), object.get_item_id()); + } + } + // --findAll parts has status Def Approved + results = checkStatus(session, results); + + // --Group datas by their item_id,and revision_id and return highest sequence + results = groupItemRevisionPerFamily(results); + + // --findAll active sequence and filtering them by their last released date to findAll highest revision + // { part_xx/A.2(-> released_date:15-Jul-2015 11:11), part_xx/B.3 (-> released_date:14-Sept-2015 08:00) } = part_xx/B.3 + + // findAll the active sequence + results = getActiveSequence(results); + // on se retrouve avec ca list {part_1/A.2,part_1/B.2} dans ce cas on garde la B + // Chercher les parts en doublons part_1 et prendre la date_released de l'objet le plus recent + + + return results; + } + + /** + * findAll current item rev if has status Def Approved + * IN : list = {partxA1 DefApproved,partxA2,partyB1} + * OUT : list = {partxA1 DefApproved} + */ + private static List checkStatus(final TcSession session, final List objectsReferencer) { + List listPartsHasStatusDefApproved = new ArrayList<>(); + + for (ItemRevision itemRevision : objectsReferencer) { + session.loadProperties(itemRevision, "release_status_list"); + ReleaseStatus[] releaseStatuses = itemRevision.get_release_status_list(); + session.loadProperties(releaseStatuses); + for (ReleaseStatus releaseStatus : releaseStatuses) { + if (SnecmaObjectProperties.DEF_APPROVED.equals(releaseStatus.get_name())) { + listPartsHasStatusDefApproved.add(itemRevision); + } + } + } + return listPartsHasStatusDefApproved; + } + + /** + * Group datas by their item_id,and revision_id and return highest sequence + * IN : list = {partx/A.1,partx/A.2,party/B.1,partx/B.1} + * OUT : List = {partx/A.2, partx/B.1,party/B.1 } + */ + private static List groupItemRevisionPerFamily(final List objectsReferencerDefApproved) { + List returnList = new ArrayList<>(); + + List temp = new ArrayList<>(); + temp.addAll(objectsReferencerDefApproved); + + for (ItemRevision itemRevision : objectsReferencerDefApproved) { + // create a sub collection + List subCollection = new ArrayList<>(); + int pos = 0; + // Compare current itemRevision_id with an element of the temp collection + // And if ok put the current temp itemRevision in a sub collection + while (pos < temp.size()) { + if (itemRevision.get_item_id().equals(temp.get(pos).get_item_id()) + && itemRevision.get_item_revision_id().equals(temp.get(pos).get_item_revision_id())) { + subCollection.add(temp.get(pos)); + temp.remove(pos); + // re start iteration + pos = 0; + continue; + } + pos++; + } + // can be empty + if (!subCollection.isEmpty()) { + // ordering objects by item_id,rev_id,sequence_id (partx/A.1,partx/A.2,...) + Collections.sort(subCollection, new ItemRevisionComparator()); + ItemRevision latestSequence = subCollection.get(subCollection.size() - 1); + log.info("On group per family -> latest sequence is {}/{}.{}", latestSequence.get_item_id(), latestSequence.get_item_revision_id(), latestSequence.get_sequence_id()); + returnList.add(latestSequence); + } + } + return returnList; + } + + /* Return the latest active sequence check if the highest sequence*/ + private static List getActiveSequence(final List result) { + List results = new ArrayList<>(); + for (ItemRevision curItemRevision : result) { + if (curItemRevision.get_active_seq() != 0) { + results.add(curItemRevision); + } else { + log.info("Rejected {} because is not the last sequence", curItemRevision.getUid()); + } + } + return getHighestSequenceByReleasedDate(results); + } + + /*Compare two Item revision have the same item_id and different revision_id, take the last date released */ + private static List getHighestSequenceByReleasedDate(final List currentList) { + Map map = new HashMap<>(); + for (ItemRevision curItemRevision : currentList) { + if (map.containsKey(defineKey(curItemRevision))) { + ItemRevision existingItemRevision = map.get(defineKey(curItemRevision)); + // findAll good object by date released + ItemRevision candidate = getTheHighestItemRevisionByDate(curItemRevision, existingItemRevision); + map.put(defineKey(candidate), candidate); + } else { + map.put(defineKey(curItemRevision), curItemRevision); + } + } + + return new ArrayList<>(map.values()); + } + + /* Check if current itemRevision have date released superior than existing item revision */ + private static ItemRevision getTheHighestItemRevisionByDate(final ItemRevision curItemRevision, final ItemRevision existingItemRevision) { + Calendar dateReleasedOfCurItemRevision = curItemRevision.get_date_released(); + Calendar dateReleasedOfexistingItemRevision = existingItemRevision.get_date_released(); + if (dateReleasedOfCurItemRevision.after(dateReleasedOfexistingItemRevision)) { + return curItemRevision; + } else { + return existingItemRevision; + } + } + + /* Helper build key for map*/ + private static String defineKey(final ItemRevision itemRevision) { + return itemRevision.get_item_id(); + } + + /** + * Returns true if the {@link ReleaseStatus}'s Effectivities contain one {@link Effectivity} named "effectivity", whose range matches the provided Unit number. + * + * @param releaseStatus the {@link ReleaseStatus} holding all the effectivities + * @param targetUnit the unit to match + * @return true if an {@link Effectivity} is found with a unit value matching the targetUnit, false otherwise + */ + private static boolean getExactUnitInEffectivities(final TcSession session, final ReleaseStatus releaseStatus, final int targetUnit) { + session.loadProperties(releaseStatus, "effectivities"); + ModelObject[] effectivities = releaseStatus.get_effectivities(); + session.loadProperties(effectivities); + for (ModelObject objectEffectivity : effectivities) { + String statusName = releaseStatus.get_name(); + if (EFFECTIVITY.equals(statusName)) { + Effectivity effectivity = (Effectivity) objectEffectivity; + String effectivityRange = effectivity.get_range_text(); + log.debug("Check is current TcEffectivity range : {} is equal to {}", effectivityRange, targetUnit); + if (equalsRangeStart(targetUnit, effectivityRange)) { + return true; + } + } + } + return false; + } + + protected boolean getClosestProductUnit(final TcSession session, final String productID, final int targetUnit, final List unitsRevision) throws NotFoundException { + if (unitsRevision.isEmpty()) { + throw new NotFoundException("No unitRevision exists for Product " + productID + WITH_UNIT + targetUnit); + } + for (ItemRevision unitRevision : unitsRevision) { + session.loadProperties(unitRevision, "release_status_list"); + ReleaseStatus[] releaseStatuses = unitRevision.get_release_status_list(); + session.loadProperties(releaseStatuses); + for (ReleaseStatus status : releaseStatuses) { + if (getExactUnitInEffectivities(session, status, targetUnit)) { + return true; + } + } + } + return false; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/ObjectInfoLoader.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/ObjectInfoLoader.java new file mode 100644 index 0000000..28c4685 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/ObjectInfoLoader.java @@ -0,0 +1,396 @@ +package com.capgemini.reports.teamcenter; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.exceptions.UserInputErrorEnum; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import com.capgemini.reports.reports.parameters.Generics; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.capgemini.reports.teamcenter.queries.DirectQuery; +import com.capgemini.reports.teamcenter.queries.saved.GenericAssembQuery; +import com.capgemini.reports.teamcenter.queries.saved.GenericQuery; +import com.capgemini.reports.teamcenter.queries.saved.ProductTypeQuery; +import com.capgemini.reports.teamcenter.queries.saved.UnitQuery; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.*; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; + +import static com.capgemini.framework.teamcenter.TeamcenterObjectTypes.ITEM_REVISION; +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_CLAUSE_PROPRIETE; +import static com.capgemini.framework.teamcenter.object.SnecmaObjectProperties.PV_TYPE_PRODUIT; +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.EFFECTIVITY; + +/** + * This class is able to send requests to the Teamcenter servers to obtain information that hasn't been loaded yet.
    + * Typical functionality is to fetch an object using its UID, load related documents or workflows, etc. + */ +@Slf4j +public class ObjectInfoLoader { + + private static final String TYPE = "Type : "; + private static final String SEARCH_UNIT_OF_PRODUCT_ID = "search unit of product ID: "; + private static final String SAVED_QUERY = "saved query : "; + private static final String UNIT_REVISION_DOES_NOT_CONTAIN_EFFECTIVITIES = "Unit Revision does not contain Effectivities..."; + + protected final TcSession session; + + /** + * Constructs a {@link ObjectInfoLoader} with the {@link TcSession} to be used for the queries. + * + * @param session the {@link TcSession} to be used for the queries. + */ + public ObjectInfoLoader(final TcSession session) { + this.session = session; + } + + /** + * Requests the 'clause de propriete' on a product type. + * + * @param typeProduit the 'type produit' property + * @param session the Tc session to make the query + * @return the clause de propriete + * @throws NotFoundException if unable to find the form + */ + public static String getClausePropriete(final String typeProduit, final TcSession session) throws NotFoundException { + ProductTypeQuery theQuery = new ProductTypeQuery(session); + theQuery.addNomTypeProduit(typeProduit.trim()); + List result = theQuery.findAll(); + for (Form form : result) { + session.loadProperties(form, PV_CLAUSE_PROPRIETE); + return form.getPropertyObject(PV_CLAUSE_PROPRIETE).getStringValue(); + } + throw new NotFoundException("Could not find a Form with the clause de propriete"); + } + + /** + * Returns the Product Type of a given ItemRevision.
    + * + * @param itemRevision the item rev + * @return the product type as a String + */ + public static String getProductType(final TcSession session, final ItemRevision itemRevision) { + // By rule, an itemRevision only owns a single Master Form Revision + Form masterForm = itemRevision.get_item_master_tag(); + session.loadProperties(masterForm); + return masterForm.getPropertyObject(PV_TYPE_PRODUIT).getStringValue(); + } + + private List getUnits(final ReleaseStatus releaseStatus) throws NotFoundException { + session.loadProperties(releaseStatus, "effectivities"); + ModelObject[] effectivities = releaseStatus.get_effectivities(); + session.loadProperties(effectivities); + if (effectivities == null) { + log.error(UNIT_REVISION_DOES_NOT_CONTAIN_EFFECTIVITIES); + throw new NotFoundException(UNIT_REVISION_DOES_NOT_CONTAIN_EFFECTIVITIES); + } + + List listOfUnits = new ArrayList<>(); + for (ModelObject objectEffectivity : effectivities) { + if (EFFECTIVITY.equals(releaseStatus.get_name())) { + Effectivity effectivity = (Effectivity) objectEffectivity; + String unitRange = effectivity.get_unit_range_text(); + log.debug("Unit range : " + unitRange); + listOfUnits.add(unitRange); + } + } + return listOfUnits; + } + + /** + * Renvoie une liste de Generique revision pour le produit dont l'ID est passe en parametre. + * + * @param productUnit le {@link ProductUnit} + * @return List de Generic Ids + * @throws NotFoundException if the Generic, the Product or the Unit could not be found + */ + public List getGenericsRevisionOfProduct(final ProductUnit productUnit) throws NotFoundException { + return getGenericsRevisionOfProduct(productUnit.getProductID(), productUnit.getUnit()); + } + + /** + * Renvoie une liste de Générique Montage revision pour le produit-unit est passé en paramètre. + * + * @param aProductUnit {@link ProductUnit} produit + * @return List de GenericsAssemblies + * @throws NotFoundException if the Generic Assemb, the Product or the Unit could not be found + */ + public List getGenericsAssembliesRevisionOfProduct(final ProductUnit aProductUnit) throws NotFoundException { + return getGenericsAssembliesRevisionOfProduct(aProductUnit.getProductID(), aProductUnit.getUnit()); + } + + /** + * Renvoie une liste de Generique revision pour le produit dont l'ID est passe en parametre. + * + * @param anObjectID Object ID du produit + * @param unit unit du produit + * @return List de Generic IDs + * @throws NotFoundException if the product could not be found + */ + public List getGenericsRevisionOfProduct(final String anObjectID, final int unit) throws NotFoundException { + return getObjectRevisionOfProduct(new GenericQuery(session), anObjectID, unit); + } + + /** + * Renvoie une liste de Générique Montage revision pour le produit dont l'ID et le unitest passé en paramètre. + * + * @param aProductID Id du produit + * @param unit unit du produit + * @return List de GenericsAssemblies + * @throws NotFoundException if the Product could not be found + */ + public List getGenericsAssembliesRevisionOfProduct(final String aProductID, final int unit) + throws NotFoundException { + return getObjectRevisionOfProduct(new GenericAssembQuery(session), aProductID, unit); + } + + /** + * Common sub method for retrieving a list of generic or generic assemb. + * + * @return a {@link List} of revisions + * @throws NotFoundException if the end item could not be found + */ + private List getObjectRevisionOfProduct(final AbstractReplicatedQuery aQuery, final String anEndItemId, final int unit) + throws NotFoundException { + // Setup the query + aQuery.addEndItemID(anEndItemId); + aQuery.addEffectivityUnitIntro(Integer.toString(unit)); + + // Obtain the list of Generics or Generics Assemb + List result = aQuery.findAll(); + if (result.isEmpty()) { + String msg = aQuery.getClass().getName() + " Could not find the request Item Revision..."; + log.error(msg); + throw new NotFoundException(msg); + } + + // Populate return list with the IDs + List listGenOrGenAssemb = new ArrayList<>(); + for (ItemRevision generic : result) { + String itemId = generic.get_item_id(); + log.debug("{} Returned an object with ID : {}", aQuery.getClass().getName(), itemId); + listGenOrGenAssemb.add(itemId); + } + + return listGenOrGenAssemb; + } + + /** + * Renvoie une liste de Unit pour le produit dont l'ID est passé en paramêtre. + * + * @param productID "end_item_id" L'identifiant unique Teamcenter + * @return Liste of Unit as {@link String} + * @throws NotFoundException if no effectivities are found on the ReleaseStatus + */ + public List getUnitsOfProduct(final String productID) throws NotFoundException { + // Setup the query + UnitQuery unitQuery = new UnitQuery(session); + unitQuery.addEndItemID(productID); + + // Perform the query: Obtain the list of all the UNIT Revision of that product + List result = unitQuery.findAll(); + if (result.isEmpty()) { + log.debug("No unit has been found using {} on product {}", unitQuery.getClass().getName(), productID); + return new ArrayList<>(); + } + + // Parse the result to obtain the Units + List listOfUnits = new ArrayList<>(); + for (ItemRevision unitRevision : result) { + session.loadProperties(unitRevision, "release_status_list"); + ReleaseStatus[] releaseStatuses = unitRevision.get_release_status_list(); + session.loadProperties(releaseStatuses); + for (ReleaseStatus status : releaseStatuses) { + listOfUnits.addAll(getUnits(status)); + } + } + return listOfUnits; + } + + /** + * Returns the ID of the object whose UID is provided. + * + * @param objectUID Lthe unique Teamcenter ID + * @return the ID + * @throws NotFoundException if the object does not point a Revision or Item + */ + public String getObjectID(final String objectUID) throws NotFoundException { + // Perform a query of the database + ModelObject modelObject = new DirectQuery<>(session).searchByUID(objectUID); + String itemID; + if (modelObject.getTypeObject().isInstanceOf(ITEM_REVISION)) { + ItemRevision queryItemRevision = (ItemRevision) modelObject; + itemID = queryItemRevision.get_item_id(); + } else if (modelObject.getTypeObject().isInstanceOf("Item")) { + Item queryItem = (Item) modelObject; + itemID = queryItem.get_item_id(); + } else { + String msg = "QueryObject is neither Item nor ItemRevision"; + log.error(msg); + throw new NotFoundException(msg); + } + return itemID; + } + + /** + * Get {@link ItemRevision} of current object by uid. + * + * @param objectUID the (String) unique identifier + * @return the {@link ItemRevision} + * @throws NotFoundException if the object could not be found + * @throws InvalidUserInputException if If the uid does not point to a Tc object at all + */ + public ItemRevision getItemRevisionByUID(final String objectUID) throws NotFoundException, InvalidUserInputException { + // Obtain the Object + ModelObject modelObject; + try { + modelObject = new DirectQuery<>(session).searchByUID(objectUID); + } catch (NotFoundException e) { + throw new NotFoundException("The provided UID could not be found", e); + } + + if (!modelObject.getTypeObject().isInstanceOf(ITEM_REVISION)) { + // The Object is not an ItemRevision! + String msg = "QueryObject is not an ItemRevision"; + log.error(msg); + throw new InvalidUserInputException(UserInputErrorEnum.OBJECT_DOES_NOT_EXIST); + } + return (ItemRevision) modelObject; + } + + /** + * Get generic revision by generic id, product id, effectivity date with saved query. + * + * @param produit the {@link ProductUnit} + * @param generic the {@link Generics} + * @param effectivityDate the {@link EffectivityDate} + * @return listGeneric the list of Generic revisions for the input product/unit + * @throws NotFoundException if the generic is not found + */ + public List getGenericsRevisionOfProductWithDate(final ProductUnit produit, final Generics generic, final EffectivityDate effectivityDate) + throws NotFoundException { + return getObjectRevisionOfProductWithDate(new GenericQuery(session), generic.getID(), produit.getProductID(), + effectivityDate.getFormattedDateForTcRequest()); + } + + /** + * Get generic assemb revision by generic id, product id, effectivity date with saved query. + * + * @param produit the {@link ProductUnit} + * @param generic the {@link Generics} + * @param effectivityDate the {@link EffectivityDate} + * @return listGeneric the list of Generic Assemb revisions for the input product/unit + * @throws NotFoundException if the generic assemb is not found + */ + public List getGenericsAssembRevisionOfProductWithDate(final ProductUnit produit, final Generics generic, + final EffectivityDate effectivityDate) throws NotFoundException { + return getObjectRevisionOfProductWithDate(new GenericAssembQuery(session), generic.getID(), produit.getProductID(), + effectivityDate.getFormattedDateForTcRequest()); + } + + /** + * Returns the Revisions of a Product. + */ + private List getObjectRevisionOfProductWithDate(final AbstractReplicatedQuery aQuery, final String itemID, + final String anEndItemId, final String dateToday) throws NotFoundException { + // Setup the query + aQuery.searchID(itemID); + aQuery.addEndItemID(anEndItemId); + aQuery.addBeforeDate(dateToday); + + // Obtain the list of Generics or Generics Assemb + List result = aQuery.findAll(); + if (result.isEmpty()) { + String msg = aQuery.getClass().getName() + " Could not find the requeste ItemRevision..."; + log.error(msg); + throw new NotFoundException(msg); + } + + // Populate return list with the IDs + List listGenOrGenAssemb = new ArrayList<>(); + for (ItemRevision generic : result) { + log.debug(TYPE + generic.getTypeObject().getName()); + String itemId = generic.get_item_id(); + log.debug("{} found an object with ID : {}", aQuery.getClass().getName(), itemId); + listGenOrGenAssemb.add(itemId); + } + + return listGenOrGenAssemb; + } + + /** + * Retourne une lise d'item revision de type Unit. + * + * @param product the {@link ProductUnit} + * @return list of Units as {@link ItemRevision} + * @throws NotFoundException if no object is found + */ + public List getUnitsOfProduct(final ProductUnit product) throws NotFoundException { + UnitQuery unitQuery = new UnitQuery(session); + log.trace(SAVED_QUERY + unitQuery.getClass().getName()); + log.trace(SEARCH_UNIT_OF_PRODUCT_ID + product.getProductID()); + return getObjectUnderProduct(product.getProductID(), unitQuery); + } + + /** + * Retourne une lise d'item revision de type Generic. + * + * @param generic the {@link Generics} + * @param product the {@link ProductUnit} + * @return liste d'item revision de type Generic + * @throws NotFoundException if no object is found + */ + public List getGenericUnderProduct(final Generics generic, final ProductUnit product) + throws NotFoundException { + GenericQuery genericQuery = new GenericQuery<>(session); + genericQuery.searchID(generic.getID()); + return getObjectUnderProduct(product.getProductID(), genericQuery); + } + + /** + * Retourne une liste d'item revision de type Generic Assemb. + * + * @param generic the {@link Generics} + * @param product the {@link ProductUnit} + * @return liste d'item revision de type Generic Assemb + * @throws NotFoundException if no object is found + */ + public List getGenericAssembUnderProduct(final Generics generic, final ProductUnit product) throws NotFoundException { + GenericAssembQuery genericAssembQuery = new GenericAssembQuery<>(session); + genericAssembQuery.searchID(generic.getID()); + return getObjectUnderProduct(product.getProductID(), genericAssembQuery); + } + + private List getObjectUnderProduct(final String endItem, final AbstractReplicatedQuery aQuery) + throws NotFoundException { + aQuery.addEndItemID(endItem); + log.trace("{} is searching under product {}", aQuery.getClass().getName(), endItem); + List result = aQuery.findAll(); + if (result.isEmpty()) { + String msg = aQuery.getClass().getName() + " did not return any matching Item Revision..."; + log.error(msg); + throw new NotFoundException(msg); + } + return result; + } + + /** + * Search active sequence of a current itemRevision by item_id/rev_id.
    + * And return the active item revision, the item revision may not be the same as that in parameter ex:
    + * INT : part_xx/A.1
    + * OUT : part_xx/A.3 + * + * @param itemRevision the ItemRev whose active sequence we seek + * @return activeItemRevision + */ + public ItemRevision searchActiveSequence(final ItemRevision itemRevision) { + List listItemRevActiveSeq = new ItemRevisionQuery(session) + .searchIDAndRevision(itemRevision.get_item_id(), itemRevision.get_item_revision_id()).findAll(); + return listItemRevActiveSeq.get(0); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/Platform.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/Platform.java new file mode 100644 index 0000000..2c9f2be --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/Platform.java @@ -0,0 +1,19 @@ +package com.capgemini.reports.teamcenter; + +import com.capgemini.framework.teamcenter.authent.FscParameters; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * Represents a TC platform. + */ +@Getter +@AllArgsConstructor +public enum Platform { + PF36("http://10.24.192.36:80/tc/", new FscParameters("http://10.24.192.36:4544", new String[]{"http://10.24.192.36:4544"}, new String[]{"http://10.24.192.36:4544"}, "C:/Users/Public/kurt/FSCcache")), + AIX("http://10.69.165.176:6666/tcval", new FscParameters("http://10.69.165.201:4544", new String[]{"http://10.69.165.201:4544"}, new String[]{"http://10.69.165.201:4544"}, "C:/Users/Public/kurt/FSCcache")), + MIG("http://10.24.192.23:5555/tcmig/", new FscParameters("http://10.69.165.198:4544", new String[]{"http://10.69.165.198:4544"}, new String[]{"http://10.69.165.198:4544"}, "C:/Users/Public/kurt/FSCcache")); + + private final String connectionAddress; + private final FscParameters fmsParams; +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/DirectQuery.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/DirectQuery.java new file mode 100644 index 0000000..8ee2f98 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/DirectQuery.java @@ -0,0 +1,33 @@ +package com.capgemini.reports.teamcenter.queries; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.reports.exceptions.NotFoundException; +import com.teamcenter.soa.client.model.ModelObject; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +/** + * Request a Teamcenter object directly using its Unique ID (UID). + */ +@Slf4j +public class DirectQuery { + + private final TcSession session; + + public DirectQuery(final TcSession session) { + this.session = session; + } + + /** + * Direct search using a unique ID (UID). + */ + public T searchByUID(final String objectUID) throws NotFoundException { + List modelObjects = session.loadObjects(objectUID); + if (modelObjects.isEmpty()) { + throw new NotFoundException("DirectQuery returned no result for UID=\"" + objectUID + "\""); + } else { + return modelObjects.get(0); + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/TypeQuery.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/TypeQuery.java new file mode 100644 index 0000000..0c6e252 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/TypeQuery.java @@ -0,0 +1,88 @@ +package com.capgemini.reports.teamcenter.queries; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.teamcenter.schemas.soa._2006_03.exceptions.ServiceException; +import com.teamcenter.services.strong.query._2007_06.Finder.FindWorkspaceObjectsResponse; +import com.teamcenter.services.strong.query._2007_06.Finder.WSOFindCriteria; +import com.teamcenter.services.strong.query._2007_06.Finder.WSOFindSet; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.*; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; + +/** + * Searches for a specific item by its name, with its type specified by the Type Parameter. + * + * @param The type of object to look for. T must extends {@link ModelObject}.
    + * Example: {@link Item}, {@link ItemRevision}, {@link Form}, {@link RevisionRule}. + */ +@Slf4j +public class TypeQuery { + + private final TcSession session; + + private final Class typeParameterClass; + + /** + * Basic constructor. + * + * @param session required to perform the query. + * @param typeParameterClass the Teamcenter {@code class} of the requested object. + */ + private TypeQuery(final TcSession session, final Class typeParameterClass) { + this.session = session; + this.typeParameterClass = typeParameterClass; + } + + /** + * Searches for a specific {@link RevisionRule} by its name. + * + * @param session an active session + * @param objectName the name of the Revision Rule + * @return a {@link List} of results + */ + public static List getRevisionRule(final TcSession session, final String objectName) { + List list = new TypeQuery<>(session, RevisionRule.class).get(objectName); + List output = new ArrayList<>(); + for (ModelObject foundObject : list) { + output.add((RevisionRule) foundObject); + } + return output; + } + + /** + * Perform a {@link TypeQuery} using the specified object name.
    + * Usage: new TypeQuery(getSession(), ItemRevision.class).findAll(itemID); + * + * @param objectName the name of the object + * @return a List containing all matching elements. + */ + private List get(final String objectName) { + WSOFindCriteria criteria = new WSOFindCriteria(); + criteria.objectType = typeParameterClass.getSimpleName(); + criteria.objectName = objectName; + criteria.scope = "WSO_scope_All"; + + WSOFindSet findSet = new WSOFindSet(); + findSet.criterias = new WSOFindCriteria[]{criteria}; + FindWorkspaceObjectsResponse findWorkspaceObjects; + try { + findWorkspaceObjects = session.getFinderService().findWorkspaceObjects(new WSOFindSet[]{findSet}); + } catch (ServiceException e) { + log.warn("finderService failed to deliver WorkspaceObjects", e); + return new ArrayList<>(); + } + if (findWorkspaceObjects.outputList.length > 0) { + // Need to cast each sub-element of the list + List list = new ArrayList<>(); + for (WorkspaceObject workspaceObject : findWorkspaceObjects.outputList[0].foundObjects) { + list.add(typeParameterClass.cast(workspaceObject)); + } + return list; + } + // Nothing found + return new ArrayList<>(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/AllSequencesOfItemQuery.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/AllSequencesOfItemQuery.java new file mode 100644 index 0000000..b20cb47 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/AllSequencesOfItemQuery.java @@ -0,0 +1,43 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +/** + * This class performs requests to obtain all sequences and revisions of an object, given its ID. + */ +public class AllSequencesOfItemQuery extends AbstractReplicatedQuery { + + /** + * Query name of Teamcenter for request in WKF objects. + */ + private static final String QUERY_SUFFIX = "All_Sequences"; + + /** + * Usual constructor with a {@link TcSession} using a proper policy. + * + * @param session an active session + */ + public AllSequencesOfItemQuery(final TcSession session) { + super(session, QUERY_SUFFIX); + } + + /** + * Obtains all sequences fo all revisions of an Item. + * + * @param itemId the item whose sequences we are looking for + * @return the query + */ + + @Override + public AllSequencesOfItemQuery searchID(final String itemId) { + return this.addParam(PARAM_ITEM_ID, itemId); + } + + @Override + protected AllSequencesOfItemQuery selfCast() { + return this; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/ChangeFromPartQuery.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/ChangeFromPartQuery.java new file mode 100644 index 0000000..9cad2c1 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/ChangeFromPartQuery.java @@ -0,0 +1,42 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +/** + * This class is able to look for ChangeItem Revision objects in Teamcenter from a Part. + */ +public class ChangeFromPartQuery extends AbstractReplicatedQuery { + /** + * Query name of Teamcenter for request in Unit objects. + */ + private static final String QUERY_SUFFIX_CHANGE_FROM_PART = "Change_from_Part"; + private static final String PARAM_PART_ID = "part_id"; + private static final String PARAM_PART_REVISION = "part_revision"; + + /** + * Constructor to build a Query for ChangeItem objects from a Part. + * + * @param session the session for the connection + */ + public ChangeFromPartQuery(final TcSession session) { + super(session, QUERY_SUFFIX_CHANGE_FROM_PART); + } + + @Override + public ChangeFromPartQuery searchID(final String partId) { + return this.addParam(AbstractReplicatedQuery.REPCOL_PREFIX + PARAM_PART_ID, partId); + } + + + @Override + public ChangeFromPartQuery searchRevision(final String partRevision) { + return this.addParam(AbstractReplicatedQuery.REPCOL_PREFIX + PARAM_PART_REVISION, partRevision); + } + + @Override + protected ChangeFromPartQuery selfCast() { + return this; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/ChangeNoticeR07Query.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/ChangeNoticeR07Query.java new file mode 100644 index 0000000..032d4e6 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/ChangeNoticeR07Query.java @@ -0,0 +1,42 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +/** + * Class which allow to findAll change notice which is rely on a part. + */ +public class ChangeNoticeR07Query extends AbstractReplicatedQuery { + /** + * Query name of Teamcenter for request in Unit objects. + */ + private static final String QUERY_SUFFIX_CHANGE_FROM_PART = "ChangeNotice_R07"; + private static final String PARAM_PART_ID = "part_id"; + private static final String PARAM_PART_REVISION = "part_revision"; + + /** + * Constructor to build a Query for ChangeItem objects from a Part. + * + * @param session the session for the connection + */ + public ChangeNoticeR07Query(final TcSession session) { + super(session, QUERY_SUFFIX_CHANGE_FROM_PART); + } + + @Override + public ChangeNoticeR07Query searchID(final String partId) { + return this.addParam(AbstractReplicatedQuery.REPCOL_PREFIX + PARAM_PART_ID, partId); + } + + + @Override + public ChangeNoticeR07Query searchRevision(final String partRevision) { + return this.addParam(AbstractReplicatedQuery.REPCOL_PREFIX + PARAM_PART_REVISION, partRevision); + } + + @Override + protected ChangeNoticeR07Query selfCast() { + return this; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/ChangeRequestQuery.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/ChangeRequestQuery.java new file mode 100644 index 0000000..1bda815 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/ChangeRequestQuery.java @@ -0,0 +1,31 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +/** + * This class is able to look for ChangeRequest Revision objects in Teamcenter. + */ +public class ChangeRequestQuery extends AbstractReplicatedQuery { + + /** + * Query name of Teamcenter for request in change objects. + */ + private static final String QUERY_SUFFIX = "ChangeRequest"; + + /** + * Constructor to build a Query for ChangeRequests objects. + * + * @param session {@link TcSession} - the session for the connection + */ + public ChangeRequestQuery(final TcSession session) { + super(session, QUERY_SUFFIX); + } + + @Override + protected ChangeRequestQuery selfCast() { + return this; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/ChangeRequestR07Query.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/ChangeRequestR07Query.java new file mode 100644 index 0000000..80f29b9 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/ChangeRequestR07Query.java @@ -0,0 +1,44 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +/** + * Queries all ChangeRevisions attached to an object. + */ +public class ChangeRequestR07Query extends AbstractReplicatedQuery { + + /** + * Query name of Teamcenter request. + */ + private static final String QUERY_SUFFIX_CHANGE_FROM_PART = "ChangeRequest_R07"; + private static final String PARAM_PART_ID = "part_id"; + private static final String PARAM_PART_REVISION = "part_revision"; + + /** + * Constructor to build a Query for ChangeItem objects from a Part. + * + * @param session the session for the connection + */ + public ChangeRequestR07Query(final TcSession session) { + super(session, QUERY_SUFFIX_CHANGE_FROM_PART); + } + + @Override + public ChangeRequestR07Query searchID(final String partId) { + return this.addParam(AbstractReplicatedQuery.REPCOL_PREFIX + PARAM_PART_ID, partId); + } + + + @Override + public ChangeRequestR07Query searchRevision(final String partRevision) { + return this.addParam(AbstractReplicatedQuery.REPCOL_PREFIX + PARAM_PART_REVISION, partRevision); + } + + @Override + protected ChangeRequestR07Query selfCast() { + return this; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/ChangeRequestWithSeqQuery.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/ChangeRequestWithSeqQuery.java new file mode 100644 index 0000000..d6d8851 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/ChangeRequestWithSeqQuery.java @@ -0,0 +1,31 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +/** + * This class is able to look for ChangeRequest Revision objects in Teamcenter.
    + * This query contains all the sequences of the revisions. + */ +public class ChangeRequestWithSeqQuery extends AbstractReplicatedQuery { + + /** + * Query name of Teamcenter for request in change objects. + */ + private static final String QUERY_SUFFIX = "ChangeRequest_With_Seq"; + + /** + * Constructor to build a Query for ChangeRequests objects. + * + * @param session {@link TcSession} - the session for the connection + */ + public ChangeRequestWithSeqQuery(final TcSession session) { + super(session, QUERY_SUFFIX); + } + + @Override + protected ChangeRequestWithSeqQuery selfCast() { + return this; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/FppWithSeqQuery.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/FppWithSeqQuery.java new file mode 100644 index 0000000..7a3e79f --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/FppWithSeqQuery.java @@ -0,0 +1,31 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +/** + * This class is able to look for FPP Revision objects in Teamcenter.
    + * This query contains all the sequences of the revisions. + */ +public class FppWithSeqQuery extends AbstractReplicatedQuery { + + /** + * Query name of Teamcenter for request in FPP objects. + */ + private static final String QUERY_SUFFIX = "FPP_With_Seq"; + + /** + * Constructor to build a Query for FPP objects. + * + * @param session {@link TcSession}the session for the connection + */ + public FppWithSeqQuery(final TcSession session) { + super(session, QUERY_SUFFIX); + } + + @Override + protected FppWithSeqQuery selfCast() { + return this; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/GenericAssembQuery.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/GenericAssembQuery.java new file mode 100644 index 0000000..6ca15bb --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/GenericAssembQuery.java @@ -0,0 +1,37 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +/** + * This class is able to look for GenericAssemb objects in Teamcenter. + * + * @param the expected type of the Object: either {@link Item} or {@link ItemRevision} + */ +public class GenericAssembQuery extends AbstractReplicatedQuery> { + + /** + * Query name of Teamcenter for requesting a GenericAssemb. + */ + protected static final String QUERY_SUFFIX_GENERIC_ASSEMB = "Generic Assemb"; + + + /** + * Constructor to build a Query for GenericAssemb objects. + * + * @param session the session for the connection + */ + public GenericAssembQuery(final TcSession session) { + super(session, QUERY_SUFFIX_GENERIC_ASSEMB); + } + + + @Override + protected GenericAssembQuery selfCast() { + return this; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/GenericQuery.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/GenericQuery.java new file mode 100644 index 0000000..5e8e6eb --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/GenericQuery.java @@ -0,0 +1,29 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.teamcenter.soa.client.model.ModelObject; + +/** + * This class is able to look for Generic objects in Teamcenter. + */ +public class GenericQuery extends AbstractReplicatedQuery> { + + /*** Query name of Teamcenter for requesting a Generic. */ + private static final String QUERY_SUFFIX_GENERIC = "Generic"; + + /** + * Constructor to build a Query for Generic objects. + * + * @param session the session for the connection + */ + public GenericQuery(final TcSession session) { + super(session, QUERY_SUFFIX_GENERIC); + } + + @Override + protected GenericQuery selfCast() { + return this; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/ProductTypeQuery.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/ProductTypeQuery.java new file mode 100644 index 0000000..c0834b5 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/ProductTypeQuery.java @@ -0,0 +1,39 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.teamcenter.soa.client.model.strong.Form; + +/** + * This class is able to look for Product types in Teamcenter. These objects are of type {@link Form}. + */ +public class ProductTypeQuery extends AbstractReplicatedQuery { + + /** + * Query name of Teamcenter for requesting a Product type. + **/ + private static final String QUERY_SUFFIX_PRODUCT_TYPE = "Product Type"; + + /** + * Constructor to build a Query for Product Types. + * + * @param session the session for the connection + */ + public ProductTypeQuery(final TcSession session) { + super(session, QUERY_SUFFIX_PRODUCT_TYPE); + } + + /** + * Request a specific product type name. + * + * @param typeProduit the 'type produit' name + */ + public void addNomTypeProduit(final String typeProduit) { + this.addParam(PARAM_NOM_TYPE_PRODUIT, typeProduit); + } + + @Override + protected ProductTypeQuery selfCast() { + return this; + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/UnitFromChangeRequestQuery.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/UnitFromChangeRequestQuery.java new file mode 100644 index 0000000..33d76f0 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/UnitFromChangeRequestQuery.java @@ -0,0 +1,38 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +/** + * This class is able to look for Unit Revision objects in Teamcenter from a ChangeRequest. + */ +public class UnitFromChangeRequestQuery extends AbstractReplicatedQuery { + + /** + * Query name of Teamcenter for request in Unit objects. + */ + private static final String QUERY_SUFFIX_UNIT_FROM_CR = "Unit_from_CR"; + private static final String PARAM_CHANGE_ID = "change_id"; + + /** + * Constructor to build a Query for Unit objects from a ChangeRequest. + * + * @param session the session for the connection + */ + public UnitFromChangeRequestQuery(final TcSession session) { + super(session, QUERY_SUFFIX_UNIT_FROM_CR); + } + + @Override + public UnitFromChangeRequestQuery searchID(final String alternateID) { + this.addParam(AbstractReplicatedQuery.REPCOL_PREFIX + PARAM_CHANGE_ID, alternateID); + return this; + } + + @Override + protected UnitFromChangeRequestQuery selfCast() { + return this; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/UnitQuery.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/UnitQuery.java new file mode 100644 index 0000000..2f1f134 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/UnitQuery.java @@ -0,0 +1,52 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.teamcenter.soa.client.model.strong.ItemRevision; + +/** + * This class is able to look for Unit Revision objects in Teamcenter. + */ +public class UnitQuery extends AbstractReplicatedQuery { + + /** + * Use this String in the Constructor to obtain Units that are going (or have gone) through a Workflow with this name. + */ + static final String UNIT_VALIDATION_UNIT_PAR_SO = "UNIT-Validation UNIT par SO"; + /** + * Query name of Teamcenter for request in Unit objects. + */ + private static final String QUERY_SUFFIX_UNIT = "Unit"; + private static final String QUERY_SUFFIX_UNIT_WITH_WKF = "Unit_With_WKF"; + private static final String TASK_NAME = "task_name"; + + /** + * Constructor to build a Query for Unit objects. + * + * @param session the session for the connection + */ + public UnitQuery(final TcSession session) { + super(session, QUERY_SUFFIX_UNIT); + } + + /** + * Constructor to build a Query for Unit objects. + * + * @param session the session for the connection + * @param wkfName (optional) Provide the name of a Workflow active or done on this unit. Input may be null or empty to deactivate this criteria.
    + * If the input is not empty, then the Unit MUST have a workflow with the provided name.
    + * Exemple value: {@link UnitQuery#UNIT_VALIDATION_UNIT_PAR_SO} + */ + public UnitQuery(final TcSession session, final String wkfName) { + super(session, (wkfName == null || wkfName.isEmpty()) ? QUERY_SUFFIX_UNIT : QUERY_SUFFIX_UNIT_WITH_WKF); + if (wkfName != null && !wkfName.isEmpty()) { + this.addParam(TASK_NAME, wkfName); + } + } + + @Override + protected UnitQuery selfCast() { + return this; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/WorkflowOnChangeQuery.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/WorkflowOnChangeQuery.java new file mode 100644 index 0000000..f2906d1 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/WorkflowOnChangeQuery.java @@ -0,0 +1,48 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.teamcenter.soa.client.model.strong.EPMTask; + +/** + * This class is able to look for WKF objects in Teamcenter from a Part. + */ +public class WorkflowOnChangeQuery extends AbstractReplicatedQuery { + + /** + * Query name of Teamcenter for request in WKF objects. + */ + private static final String QUERY_SUFFIX = "WKF_on_Change"; + private static final String PARAM_SUFFIX_WKF_NAME = REPCOL_PREFIX + "wkf_name"; + private static final String PARAM_SUFFIX_SEQUENCE_ID = REPCOL_PREFIX + "sequence_id"; + + /** + * Construct a Query to obtain the Workflow(s) acting on a specific ItemRevision. + * + * @param session the Tc session + */ + public WorkflowOnChangeQuery(final TcSession session) { + super(session, QUERY_SUFFIX); + } + + @Override + public WorkflowOnChangeQuery searchName(final String wkfName) { + return this.addParam(PARAM_SUFFIX_WKF_NAME, wkfName); + } + + /** + * Add a search on the sequence_id param. + * + * @param sequenceId the sequence ID + * @return the query + */ + public WorkflowOnChangeQuery searchSequenceId(final String sequenceId) { + return this.addParam(PARAM_SUFFIX_SEQUENCE_ID, sequenceId); + } + + @Override + protected WorkflowOnChangeQuery selfCast() { + return this; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/WorkflowOnUnitQuery.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/WorkflowOnUnitQuery.java new file mode 100644 index 0000000..0ae2317 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/queries/saved/WorkflowOnUnitQuery.java @@ -0,0 +1,44 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery; +import com.teamcenter.soa.client.model.strong.EPMTask; + +/** + * Search for a Workflow. + */ +public final class WorkflowOnUnitQuery extends AbstractReplicatedQuery { + + static final String UNIT_VALIDATION_UNIT_PAR_SO = "UNIT-Validation UNIT par SO"; + + /** + * Query name of Teamcenter for requesting a Workflow, by giving the ID of the Unit it was launched upon. + */ + private static final String QUERY_SUFFIX_WKF = "WKF_ValidationUnit_on_Unit"; + private static final String PARAM_SUFFIX_WKF_NAME = REPCOL_PREFIX + "wkf_name"; + private static final String PARAM_SUFFIX_UNIT_ID = REPCOL_PREFIX + "unit_id"; + + private WorkflowOnUnitQuery(final TcSession session, final String wkfSearchName) { + super(session, wkfSearchName); + } + + /** + * Construct a Query that will look for any Workflow named 'UNIT-Validation UNIT par SO' that was launched on the specified Unit. + * + * @param session the session + * @param unitID the ID of the Unit that the Workflow was working on + * @return the Query + */ + public static WorkflowOnUnitQuery searchValidationUnitParSO(final TcSession session, final String unitID) { + WorkflowOnUnitQuery workflowQuery = new WorkflowOnUnitQuery(session, QUERY_SUFFIX_WKF); + workflowQuery.addParam(PARAM_SUFFIX_WKF_NAME, UNIT_VALIDATION_UNIT_PAR_SO); + workflowQuery.addParam(PARAM_SUFFIX_UNIT_ID, unitID); + return workflowQuery; + } + + @Override + protected WorkflowOnUnitQuery selfCast() { + return this; + } + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/resolution/IBOMLineExplorer.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/resolution/IBOMLineExplorer.java new file mode 100644 index 0000000..1f32bf6 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/resolution/IBOMLineExplorer.java @@ -0,0 +1,25 @@ +package com.capgemini.reports.teamcenter.resolution; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolder.BOMLineHolderState; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.MalformedNomenclatureException; +import com.capgemini.reports.teamcenter.resolution.structureservice.SingleStructureServiceCaller; +import com.capgemini.reports.teamcenter.resolution.structureservice.SingleStructureServiceCaller.SingleLevelExpander; +import com.teamcenter.soa.client.model.strong.BOMLine; + +/** + * Use this interface to specify how explode a nomenclature, step by step, in a {@link SingleStructureServiceCaller}.
    + * Exemple: Explode a Generic, look for its RFGeneric, explod ONLY this RFGeneric, look for a PArt, return that Part.
    + */ +public interface IBOMLineExplorer { + + /** + * Explore a Top {@link BOMLineHolder}.
    + * The BOMLineHolder should already possess the Teamcenter objects ({@link BOMLine}s) so this BOM must be not built (status Frozen via {@link BOMLineHolderState}). + */ + BOMLineHolder explore(final TcSession session, final SingleLevelExpander expander, final BOMLineHolder bomLineHolder) throws EmptyNomenclatureException, InvalidInputException, + MalformedNomenclatureException; +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/resolution/structureservice/IStructureServiceCaller.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/resolution/structureservice/IStructureServiceCaller.java new file mode 100644 index 0000000..32736fd --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/resolution/structureservice/IStructureServiceCaller.java @@ -0,0 +1,27 @@ +package com.capgemini.reports.teamcenter.resolution.structureservice; + +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.exceptions.NoSuchBomViewException; +import com.capgemini.framework.teamcenter.resolution.filtering.ITcTypeFilter; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.MalformedNomenclatureException; +import com.capgemini.reports.filter.IFilterExplosionNomenclature; +import com.teamcenter.soa.client.model.strong.BOMLine; + +/** + * Interface for all Services than can perfom an explosion of Nomenclature on a given congiguration. + */ +public interface IStructureServiceCaller { + + /** + * Resolve a nomenclature for a given configuration, while only exposing objects that belong to the provided wanted types. + * + * @param topBomLine the configuration + * @param filter is a {@link ITcTypeFilter}. + * @return a {@link BOMLineHolder} representing the top Line of the nomenclature. + */ + BOMLineHolder resolve(final BOMLine topBomLine, final IFilterExplosionNomenclature filter) + throws EmptyNomenclatureException, NoSuchBomViewException, InvalidInputException, MalformedNomenclatureException; + +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/resolution/structureservice/MultiStructureServiceCaller.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/resolution/structureservice/MultiStructureServiceCaller.java new file mode 100644 index 0000000..200e03b --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/resolution/structureservice/MultiStructureServiceCaller.java @@ -0,0 +1,29 @@ +package com.capgemini.reports.teamcenter.resolution.structureservice; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.exceptions.NoSuchBomViewException; +import com.capgemini.framework.teamcenter.resolution.structureservice.MultiStructureServiceCallerRaw; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.filter.IFilterExplosionNomenclature; +import com.teamcenter.soa.client.model.strong.BOMLine; + +/** + * Wrapper dedicated to multi levels resolution of configurations. + **/ +public class MultiStructureServiceCaller implements IStructureServiceCaller { + + private final TcSession session; + + /** + * Constructor for multi levels resolution. + */ + public MultiStructureServiceCaller(final TcSession session) { + this.session = session; + } + + @Override + public BOMLineHolder resolve(final BOMLine topBomLine, final IFilterExplosionNomenclature filter) throws EmptyNomenclatureException, NoSuchBomViewException { + return new MultiStructureServiceCallerRaw(session).resolve(topBomLine, filter); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/resolution/structureservice/SingleStructureServiceCaller.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/resolution/structureservice/SingleStructureServiceCaller.java new file mode 100644 index 0000000..079373c --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/resolution/structureservice/SingleStructureServiceCaller.java @@ -0,0 +1,89 @@ +package com.capgemini.reports.teamcenter.resolution.structureservice; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.exceptions.NoSuchBomViewException; +import com.capgemini.framework.teamcenter.resolution.filtering.ITcTypeFilter; +import com.capgemini.framework.teamcenter.resolution.structureservice.SingleStructureServiceCallerRaw; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.MalformedNomenclatureException; +import com.capgemini.reports.filter.IFilterExplosionNomenclature; +import com.capgemini.reports.teamcenter.resolution.IBOMLineExplorer; +import com.teamcenter.soa.client.model.strong.BOMLine; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; + +/** + * Helper dedicated to single level resolution of configurations. + **/ +@Slf4j +public class SingleStructureServiceCaller implements IStructureServiceCaller { + + private final TcSession session; + + /** + * Constructor for single level resolution. + * + * @param session {@link TcSession} - Teamcenter session + */ + public SingleStructureServiceCaller(final TcSession session) { + this.session = session; + } + + @Override + public BOMLineHolder resolve(final BOMLine topBomLine, final IFilterExplosionNomenclature filter) throws EmptyNomenclatureException, NoSuchBomViewException { + return new SingleStructureServiceCallerRaw(session).resolve(topBomLine, filter); + } + + /** + * This method allows the caller to finely explode a nomenclature under a certain configuration.
    + * It allows fine control of which BoLines are opened, through the use of an {@link IBOMLineExplorer} which can open a BomLine one at a time.
    + * All the work will be performed using a single BomWindow. + */ + public BOMLineHolder resolve(final BOMLine topBomLine, final IBOMLineExplorer bomLineExplorer) throws EmptyNomenclatureException, NoSuchBomViewException, InvalidInputException, MalformedNomenclatureException { + SingleStructureServiceCallerRaw impl = new SingleStructureServiceCallerRaw(session); + // Do the exploration while the window is open + return bomLineExplorer.explore(session, new SingleLevelExpander(impl), new BOMLineHolder(topBomLine)); + } + + /** + * This class exists in the context of a bomWindow, and can expand a bom one level below, with a type filter.
    + * It is only able to expand a Bom while said window is open. + */ + @AllArgsConstructor(access = AccessLevel.PRIVATE) + public final class SingleLevelExpander { + + private final SingleStructureServiceCallerRaw impl; + + /** + * Expands a bom one level below the provided {@link BOMLineHolder}. + * + * @param target the parent {@link BOMLineHolder} whose children will be loaded + * @param filter a {@link ITcTypeFilter} to keep only the wanted objects types. + * @throws EmptyNomenclatureException if the nomenclature is empty + */ + public BOMLineHolder expand(final BOMLineHolder target, final ITcTypeFilter filter) throws EmptyNomenclatureException { + return impl.resolve(target.getBomLineObject(), filter); + } + + /** + * Expands a bom one level below the provided {@link BOMLineHolder}. + * + * @param targetBomLineHolders the parent {@link BOMLineHolder} whose children will be loaded + * @param filter a {@link ITcTypeFilter} to keep only the wanted objects types. + * @throws EmptyNomenclatureException if the nomenclature is empty + */ + public List expandEach(final List targetBomLineHolders, final ITcTypeFilter filter) throws EmptyNomenclatureException { + List bomLines = new ArrayList<>(targetBomLineHolders.size()); + for (BOMLineHolder holder : targetBomLineHolders) { + bomLines.add(impl.resolve(holder.getBomLineObject(), filter)); + } + return bomLines; + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/resolution/structureservice/TripleStructureServiceCaller.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/resolution/structureservice/TripleStructureServiceCaller.java new file mode 100644 index 0000000..24ee17e --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/resolution/structureservice/TripleStructureServiceCaller.java @@ -0,0 +1,187 @@ +package com.capgemini.reports.teamcenter.resolution.structureservice; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.exceptions.NoSuchBomViewException; +import com.capgemini.framework.teamcenter.resolution.filtering.*; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderHelper; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.MalformedNomenclatureException; +import com.capgemini.reports.filter.IFilterExplosionNomenclature; +import com.capgemini.reports.teamcenter.resolution.IBOMLineExplorer; +import com.capgemini.reports.teamcenter.resolution.structureservice.SingleStructureServiceCaller.SingleLevelExpander; +import com.teamcenter.soa.client.model.strong.BOMLine; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; + +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.*; + +/** + * Helper dedicated to triple levels resolution of configurations. + **/ +@Slf4j +public class TripleStructureServiceCaller implements IStructureServiceCaller { + + private final TcSession session; + + /** + * Constructor for Triple levels resolution. + */ + public TripleStructureServiceCaller(final TcSession session) { + this.session = session; + } + + @Override + public BOMLineHolder resolve(final BOMLine topBomLine, final IFilterExplosionNomenclature filter) throws EmptyNomenclatureException, NoSuchBomViewException, InvalidInputException, MalformedNomenclatureException { + return new SingleStructureServiceCaller(session).resolve(topBomLine, new TripleLevelExplorer(filter)); + } + + private static class TripleLevelExplorer implements IBOMLineExplorer { + private static final ITcTypeFilter RF_GENERIC_FILTER = new TcTypeInclusionFilter(RF_ADMIN_REVISION, RF_ADMIN_AG_REVISION, PART_AERO_REVISION); + private static final ITcTypeFilter COMPONENT_REJECTOR = new TcTypeExclusionFilter(RF_PART_REVISION, RF_PART_ASSEMB_REVISION, GENERIC_REVISION, GENERIC_ASSEMB_REVISION); + + private final ITcTypeFilter componentFilter; + + TripleLevelExplorer(final ITcTypeFilter componentFilter) { + this.componentFilter = componentFilter; + } + + @Override + public BOMLineHolder explore(final TcSession session, final SingleLevelExpander expander, final BOMLineHolder topLine) throws EmptyNomenclatureException, MalformedNomenclatureException { + log.debug("Expand level 1..."); + BOMLineHolder expandedTopLine = expander.expand(topLine, AllFilter.getInstance()); + log.debug("Expand level 1 DONE, size = {}", expandedTopLine.getBomChilds().size()); + + log.debug("Filter the results..."); + // filter out generics & rf generics from the rest (they must receive a special treatment) + List genericsComponents = new ArrayList<>(); + List rfParts = new ArrayList<>(); + BOMLineHolder rfGenericReceptor = filterChildren(expandedTopLine.getBomChilds(), genericsComponents, rfParts); + log.debug("Filtering DONE: {} generics, {} RF Generics and {} RF Part found", genericsComponents.size(), rfGenericReceptor == null ? 0 : 1, rfParts.size()); + + ITcTypeFilter rfGenFilter = new OrFilter(RF_GENERIC_FILTER, componentFilter); + if (rfGenericReceptor != null) { // happens If topline is a Generic / Generic Assemb + for (BOMLineHolder bomChild : expander.expand(rfGenericReceptor, rfGenFilter).getBomChilds()) { + rfGenericReceptor.addChild(bomChild); + } + } + + // Simply expand the lvl 1 RF Parts + log.debug("Expand All RF Parts.."); + List alternates = expandRfPartsExtractAlternates(expander, rfParts); + log.debug("Expand RF Part DONE"); + + // For each Alternate found expand one level further. + log.debug("Expand Alternates..."); + //List expandedAlternates = expander.expandEach(alternates, AllFilter.getInstance()); + for (BOMLineHolder alternate : alternates) { + for (BOMLineHolder bomChild : expander.expand(alternate, AllFilter.getInstance()).getBomChilds()) { + alternate.addChild(bomChild); + } + } + log.debug("Expand Alternates DONE"); + + // The Generics must be expanded. This may also return some RF Generics, which must be added to the existing list. + List rfGenericComponents = expandGenericComponents(expander, genericsComponents); + // RF Generics MUST have their RF Admin loaded because they hold relevant info + // expander.expandEach(rfGenericComponents, rfGenFilter); + for (BOMLineHolder rfGenericComponent : rfGenericComponents) { + for (BOMLineHolder bomChild : expander.expand(rfGenericComponent, rfGenFilter).getBomChilds()) { + rfGenericComponent.addChild(bomChild); + } + } + + log.debug("Mono-level expansion DONE"); + return expandedTopLine; + } + + + /** + * Second level of MONO explosion.
    + * This method expands the provided Generics, but only keeps their RF Generic (Assemb) children.
    + * they will be included into the tree of existing {@link BOMLineHolder}s. + */ + List expandGenericComponents(final SingleLevelExpander expander, final List generics) throws EmptyNomenclatureException, MalformedNomenclatureException { + log.debug("Expand newly found Generics.."); + //expander.expandEach(generics, new AndFilter(COMPONENT_REJECTOR, componentFilter)); // Each Generic now has children, but no further components + for (BOMLineHolder generic : generics) { + for (BOMLineHolder bomChild : expander.expand(generic, new TcTypeInclusionFilter(RF_GENERIC_REVISION)).getBomChilds()) { + generic.addChild(bomChild); + } + } + + // Filter only the RF Generics, add them to the BOMLineholder tree and return them + List rfGenerics = addAndGetRfGenerics(generics); + + log.debug("Expand Generics DONE: {} RF Generics found", rfGenerics.size()); + return rfGenerics; + } + + /** + * Expands one level below the provided RF Generics.
    + * The generated children are all linked to the existing {@link BOMLineHolder}s.
    + * This method also looks for any Alternate and returns them. + */ + List expandRfPartsExtractAlternates(final SingleLevelExpander expander, final List rfParts) throws EmptyNomenclatureException { + // Expand one level + log.debug("Expand RF Generics..."); + //List expandedRfParts = expander.expandEach(rfParts, AllFilter.getInstance());// Each RF Generic now has children + for (BOMLineHolder rfPart : rfParts) { + for (BOMLineHolder bomChild : expander.expand(rfPart, AllFilter.getInstance()).getBomChilds()) { + rfPart.addChild(bomChild); + } + } + + // look for alternates/DET in the children + List alternates = new ArrayList<>(); + for (BOMLineHolder rfPartBom : rfParts) { + for (BOMLineHolder child : rfPartBom.getBomChilds()) { + String objectType = child.getObjectType(); + if (ALTERNATE_REVISION.equals(objectType) || DET_REVISION.equals(objectType)) { + alternates.add(child); + } + } + } + log.debug("Expand RF Parts DONE: {} alternates found", alternates.size()); + return alternates; + } + + /** + * Adds the RG Generics found in the expansion results (with BOMLines) to the {@link BOMLineHolder} map provided. + */ + List addAndGetRfGenerics(final List generics) throws MalformedNomenclatureException { + List rfGenerics = new ArrayList<>(); + log.debug("addAndGetRfGenerics: {} items...", generics.size()); + for (BOMLineHolder gen : generics) { + // Register this BOMLine's children, and create the parent-child link + try { + rfGenerics.add(BOMLineHolderHelper.findRfGenericBL(gen)); + } catch (InvalidInputException e) { + log.error("Null BomLineHolder detected below a Generic", e); + } + } + log.debug("addAndGetRfGenerics: {} RF Generics found", rfGenerics.size()); + return rfGenerics; + } + + BOMLineHolder filterChildren(final List children, final List generics, final List rfPart) { + BOMLineHolder theTopRfGen = null; + for (BOMLineHolder child : children) { + String objectType = child.getObjectType(); + if (GENERIC_REVISION.equals(objectType) || GENERIC_ASSEMB_REVISION.equals(objectType) || SUPERMODEL_REVISION.equals(objectType)) { + generics.add(child); + } else { + if (RF_GENERIC_REVISION.equals(objectType)) { + theTopRfGen = child; + } else { + rfPart.add(child); + } + } + } + return theTopRfGen; + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/teamcenter/resolution/structureservice/explorer/PartNumberFinder.java b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/resolution/structureservice/explorer/PartNumberFinder.java new file mode 100644 index 0000000..d3b7770 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/teamcenter/resolution/structureservice/explorer/PartNumberFinder.java @@ -0,0 +1,38 @@ +package com.capgemini.reports.teamcenter.resolution.structureservice.explorer; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.EmptyNomenclatureException; +import com.capgemini.framework.teamcenter.resolution.filtering.TcTypeInclusionFilter; +import com.capgemini.reports.bomlineholder.BOMLineHolder; +import com.capgemini.reports.bomlineholder.BOMLineHolderHelper; +import com.capgemini.reports.exceptions.InvalidInputException; +import com.capgemini.reports.exceptions.MalformedNomenclatureException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.teamcenter.resolution.IBOMLineExplorer; +import com.capgemini.reports.teamcenter.resolution.structureservice.SingleStructureServiceCaller.SingleLevelExpander; +import lombok.extern.slf4j.Slf4j; + +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.PART_AERO_REVISION; +import static com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes.RF_GENERIC_REVISION; + +/** + * This class is an {@link IBOMLineExplorer} using a {@link SingleLevelExpander}.
    + * This class can locate and return the Part Number of a Generic (found below the RF Generic of said Generic). + */ +@Slf4j +public class PartNumberFinder implements IBOMLineExplorer { + + @Override + public BOMLineHolder explore(TcSession session, final SingleLevelExpander expander, final BOMLineHolder genericBom) + throws InvalidInputException, MalformedNomenclatureException, EmptyNomenclatureException { + try { + BOMLineHolder expandedGenericBom = expander.expand(genericBom, new TcTypeInclusionFilter(RF_GENERIC_REVISION)); + BOMLineHolder rfGenericBom = BOMLineHolderHelper.findRfGenericBL(expandedGenericBom); + BOMLineHolder expandedRfGenericBom = expander.expand(rfGenericBom, new TcTypeInclusionFilter(PART_AERO_REVISION)); + return BOMLineHolderHelper.findFirst(expandedRfGenericBom, PART_AERO_REVISION); + } catch (NotFoundException e) { + log.trace("No RF Generic previously loaded in the Generic", e); + return null; + } + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/users/SnecmaPerson.java b/teamcenter/src/main/java/com/capgemini/reports/users/SnecmaPerson.java new file mode 100644 index 0000000..4a69be9 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/users/SnecmaPerson.java @@ -0,0 +1,31 @@ +package com.capgemini.reports.users; + +import com.teamcenter.soa.client.model.strong.Person; + +import java.io.Serializable; + +/** + * Class representing a Person. + */ +public class SnecmaPerson implements Serializable { + private static final long serialVersionUID = 4489416228194869431L; + + private final Person person; + + public SnecmaPerson(final Person person) { + this.person = person; + } + + public String getPersonName() { + return person.get_user_name(); + } + + public String getCodeCourrier() { + return person.get_PA8(); + } + + @Override + public String toString() { + return "Person " + (getPersonName() == null ? "(no name)" : getPersonName()); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/users/SnecmaUser.java b/teamcenter/src/main/java/com/capgemini/reports/users/SnecmaUser.java new file mode 100644 index 0000000..60e8947 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/users/SnecmaUser.java @@ -0,0 +1,53 @@ +package com.capgemini.reports.users; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.teamcenter.soa.client.model.strong.Person; +import com.teamcenter.soa.client.model.strong.User; + +import java.io.Serializable; + +/** + * Represents a TC User. + */ +public class SnecmaUser implements Serializable { + private static final long serialVersionUID = -4311528092285199052L; + + private static final long ACTIVE_STATUS = 0; // TC code for active status is '0' + private final TcSession session; + private final User user; + + /** + * Builds a TC {@link User}. + */ + public SnecmaUser(final TcSession session, final User user) { + this.session = session; + this.user = user; + } + + public String getName() { + return user.get_user_name(); + } + + public String getUserId() { + return user.get_user_id(); + } + + public SnecmaPerson getPerson() { + session.loadProperties(user, "person"); + Person person = user.get_person(); + session.loadProperties(person); + return new SnecmaPerson(person); + } + + /** + * The values are 1 ("inactif") and 0 ("actif"). + */ + public boolean isActive() { + return user.get_status() == ACTIVE_STATUS; + } + + @Override + public String toString() { + return "User " + getName() + " ID=" + getUserId(); + } +} diff --git a/teamcenter/src/main/java/com/capgemini/reports/workflows/Task.java b/teamcenter/src/main/java/com/capgemini/reports/workflows/Task.java new file mode 100644 index 0000000..65ef493 --- /dev/null +++ b/teamcenter/src/main/java/com/capgemini/reports/workflows/Task.java @@ -0,0 +1,234 @@ +package com.capgemini.reports.workflows; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.reports.changeobjects.change.AbstractChangeObject; +import com.capgemini.reports.users.SnecmaUser; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.EPMTask; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.Signoff; +import com.teamcenter.soa.client.model.strong.User; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +import static com.capgemini.framework.teamcenter.TeamcenterObjectTypes.SIGNOFF; +import static com.capgemini.framework.teamcenter.TeamcenterObjectTypes.USER; + +/** + * Represents a TC EPMTask. + */ +@Slf4j +public class Task implements Serializable { + private static final long serialVersionUID = 2426203736278592266L; + + private static final int VAL_DECISION_PENDING = 0; + private final TcSession session; + private final EPMTask task; + + public Task(final TcSession session, final EPMTask task) { + this.session = session; + this.task = task; + } + + public String getType() { + return task.getTypeObject().getName(); + } + + public String getName() { + return task.get_object_name(); + } + + public SnecmaUser getOwningUser() { + session.loadProperties(task, "owning_user"); + User user = (User) task.get_owning_user(); + session.loadProperties(user); + return new SnecmaUser(session, user); + } + + public SnecmaUser getResponsibleUser() throws KurtException { + try { + session.loadProperties(task, "fnd0Assignee"); + User user = (User) task.get_fnd0Assignee(); + session.loadProperties(user); + return new SnecmaUser(session, user); + } + catch (ClassCastException e) { + throw new KurtException("Erreur lors de la récupération du User responsable.", e); + } + } + + + public SnecmaUser getLastModUser() { + + session.loadProperties(task, "last_mod_user"); + User user = (User) task.get_last_mod_user(); + session.loadProperties(user); + return new SnecmaUser(session, user); + } + + public Calendar getLastModDate() { + return task.get_last_mod_date(); + } + + public Calendar getCreationDate() { + return task.get_creation_date(); + } + + public Calendar getDueDate() { + return task.get_due_date(); + } + + public TaskState getState() { + return TaskState.findState(task.get_state()); + } + + public boolean isInTargetAttachments(final AbstractChangeObject change) { + session.loadProperties(task, "root_target_attachments"); + ModelObject[] rootTargetObjects = task.get_root_target_attachments(); + session.loadProperties(rootTargetObjects); + for (ModelObject object : rootTargetObjects) { + if (object instanceof ItemRevision) { + ItemRevision itemRevision = (ItemRevision) object; + if (itemRevision.get_item_id().equals(change.getItemId()) && itemRevision.get_item_revision_id().equals(change.getRevisionId())) { + return true; + } + } + } + return false; + } + + public List getActiveChildTasks() { + return getChildren(TaskState.STARTED); + } + + public List getCompletedChildTasks() { + return getChildren(TaskState.COMPLETED); + } + + public List getChildren(final TaskState state) { + List children = new ArrayList<>(); + session.loadProperties(task, "child_tasks"); + ModelObject[] childTasks = task.get_child_tasks(); + session.loadProperties(childTasks); + for (ModelObject childTask : childTasks) { + if (childTask instanceof EPMTask) { + if (state.equals(TaskState.findState(((EPMTask) childTask).get_state()))) { + children.add(new Task(session, (EPMTask) childTask)); + } + } + } + + return children; + } + + public List getPendingSignoffsUser() { + List pendingSignoffsUser = new ArrayList<>(); + session.loadProperties(task, "signoff_attachments"); + ModelObject[] signoffAttachments = task.get_signoff_attachments(); + session.loadProperties(signoffAttachments); + for (ModelObject signoff : signoffAttachments) { + if (SIGNOFF.equals(signoff.getTypeObject().getName()) && ((Signoff) signoff).get_decision() == VAL_DECISION_PENDING) { + session.loadProperties(signoff, "owning_user"); + User signoffOwner = (User) ((Signoff) signoff).get_owning_user(); + session.loadProperties(signoffOwner); + if (USER.equals(signoffOwner.getTypeObject().getName())) { + pendingSignoffsUser.add(new SnecmaUser(session, signoffOwner)); + } + } + } + + return pendingSignoffsUser; + } + + public boolean isRunning() { + return getState() == TaskState.STARTED; + } + + @Override + public String toString() { + return getType() + " " + getName(); + } + + + /** + * Represents the state of a Task. + */ + public enum TaskState { + UNASSIGNED, // Unassigned task state. Code 1. + PENDING, // Pending task state. Code 2. + STARTED, // Started task state. Code 4. + COMPLETED, // Completed task state. Code 8. + SKIPPED, // Skipped task state. Code 16. + ABORTED, // Aborted task state. Code 32. + FAILED, // Failed task state. Code 64. + SUSPENDED; // Suspended task state. Code 128. + + private static final int TC_CODE_FOR_SUSPENDED = 128; + private static final int TC_CODE_FOR_FAILED = 64; + private static final int TC_CODE_FOR_ABORTED = 32; + private static final int TC_CODE_FOR_SKIPPED = 16; + private static final int TC_CODE_FOR_COMPLETED = 8; + private static final int TC_CODE_FOR_STARTED = 4; + private static final int TC_CODE_FOR_PENDING = 2; + private static final int TC_CODE_FOR_UNASSIGNED = 1; + + /** + * Return the matching State enum instance form the TC int value, based on the TC convention. + */ + public static TaskState findState(final int intValue) { + switch (intValue) { + case TC_CODE_FOR_UNASSIGNED: + return TaskState.UNASSIGNED; + case TC_CODE_FOR_PENDING: + return TaskState.PENDING; + case TC_CODE_FOR_STARTED: + return TaskState.STARTED; + case TC_CODE_FOR_COMPLETED: + return TaskState.COMPLETED; + case TC_CODE_FOR_SKIPPED: + return TaskState.SKIPPED; + case TC_CODE_FOR_ABORTED: + return TaskState.ABORTED; + case TC_CODE_FOR_FAILED: + return TaskState.FAILED; + case TC_CODE_FOR_SUSPENDED: + return TaskState.SUSPENDED; + default: + log.error("Task State unknown: {}", intValue); + return null; + } + } + + /** + * Returns true if this {@link TaskState} and the provided Task code are a match. + */ + public boolean matches(final int intValue) { + switch (intValue) { + case TC_CODE_FOR_UNASSIGNED: + return this == TaskState.UNASSIGNED; + case TC_CODE_FOR_PENDING: + return this == TaskState.PENDING; + case TC_CODE_FOR_STARTED: + return this == TaskState.STARTED; + case TC_CODE_FOR_COMPLETED: + return this == TaskState.COMPLETED; + case TC_CODE_FOR_SKIPPED: + return this == TaskState.SKIPPED; + case TC_CODE_FOR_ABORTED: + return this == TaskState.ABORTED; + case TC_CODE_FOR_FAILED: + return this == TaskState.FAILED; + case TC_CODE_FOR_SUSPENDED: + return this == TaskState.SUSPENDED; + default: + log.error("Task Code unknown: {}", intValue); + return false; + } + } + } +} diff --git a/teamcenter/src/main/java/com/teamcenter/soa/exceptions/NotLoadedException.java b/teamcenter/src/main/java/com/teamcenter/soa/exceptions/NotLoadedException.java new file mode 100644 index 0000000..47e8906 --- /dev/null +++ b/teamcenter/src/main/java/com/teamcenter/soa/exceptions/NotLoadedException.java @@ -0,0 +1,14 @@ +package com.teamcenter.soa.exceptions; + +import com.capgemini.framework.teamcenter.exceptions.runtime.KurtRuntimeException; + +public class NotLoadedException extends KurtRuntimeException { + private static final long serialVersionUID = 6774158621504788960L; + + public NotLoadedException() { + } + + public NotLoadedException(String message) { + super(message); + } +} diff --git a/teamcenter/src/test/java/com/capgemini/framework/common/DummyBean.java b/teamcenter/src/test/java/com/capgemini/framework/common/DummyBean.java new file mode 100644 index 0000000..06bb2f5 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/framework/common/DummyBean.java @@ -0,0 +1,52 @@ +package com.capgemini.framework.common; + +/** + * Dummy test class.
    + * Required by: ReflectionHelperTest + **/ +public class DummyBean { + + private String fooString; + private int fooInt; + + /** Default constructor. **/ + public DummyBean() { + // Nothing to do but must be keep for reflection + } + + /** + * String getter. + * + * @return String value + **/ + public String getFooString() { + return fooString; + } + + /** + * String setter. + * + * @param aFooString String value + **/ + public void setFooString(String aFooString) { + fooString = aFooString; + } + + /** + * Integer getter. + * + * @return Integer value + **/ + public int getFooInt() { + return fooInt; + } + + /** + * Integer setter. + * + * @param aFooInt Integer value + **/ + public void setFooInt(int aFooInt) { + fooInt = aFooInt; + } +} diff --git a/teamcenter/src/test/java/com/capgemini/framework/common/ReflectionHelperTest.java b/teamcenter/src/test/java/com/capgemini/framework/common/ReflectionHelperTest.java new file mode 100644 index 0000000..d2331d1 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/framework/common/ReflectionHelperTest.java @@ -0,0 +1,28 @@ +package com.capgemini.framework.common; + +import junit.framework.Assert; +import org.junit.Test; + +public class ReflectionHelperTest { + private static final String DUMMY_BEAN_CLASSNAME = "com.capgemini.framework.common.DummyBean"; + private static final String WRONG_CLASSNAME = "com.capgemini.framework.common.WrongBean"; + + @Test + public void testGetClassForName() { + Class theClass = ReflectionHelper.getClassForName(DUMMY_BEAN_CLASSNAME); + Assert.assertEquals("Compare classes", DummyBean.class, theClass); + + Class theNullClass = ReflectionHelper.getClassForName(WRONG_CLASSNAME); + Assert.assertNull("Unknown class", theNullClass); + } + + @Test + public void testNewFromClassForName() { + Object theObj = ReflectionHelper.newFromClassForName(DUMMY_BEAN_CLASSNAME); + boolean isInstance = theObj instanceof DummyBean; + Assert.assertTrue("Compare classes", isInstance); + + Object theNullObj = ReflectionHelper.newFromClassForName(WRONG_CLASSNAME); + Assert.assertNull("Unknown class name for newInstance", theNullObj); + } +} diff --git a/teamcenter/src/test/java/com/capgemini/framework/common/StringHelperTest.java b/teamcenter/src/test/java/com/capgemini/framework/common/StringHelperTest.java new file mode 100644 index 0000000..36c00d6 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/framework/common/StringHelperTest.java @@ -0,0 +1,25 @@ +package com.capgemini.framework.common; + +import junit.framework.Assert; +import org.junit.Test; + +public class StringHelperTest { + + @Test + public void testTruncate() { + Assert.assertEquals("Truncated value", "12345", StringHelper.truncate("1234567890", 5)); + Assert.assertEquals("Equals to length value", "12345", StringHelper.truncate("12345", 5)); + Assert.assertEquals("Too small value", "1", StringHelper.truncate("1", 5)); + Assert.assertEquals("Null value", null, StringHelper.truncate(null, 5)); + } + + @Test + public void testSplitWithoutDelim() { + String value = "2015-11"; + String expected = "2015"; + + String delimiter = StringHelper.DASH; + String[] tokens = StringHelper.splitWithoutDelim(delimiter, value); + Assert.assertEquals("Expected the first range [" + expected + "] of value:" + value + " with delimiter [" + delimiter + "]", expected, tokens[0]); + } +} diff --git a/teamcenter/src/test/java/com/capgemini/framework/common/TeamcenterDateFormatterTest.java b/teamcenter/src/test/java/com/capgemini/framework/common/TeamcenterDateFormatterTest.java new file mode 100644 index 0000000..3e7ada3 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/framework/common/TeamcenterDateFormatterTest.java @@ -0,0 +1,30 @@ +package com.capgemini.framework.common; + +import junit.framework.Assert; +import lombok.extern.slf4j.Slf4j; +import org.junit.Test; + +import java.text.ParseException; +import java.util.Calendar; + + +@Slf4j +public class TeamcenterDateFormatterTest { + + /** + * JUNIT TEST. + * + * @throws ParseException should not happen + */ + @Test + public void testFormatCalendarToFrench() throws ParseException { + log.info("testCalendarWithTimeZoneFR ...."); + Calendar date = Calendar.getInstance(); + date.set(2015, 1, 2); // Feb 4th, 2015 + String dateFr = TeamcenterDateFormatter.formatCalendarToFrench(date); + log.info("Date FR : " + dateFr); + + log.info("With date to compare : " + date); + Assert.assertEquals("WRONG FORMAT DATE EXPECTED [DD MMMM YYYY], LOCALE FR", "02 février 2015", dateFr); + } +} diff --git a/teamcenter/src/test/java/com/capgemini/framework/teamcenter/files/DatasetPreparatorTest.java b/teamcenter/src/test/java/com/capgemini/framework/teamcenter/files/DatasetPreparatorTest.java new file mode 100644 index 0000000..dd2f1a2 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/framework/teamcenter/files/DatasetPreparatorTest.java @@ -0,0 +1,99 @@ +package com.capgemini.framework.teamcenter.files; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.MalformedDataSetException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.files.FileManagement.FileType; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.teamcenter.schemas.soa._2006_03.exceptions.InvalidCredentialsException; +import com.teamcenter.schemas.soa._2006_03.exceptions.ServiceException; +import com.teamcenter.services.loose.core._2006_03.FileManagement.GetDatasetWriteTicketsInputData; +import com.teamcenter.soa.client.model.ModelObject; +import junit.framework.Assert; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.File; +import java.util.NoSuchElementException; + +public class DatasetPreparatorTest { + private static final String DESCRIPTION = "A nice description"; + private static final String DATASET_NAME = "aDatasetName"; + private static final String FILE_NAME = "jasperPdfPrinterTest.pdf"; + private static final String FOLDER = "src/test/resources/"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/test_policy.xml"); + private static final TcSession session = new TcSession(); + + @BeforeClass + public static void login() throws NoTeamcenterConnectionException, InvalidConfigurationException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + } + + @AfterClass + public static void logout() { + session.close(); + } + + @Test + public void testAddFile() throws MalformedDataSetException, InvalidCredentialsException, ServiceException, NoTeamcenterConnectionException { + DatasetPreparator datapreparator = new DatasetPreparator(session, DATASET_NAME, DESCRIPTION); + addValidfile(datapreparator); + } + + @Test(expected = MalformedDataSetException.class) + public void testDatasetPreparatorNoName() throws MalformedDataSetException { + DatasetPreparator datasetPreparator = new DatasetPreparator(session, "", DESCRIPTION); + Assert.fail("'" + datasetPreparator.getDatasetName() + "' should not be accepted as a dataset name"); + } + + @Test(expected = MalformedDataSetException.class) + public void testDatasetPreparatorNullName() throws MalformedDataSetException { + DatasetPreparator datasetPreparator = new DatasetPreparator(session, null, DESCRIPTION); + datasetPreparator.isEmpty(); + Assert.fail("NULL should not be accepted as a dataset name"); + } + + @Test(expected = MalformedDataSetException.class) + public void testDatasetPreparatorNoFile() + throws MalformedDataSetException, InvalidCredentialsException, ServiceException, NoTeamcenterConnectionException { + DatasetPreparator datapreparator = new DatasetPreparator(session, DATASET_NAME, ""); + datapreparator.prepare(); // Fails here + } + + @Test + public void testPrepare() throws MalformedDataSetException, InvalidCredentialsException, ServiceException, NoTeamcenterConnectionException { + DatasetPreparator datapreparator = new DatasetPreparator(session, DATASET_NAME, DESCRIPTION); + addValidfile(datapreparator); + GetDatasetWriteTicketsInputData createdDataset = datapreparator.prepare(); + + // Cleanup + ModelObject asModelObject = createdDataset.dataset; + session.deleteObjects(asModelObject); + } + + @Test + public void testIsCreated() throws MalformedDataSetException, InvalidCredentialsException, ServiceException, NoTeamcenterConnectionException { + DatasetPreparator datapreparator = new DatasetPreparator(session, DATASET_NAME, DESCRIPTION); + Assert.assertFalse(datapreparator.isCreated()); + addValidfile(datapreparator); + Assert.assertFalse(datapreparator.isCreated()); + GetDatasetWriteTicketsInputData createdDataset = datapreparator.prepare(); + Assert.assertTrue(datapreparator.isCreated()); + + // Cleanup + ModelObject asModelObject = createdDataset.dataset; + session.deleteObjects(asModelObject); + } + + // Helper function + private void addValidfile(DatasetPreparator datapreparator) throws MalformedDataSetException { + File theFile = new File(FOLDER + FILE_NAME); + if (!theFile.exists() || theFile.isDirectory()) { + throw new NoSuchElementException("Missing test file " + FOLDER + FILE_NAME); // This is the failure of the test-class, not of the class being tested + } + datapreparator.addFile(theFile, FileType.FICHE_ARTICLE); + } +} diff --git a/teamcenter/src/test/java/com/capgemini/framework/teamcenter/files/FileManagementTest.java b/teamcenter/src/test/java/com/capgemini/framework/teamcenter/files/FileManagementTest.java new file mode 100644 index 0000000..46be90b --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/framework/teamcenter/files/FileManagementTest.java @@ -0,0 +1,104 @@ +package com.capgemini.framework.teamcenter.files; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.ConnectionMisconguredException; +import com.capgemini.framework.teamcenter.exceptions.MalformedDataSetException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.files.FileManagement.FileType; +import com.teamcenter.schemas.soa._2006_03.exceptions.InvalidCredentialsException; +import com.teamcenter.schemas.soa._2006_03.exceptions.ServiceException; +import com.teamcenter.services.loose.core._2006_03.FileManagement.GetDatasetWriteTicketsInputData; +import com.teamcenter.soa.client.model.ModelObject; +import junit.framework.Assert; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +public class FileManagementTest { + + private static final String DESCRIPTION = "A nice description"; + private static final String DATASET_NAME = "aDatasetName"; + private static final String TEXT_FILE_NAME = "TextFile.txt"; + private static final String PDF_FILE_NAME = "jasperPdfPrinterTest.pdf"; + private static final String FOLDER = "src/test/resources/"; + + @Test + public void testFileManagementText() + throws MalformedDataSetException, IOException, ConnectionMisconguredException, NoTeamcenterConnectionException { + try (TcSession session = new TcSession()) { + session.login(); + + // Prepare dataset + DatasetPreparator dataset = new DatasetPreparator(session, DATASET_NAME, DESCRIPTION); + File targetFile = new File(FOLDER + TEXT_FILE_NAME); + dataset.addFile(targetFile, FileType.TEXT_FILE); + + // Upload file (dataset will be uploaded too) + FileManagement fileManager = new FileManagement(session); + fileManager.addDataSet(dataset); + fileManager.upload(); + + List createdDatasets = fileManager.getDataSets(); + // Verify creation + Assert.assertFalse(createdDatasets.isEmpty()); + + // Delete all objects created + ModelObject[] datasets = new ModelObject[createdDatasets.size()]; + int num = 0; + for (GetDatasetWriteTicketsInputData data : createdDatasets) { + datasets[num++] = data.dataset; + } + session.deleteObjects(datasets); + } + } + + @Test + public void testFileManagementPDF() + throws MalformedDataSetException, IOException, ConnectionMisconguredException, NoTeamcenterConnectionException { + try (TcSession session = new TcSession()) { + session.login(); + + // Prepare dataset + DatasetPreparator dataset = new DatasetPreparator(session, DATASET_NAME, DESCRIPTION); + File targetFile = new File(FOLDER + PDF_FILE_NAME); + dataset.addFile(targetFile, FileType.PDF); + + // Upload file (dataset will be uploaded too) + FileManagement fileManager = new FileManagement(session); + fileManager.addDataSet(dataset); + try { + // Perform the file upload + fileManager.upload(); + + // Verify creation + List createdDatasets = fileManager.getDataSets(); + Assert.assertFalse(createdDatasets.isEmpty()); + } finally { + if (dataset.isCreated()) { + // Delete The dataset + session.deleteObjects(dataset.getCreatedDataset().dataset); + } + } + } + } + + @Test(expected = MalformedDataSetException.class) + public void testFileManagementNoDataset() + throws InvalidCredentialsException, ServiceException, MalformedDataSetException, ConnectionMisconguredException { + try (TcSession session = new TcSession()) { + FileManagement fileManager = new FileManagement(session); + fileManager.upload(); // Should fail because no datasets were provided + } + } + + @Test(expected = MalformedDataSetException.class) + public void testFileManagementFailedDataset() + throws InvalidCredentialsException, ServiceException, MalformedDataSetException, ConnectionMisconguredException { + try (TcSession session = new TcSession()) { + FileManagement fileManager = new FileManagement(session); + fileManager.addDataSetWithSingleFile(DATASET_NAME, DESCRIPTION, null, FileType.FICHE_ARTICLE); + } + } +} diff --git a/teamcenter/src/test/java/com/capgemini/framework/teamcenter/queries/saved/modelobject/ItemQueryTest.java b/teamcenter/src/test/java/com/capgemini/framework/teamcenter/queries/saved/modelobject/ItemQueryTest.java new file mode 100644 index 0000000..f8f81f0 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/framework/teamcenter/queries/saved/modelobject/ItemQueryTest.java @@ -0,0 +1,69 @@ +package com.capgemini.framework.teamcenter.queries.saved.modelobject; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.teamcenter.soa.client.model.strong.Item; +import lombok.extern.slf4j.Slf4j; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.List; + +@Slf4j +public class ItemQueryTest { + private static final TcSession session = new TcSession(); + private static final String expectedItemID = "22U"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/test_policy.xml"); + + + @BeforeClass + public static void login() throws NoTeamcenterConnectionException, InvalidConfigurationException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + } + + @AfterClass + public static void logout() { + session.close(); + } + + @Test + public void testSearchID() { + log.info("testSearchID--------------------------"); + + // Create a query + ItemQuery query = new ItemQuery(session); + query.searchID(expectedItemID); + + // Execute the query + List result = query.findAll(); + Assert.assertNotNull(result); + Assert.assertFalse(result.isEmpty()); + + // Parse the results + log.info("Matching Items: "); + for (Item item : result) { + Assert.assertNotNull(item); + log.info("ID = {}\t\tName = {}", item.get_item_id(), item.get_object_name()); + Assert.assertEquals(expectedItemID, item.get_item_id()); + } + } + + @Test + public void testSearchFakeID() { + log.info("testSearchID--------------------------"); + + // Create a query + ItemQuery query = new ItemQuery(session); + query.searchID("babar"); + + // Execute the query + List result = query.findAll(); + Assert.assertNotNull(result); + Assert.assertTrue(result.isEmpty()); + } +} diff --git a/teamcenter/src/test/java/com/capgemini/framework/teamcenter/queries/saved/modelobject/ItemRevisionQueryTest.java b/teamcenter/src/test/java/com/capgemini/framework/teamcenter/queries/saved/modelobject/ItemRevisionQueryTest.java new file mode 100644 index 0000000..6c53c58 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/framework/teamcenter/queries/saved/modelobject/ItemRevisionQueryTest.java @@ -0,0 +1,140 @@ +package com.capgemini.framework.teamcenter.queries.saved.modelobject; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.List; + +@Slf4j +public class ItemRevisionQueryTest { + private static final TcSession session = new TcSession(); + private static final String expectedItemID = "22U"; + private static final String expectedObjectName = "GE90 M10 MOTEUR ASSEMBLE"; + private static final String expectedItemRevision = "C"; // <-- revision B also exists + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/test_policy.xml"); + + @BeforeClass + public static void login() throws NoTeamcenterConnectionException, InvalidConfigurationException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + } + + @AfterClass + public static void logout() { + session.close(); + } + + @Test + public void testSearchID() { + log.info("testSearchID--------------------------"); + // Create a query + ItemRevisionQuery query = new ItemRevisionQuery(session); + query.searchID(expectedItemID); + + // Execute the query + List result = query.findAll(); + Assert.assertNotNull(result); + Assert.assertFalse(result.isEmpty()); + + // Parse the results + log.info("Matching ItemRevisions: "); + for (ItemRevision itemRev : result) { + log.info("ID = {}\tRev={}\tName = {}", itemRev.get_item_id(), itemRev.get_item_revision_id(), itemRev.get_object_name()); + Assert.assertEquals(expectedItemID, itemRev.get_item_id()); + } + } + + @Test + public void testSearchFakeID() { + log.info("testSearchFakeID----------------------"); + // Create a query + ItemRevisionQuery query = new ItemRevisionQuery(session); + query.searchID("some ID that does not exist"); + + // Execute the query + List result = query.findAll(); + Assert.assertNotNull(result); + Assert.assertTrue(result.isEmpty()); + } + + @Test + public void testSearchIDAndRevision() { + log.info("testSearchIDAndRevision---------------"); + // Create a query + ItemRevisionQuery query = new ItemRevisionQuery(session); + query.searchIDAndRevision(expectedItemID, expectedItemRevision); + + // Execute the query + List result = query.findAll(); + Assert.assertNotNull(result); + Assert.assertTrue(result.size() == 1); + + // Parse the results + ItemRevision theItemRev = result.get(0); + Assert.assertNotNull(theItemRev); + Assert.assertEquals(expectedItemID, theItemRev.get_item_id()); + Assert.assertEquals(expectedItemRevision, theItemRev.get_item_revision_id()); + log.info("Matching ItemRevision: "); + log.info("ID = {}\tRev={}\tName = {}", theItemRev.get_item_id(), theItemRev.get_item_revision_id(), theItemRev.get_object_name()); + } + + /** + * JUnit test. + */ + @Test + public void testSearchIdAndFakeRevision() { + log.info("testSearchIdAndFakeRevision-----------"); + // Create a query + ItemRevisionQuery query = new ItemRevisionQuery(session); + query.searchIDAndRevision(expectedItemID, "pouet pouet truc"); + + // Execute the query + List result = query.searchID(expectedItemID).findAll(); + Assert.assertNotNull(result); + Assert.assertTrue(result.isEmpty()); + } + + @Test + public void testSearchName() { + log.info("testSearchName------------------------"); + // Create a query + ItemRevisionQuery query = new ItemRevisionQuery(session); + query.searchName(expectedObjectName); + + // Execute the query + List result = query.findAll(); + Assert.assertNotNull(result); + Assert.assertTrue(!result.isEmpty()); + + // Parse the results + log.info("Matching ItemRevisions: "); + for (ItemRevision itemRev : result) { + log.info("ID = {}\tRev={}", itemRev.get_item_id(), itemRev.get_item_revision_id()); + Assert.assertEquals(expectedObjectName, itemRev.get_object_name()); + } + } + + /** + * JUnit test. + */ + @Test + public void testSearchFakeName() { + log.info("testSearchFakeName--------------------"); + // Create a query + ItemRevisionQuery query = new ItemRevisionQuery(session); + query.searchName("pouet pouet truc"); + + // Execute the query + List result = query.searchID(expectedItemID).findAll(); + Assert.assertNotNull(result); + Assert.assertTrue(result.isEmpty()); + } +} diff --git a/teamcenter/src/test/java/com/capgemini/framework/teamcenter/relations/RelationshipManagerTest.java b/teamcenter/src/test/java/com/capgemini/framework/teamcenter/relations/RelationshipManagerTest.java new file mode 100644 index 0000000..a2775fa --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/framework/teamcenter/relations/RelationshipManagerTest.java @@ -0,0 +1,63 @@ +package com.capgemini.framework.teamcenter.relations; + +import com.capgemini.framework.teamcenter.TeamcenterObjectTypes; +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.FailedRelationshipActionException; +import com.capgemini.framework.teamcenter.exceptions.MalformedDataSetException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.files.DatasetPreparator; +import com.capgemini.framework.teamcenter.files.FileManagement.FileType; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemQuery; +import com.teamcenter.schemas.soa._2006_03.exceptions.InvalidCredentialsException; +import com.teamcenter.services.loose.core._2006_03.FileManagement.GetDatasetWriteTicketsInputData; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Item; +import junit.framework.Assert; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.util.NoSuchElementException; + +public class RelationshipManagerTest { + + private static final String DATASET_NAME = "TestDataset"; + private static final String PART_ID = "002711"; + private static final String FILE_NAME = "jasperPdfPrinterTest.pdf"; + private static final String FOLDER = "src/test/resources/"; + + private final TcSession session = new TcSession(); + private ModelObject dataset; + + @Before + public void makeDataset() throws MalformedDataSetException, InvalidCredentialsException, NoTeamcenterConnectionException { + session.login(); + DatasetPreparator datapreparator = new DatasetPreparator(session, DATASET_NAME, "For Kurt Unit testing"); + File theFile = new File(FOLDER + FILE_NAME); + if (!theFile.exists() || theFile.isDirectory()) { + throw new NoSuchElementException("Missing test file " + FOLDER + FILE_NAME); // This is the failure of the test-class, not of the class being tested + } + datapreparator.addFile(theFile, FileType.FICHE_ARTICLE); + GetDatasetWriteTicketsInputData datasetTicket = datapreparator.prepare(); + dataset = datasetTicket.dataset; + } + + @Test + public void createDeleteTest() throws InvalidCredentialsException, FailedRelationshipActionException, NoTeamcenterConnectionException { + Item part = new ItemQuery(session).searchID(PART_ID).findAll().get(0); + + // Create the link + Assert.assertNotNull(session.createRelation(part, dataset, TeamcenterObjectTypes.IMAN_REFERENCE)); + session.deleteRelations(part, dataset, TeamcenterObjectTypes.IMAN_REFERENCE); + } + + /** + * Destroy the dataset. + */ + @After + public void cleanup() { + session.deleteObjects(dataset); + session.close(); + } +} diff --git a/teamcenter/src/test/java/com/capgemini/framework/teamcenter/statuating/StatusSetterTest.java b/teamcenter/src/test/java/com/capgemini/framework/teamcenter/statuating/StatusSetterTest.java new file mode 100644 index 0000000..a72d572 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/framework/teamcenter/statuating/StatusSetterTest.java @@ -0,0 +1,58 @@ +package com.capgemini.framework.teamcenter.statuating; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.MalformedDataSetException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.exceptions.UnableToCreateStatusException; +import com.capgemini.framework.teamcenter.files.DatasetPreparator; +import com.capgemini.framework.teamcenter.files.FileManagement.FileType; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.teamcenter.services.loose.core._2006_03.FileManagement.GetDatasetWriteTicketsInputData; +import com.teamcenter.soa.client.model.strong.ReleaseStatus; +import com.teamcenter.soa.client.model.strong.WorkspaceObject; +import junit.framework.Assert; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.File; + +public class StatusSetterTest { + private static final TcSession session = new TcSession(); + private static final String DESCRIPTION = "to perform a test, will be destroyed"; + private static final String DATASET_NAME = "aDatasetName"; + private static final String FILE_NAME = "jasperPdfPrinterTest.pdf"; + private static final String FOLDER = "src/test/resources/"; + private static final String TEST_STATUS_NAME = "J3B"; + private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/test_policy.xml"); + + @BeforeClass + public static void login() throws NoTeamcenterConnectionException, InvalidConfigurationException { + session.login(); + session.setObjectPropPolicy(XML_POLICY); + } + + @AfterClass + public static void logout() { + session.close(); + } + + + @Test + public void poseAndDeleteStatus() throws MalformedDataSetException, UnableToCreateStatusException { + // Create the target Dataset + DatasetPreparator datasetPreparator = new DatasetPreparator(session, DATASET_NAME, DESCRIPTION); + datasetPreparator.addFile(new File(FOLDER + FILE_NAME), FileType.PDF); + GetDatasetWriteTicketsInputData datasetTicket = datasetPreparator.prepare(); + + // Perform the test: put a status on the brand new dataset + StatusSetter setter = new StatusSetter(session); + ReleaseStatus createdStatus = setter.putStatus((WorkspaceObject) datasetTicket.dataset, TEST_STATUS_NAME); + Assert.assertNotNull(createdStatus); + Assert.assertEquals(TEST_STATUS_NAME, createdStatus.get_name()); + + // Status passed! now delete the dataset, with the and with it + session.deleteObjects(datasetTicket.dataset); + } +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/AbstractTeamcenterTest.java b/teamcenter/src/test/java/com/capgemini/reports/AbstractTeamcenterTest.java new file mode 100644 index 0000000..e4fe254 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/AbstractTeamcenterTest.java @@ -0,0 +1,233 @@ +package com.capgemini.reports; + +import com.capgemini.framework.teamcenter.authent.TcSession; +import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.teamcenter.Platform; +import com.teamcenter.schemas.soa._2006_03.exceptions.ServiceException; +import lombok.extern.slf4j.Slf4j; +import org.junit.AfterClass; + +/** + * Helper class to initialize a Teamcenter connection.
    + * Provides daughter classes a transparent way to access a Teamcenter connection.
    + * The session will have its Property Policies set to the default testing policies found in "/src/test/resources/test_policy.xml". + *

    + * Access the connection through the static {@link AbstractTeamcenterTest#getSession()} method. + */ +@Slf4j +public abstract class AbstractTeamcenterTest { + + /** + * Minimum delay between each login (by milliseconds). + **/ + private static final long LOGIN_DELAY = 30000; + + /** + * Time by milliseconds of the last login. + **/ + private static long lastLogInTimeMs = 0L; + + /** + * Plateform A36 for Tests. + */ + public static final Platform A36_URL = Platform.PF36; + /** + * Plateform AIX for Tests. + */ + public static final Platform AIX_URL = Platform.AIX; + /** + * Plateform MIG. + */ + public static final Platform MIG_URL = Platform.MIG; + + /** + * The file location of the default policy. (test_policy). + **/ + public static final PolicyLocation DEFAULT_POLICY = PolicyLocation.make("test_policy", "/xml/policies/test_policy.xml"); + /** + * The file location of the policy with full access to all attributes. + **/ + public static final PolicyLocation POLICY_FULL = PolicyLocation.make("policy_full", "/xml/policies/policy_full.xml"); + /** + * The file location of the policy with full access to all attributes. + **/ + public static final PolicyLocation POLICY_LIGHT = PolicyLocation.make("policy_light", "/xml/policies/policy_light.xml"); + /** + * The file location of the policy with minimal content, that still performs nomenclature resolution tests. + **/ + public static final PolicyLocation BOM_POLICY = PolicyLocation.make("bom_policy", "/xml/policies/bom_policy.xml"); + /** + * The file location of the full policy for a R01 report. + **/ + public static final PolicyLocation R01_POLICY_FULL = PolicyLocation.make("R01_policy_full", "/xml/policies/r01report/R01_policy_full.xml"); + /** + * The file location of the light policy for a R01 report. + **/ + public static final PolicyLocation R01_POLICY_LIGHT = PolicyLocation.make("R01_policy_light", "/xml/policies/r01report/R01_policy_light.xml"); + /** + * The file location of the full policy for a R03 report. + **/ + public static final PolicyLocation R03_POLICY_FULL = PolicyLocation.make("R03_policy_full", "/xml/policies/r03report/R03_policy_full.xml"); + /** + * The file location of the light policy for a R03 report. + **/ + public static final PolicyLocation R03_POLICY_LIGHT = PolicyLocation.make("R03_policy_light", "/xml/policies/r03report/R03_policy_light.xml"); + /** + * The file location of the full policy for a R03 report. + **/ + public static final PolicyLocation R07_POLICY_FULL = PolicyLocation.make("R07_policy_full", "/xml/policies/r07report/R07_policy_full.xml"); + /** + * The file location of the light policy for a R03 report. + **/ + public static final PolicyLocation R07_POLICY_LIGHT = PolicyLocation.make("R07_policy_light", "/xml/policies/r07report/R07_policy_light.xml"); + /** + * The file location of the full policy for a R10 report. + **/ + public static final PolicyLocation R10_POLICY_FULL = PolicyLocation.make("R10_policy_full", "/xml/policies/r10report/R10_policy_full.xml"); + /** + * The file location of the light policy for a R10 report. + **/ + public static final PolicyLocation R10_POLICY_LIGHT = PolicyLocation.make("R10_policy_light", "/xml/policies/r10report/R10_policy_light.xml"); + /** + * The file location of the full policy for a R11 report. + **/ + public static final PolicyLocation R11_POLICY_FULL = PolicyLocation.make("R11_policy_full", "/xml/policies/r11report/R11_policy_full.xml"); + /** + * The file location of the light policy for a R11 report. + **/ + public static final PolicyLocation R11_POLICY_LIGHT = PolicyLocation.make("R11_policy_light", "/xml/policies/r11report/R11_policy_light.xml"); + /** + * The file location of the full policy for a R13 report. + **/ + public static final PolicyLocation R13_POLICY_FULL = PolicyLocation.make("R13_policy_full", "/xml/policies/r13report/R13_policy_full.xml"); + /** + * The file location of the light policy for a R13 report. + **/ + public static final PolicyLocation R13_POLICY_LIGHT = PolicyLocation.make("R13_policy_light", "/xml/policies/r13report/R13_policy_light.xml"); + /** + * The file location of the full policy for a R15 report. + **/ + public static final PolicyLocation R15_POLICY_FULL = PolicyLocation.make("R15_policy_full", "/xml/policies/r15report/R15_policy_full.xml"); + /** + * The file location of the light policy for a R15 report. + **/ + public static final PolicyLocation R15_POLICY_LIGHT = PolicyLocation.make("R15_policy_light", "/xml/policies/r15report/R15_policy_light.xml"); + /** + * The file location of the full policy for a R16 report. + **/ + public static final PolicyLocation R16_POLICY_FULL = PolicyLocation.make("R16_policy_full", "/xml/policies/r16report/R16_policy_full.xml"); + /** + * The file location of the light policy for a R16 report. + **/ + public static final PolicyLocation R16_POLICY_LIGHT = PolicyLocation.make("R16_policy_light", "/xml/policies/r16report/R16_policy_light.xml"); + /** + * The file location of the full policy for a R17 report. + **/ + public static final PolicyLocation R17_POLICY_FULL = PolicyLocation.make("R17_policy_full", "/xml/policies/r17report/R17_policy_full.xml"); + /** + * The file location of the light policy for a R17 report. + **/ + public static final PolicyLocation R17_POLICY_LIGHT = PolicyLocation.make("R17_policy_light", "/xml/policies/r17report/R17_policy_light.xml"); + /** + * The file location of the full policy for a R19 report. + **/ + public static final PolicyLocation R19_POLICY_FULL = PolicyLocation.make("R19_policy_full", "/xml/policies/r19report/R19_policy_full.xml"); + /** + * The file location of the light policy for a R19 report. + **/ + public static final PolicyLocation R19_POLICY_LIGHT = PolicyLocation.make("R19_policy_light", "/xml/policies/r19report/R19_policy_light.xml"); + /** + * The file location of the full policy for a R20 report. + **/ + public static final PolicyLocation R20_POLICY_FULL = PolicyLocation.make("R20_policy_full", "/xml/policies/r20report/R20_policy_full.xml"); + /** + * The file location of the light policy for a R20 report. + **/ + public static final PolicyLocation R20_POLICY_LIGHT = PolicyLocation.make("R20_policy_light", "/xml/policies/r20report/R20_policy_light.xml"); + /** + * The file location of the full policy for a R21 report. + **/ + public static final PolicyLocation R21_POLICY_FULL = PolicyLocation.make("R21_policy_full", "/xml/policies/r21report/R21_policy_full.xml"); + /** + * The file location of the light policy for a R21 report. + **/ + public static final PolicyLocation R21_POLICY_LIGHT = PolicyLocation.make("R21_policy_light", "/xml/policies/r21report/R21_policy_light.xml"); + /** + * The file location of the full policy for a R22 report. + **/ + public static final PolicyLocation R22_POLICY_FULL = PolicyLocation.make("R22_policy_full", "/xml/policies/r22report/R22_policy_full.xml"); + /** + * The file location of the light policy for a R22 report. + **/ + public static final PolicyLocation R22_POLICY_LIGHT = PolicyLocation.make("R22_policy_light", "/xml/policies/r22report/R22_policy_light.xml"); + + /** + * Flag to only build the objects once. + **/ + private static boolean isPolicySetup; + + private static boolean isChangeSession; + + private static TcSession session; + + /** + * Opens a connection. May fail if the default policy (policy_full.xml) does not exist on the TC server + * + * @return the session + * @throws NoTeamcenterConnectionException Should not happen + */ + public static TcSession getSession() throws NoTeamcenterConnectionException { + if (session == null) { + // Check the duration between current login and the previous one + long theCurrentTimestamp = System.currentTimeMillis(); + if (theCurrentTimestamp < lastLogInTimeMs + LOGIN_DELAY) { + long theWaitDuration = lastLogInTimeMs + LOGIN_DELAY - theCurrentTimestamp; + log.info("Waiting for next login retry in order to wait during the TCServer initialization: " + theWaitDuration + "ms"); + try { + Thread.sleep(theWaitDuration); + } catch (InterruptedException e) { + log.error("Sleep interrupted", e); + } + } + + // Save the current login time + lastLogInTimeMs = System.currentTimeMillis(); + + // Create the session (login is performed) + session = new TcSession(); + session.login(); + try { + session.setObjectPropPolicy(POLICY_FULL); + } catch (InvalidConfigurationException e) { + throw new RuntimeException("Unable to load properties", e); + } + } + return session; + } + + /** + * Cleanly close the connection. + * + * @throws ServiceException Should not happen + */ + @AfterClass + public static void logoutTeamcenter() throws ServiceException { + // Try to log out the current session + if (session == null) { + log.error("No session handle found to close the session. The session may not have been closed."); + } else { + session.close(); + } + } + + /** + * Declares the location of the property policy to be used throughout the daughter class's unit Tests.
    + * A default policy file location is provided by this class in the static constant DEFAULT_POLICY. + * + * @return the relative location of the property policy file. + */ + public abstract PolicyLocation getPropertyPolicyIdentifier(); + +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/ScenarioForTests.java b/teamcenter/src/test/java/com/capgemini/reports/ScenarioForTests.java new file mode 100644 index 0000000..0900356 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/ScenarioForTests.java @@ -0,0 +1,101 @@ +package com.capgemini.reports; + +/** + * Enumeration of different scenarios.
    + * Used for tests. + **/ +public enum ScenarioForTests { + /** + * Normal test. + */ + TEST_N24( + "N24", + "24N", + "35R0", + "60", + "/serialization/n24-24n/serialN24etudeMono.ser", + "/serialization/n24-24n/serialN24etudeMulti.ser", + "/serialization/n24-24n/serial24NassembMono.ser", + "/serialization/n24-24n/serial24NassembMulti.ser"), + /** + * Large test. + */ + TEST_U22( + "U22", + "22U", + "97R0", + "550", + "/serialization/u22-22u/serialU22etudeMono.ser", + "/serialization/u22-22u/serialU22etudeMulti.ser", + "/serialization/u22-22u/serial22UassembMono.ser", + "/serialization/u22-22u/serial22UassembMulti.ser"), + /** + * Tiny test. + */ + TEST_E24( + "E24", + "24E", + "30E0", + "20", + "/serialization/e24-24e/serialE24etudeMono.ser", + "/serialization/e24-24e/serialE24etudeMulti.ser", + "/serialization/e24-24e/serial24EassembMono.ser", + "/serialization/e24-24e/serial24EassembMulti.ser"), + /** + * Small test. + */ + TEST_U24( + "U24", + "24U", + "35R0", + "60", + "/serialization/u24-24u/serialU24etudeMono.ser", + "/serialization/u24-24u/serialU24etudeMulti.ser", + "/serialization/u24-24u/serial24UassembMono.ser", + "/serialization/u24-24u/serial24UassembMulti.ser"); + + /** + * The id of the Generic. + */ + public final String generic; + /** + * The id of the Generic Assemb. + */ + public final String genericAssemb; + /** + * The id of the Product. + */ + public final String product; + /** + * The unit. + */ + public final String unit; + /** + * The file of Technical view for deserialization in Mono. + */ + public final String fileTechnicalMono; + /** + * The file of Technical view for deserialization in Multi. + */ + public final String fileTechnicalMulti; + /** + * The file of Assembly view for deserialization in Mono. + */ + public final String fileAssembMono; + /** + * The file of Assembly view for deserialization in Multi. + */ + public final String fileAssembMulti; + + ScenarioForTests(final String generic, final String genericAssemb, final String product, final String unit, + final String fileTechnicalMono, final String fileTechnicalMulti, final String fileAssembMono, final String fileAssembMulti) { + this.product = product; + this.generic = generic; + this.genericAssemb = genericAssemb; + this.unit = unit; + this.fileTechnicalMono = fileTechnicalMono; + this.fileTechnicalMulti = fileTechnicalMulti; + this.fileAssembMono = fileAssembMono; + this.fileAssembMulti = fileAssembMulti; + } +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/TeamcenterTypeObjectsTest.java b/teamcenter/src/test/java/com/capgemini/reports/TeamcenterTypeObjectsTest.java new file mode 100644 index 0000000..4b71229 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/TeamcenterTypeObjectsTest.java @@ -0,0 +1,78 @@ +package com.capgemini.reports; + +import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.junit.Test; + + +@Slf4j +public class TeamcenterTypeObjectsTest { + + + @Test + public void testIsPart() { + log.info("Testing pattern: '{}'", SnecmaObjectTypes.PART_REVISION_PATTERN.pattern()); + + // Success + Assert.assertTrue(SnecmaObjectTypes.isPartRevision("Alternate Revision")); + Assert.assertTrue(SnecmaObjectTypes.isPartRevision("DET Revision")); + Assert.assertTrue(SnecmaObjectTypes.isPartRevision("Part Aero Revision")); + Assert.assertTrue(SnecmaObjectTypes.isPartRevision("Part Assemb Revision")); + Assert.assertTrue(SnecmaObjectTypes.isPartRevision("Part Mat Revision")); + Assert.assertTrue(SnecmaObjectTypes.isPartRevision("Part No Aero Revision")); + Assert.assertTrue(SnecmaObjectTypes.isPartRevision("Standard Revision")); + + // Fails + Assert.assertFalse(SnecmaObjectTypes.isPartRevision(SnecmaObjectTypes.GENERIC_REVISION)); + Assert.assertFalse(SnecmaObjectTypes.isPartRevision("Altrnate Revision")); // misspelled on purpose + Assert.assertFalse(SnecmaObjectTypes.isPartRevision("Alternate")); // Item + Assert.assertFalse(SnecmaObjectTypes.isPartRevision("Alternate Revision Master")); // Master + } + + + @Test + public void testIsAltOrDet() { + log.info("Testing pattern: '{}'", SnecmaObjectTypes.ALT_OR_DET_PATTERN.pattern()); + + // Success + Assert.assertTrue(SnecmaObjectTypes.isAltOrDet("Alternate Revision")); + Assert.assertTrue(SnecmaObjectTypes.isAltOrDet("DET Revision")); + + // Fails + Assert.assertFalse(SnecmaObjectTypes.isAltOrDet("Part Aero Revision")); + Assert.assertFalse(SnecmaObjectTypes.isAltOrDet("Part Assemb Revision")); + Assert.assertFalse(SnecmaObjectTypes.isAltOrDet("Part Mat Revision")); + Assert.assertFalse(SnecmaObjectTypes.isAltOrDet("Part No Aero Revision")); + Assert.assertFalse(SnecmaObjectTypes.isAltOrDet("Standard Revision")); + Assert.assertFalse(SnecmaObjectTypes.isAltOrDet(SnecmaObjectTypes.GENERIC_REVISION)); + Assert.assertFalse(SnecmaObjectTypes.isAltOrDet("Altrnate Revision")); // misspelled on purpose + Assert.assertFalse(SnecmaObjectTypes.isAltOrDet("Alternate")); // Item + Assert.assertFalse(SnecmaObjectTypes.isAltOrDet("Alternate Revision Master")); // Master + } + + + @Test + public void testIsA() { + log.info("Testing pattern: '{}'", SnecmaObjectTypes.PART_REVISION_PATTERN.pattern()); + + // Success + Assert.assertTrue(SnecmaObjectTypes.isA("Alternate Revision", SnecmaObjectTypes.ALTERNATE_REVISION)); + Assert.assertTrue(SnecmaObjectTypes.isA("Alternate Revision", SnecmaObjectTypes.ALTERNATE_REVISION, + SnecmaObjectTypes.PART_AERO_REVISION, SnecmaObjectTypes.PART_NO_AERO_REVISION, SnecmaObjectTypes.PART_ASSEMB_REVISION, + SnecmaObjectTypes.PART_MAT_REVISION, SnecmaObjectTypes.DET_REVISION, SnecmaObjectTypes.STANDARD_REVISION)); + Assert.assertTrue(SnecmaObjectTypes.isA("Part Aero Revision", SnecmaObjectTypes.ALTERNATE_REVISION, + SnecmaObjectTypes.PART_AERO_REVISION, SnecmaObjectTypes.PART_NO_AERO_REVISION, SnecmaObjectTypes.PART_ASSEMB_REVISION, + SnecmaObjectTypes.PART_MAT_REVISION, SnecmaObjectTypes.DET_REVISION, SnecmaObjectTypes.STANDARD_REVISION)); + + // Fails + Assert.assertFalse(SnecmaObjectTypes.isA("Altrnate Revision", SnecmaObjectTypes.ALTERNATE_REVISION)); // misspelled on purpose + Assert.assertFalse(SnecmaObjectTypes.isA("Alternate Revision Master", SnecmaObjectTypes.ALTERNATE_REVISION)); // master + Assert.assertFalse(SnecmaObjectTypes.isA("Alternate Master", SnecmaObjectTypes.ALTERNATE_REVISION)); // master + Assert.assertFalse(SnecmaObjectTypes.isA("Alternate", SnecmaObjectTypes.ALTERNATE_REVISION)); // item + Assert.assertFalse(SnecmaObjectTypes.isA("Alternate Revision", SnecmaObjectTypes.PART_AERO_REVISION, + SnecmaObjectTypes.PART_NO_AERO_REVISION, SnecmaObjectTypes.PART_ASSEMB_REVISION, SnecmaObjectTypes.PART_MAT_REVISION, + SnecmaObjectTypes.DET_REVISION, SnecmaObjectTypes.STANDARD_REVISION)); // alt is not there + } + +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/changeobjects/AbstractChangeObjectTest.java b/teamcenter/src/test/java/com/capgemini/reports/changeobjects/AbstractChangeObjectTest.java new file mode 100644 index 0000000..2649a2f --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/changeobjects/AbstractChangeObjectTest.java @@ -0,0 +1,103 @@ +package com.capgemini.reports.changeobjects; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.object.pom.status.TcReleaseStatus; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.capgemini.reports.changeobjects.change.TcChangeNoticeRevision; +import com.capgemini.reports.changeobjects.change.TcChangeRequestRevision; +import com.capgemini.reports.snecmaobjects.generic.AbstractGeneric; +import com.capgemini.reports.teamcenter.queries.saved.ChangeRequestQuery; +import com.capgemini.reports.workflows.Task; +import com.teamcenter.schemas.soa._2006_03.exceptions.ServiceException; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import junit.framework.Assert; +import org.junit.Test; + +import java.util.List; + + +public class AbstractChangeObjectTest extends AbstractTeamcenterTest { + + @Test + public void testLigneProduit() throws ServiceException, NoTeamcenterConnectionException { + ItemRevisionQuery query = new ItemRevisionQuery(getSession()); + query.searchID("MOD200281"); + query.searchType("PV4_ETU_ANTICIPRevision"); // Making sure we don't obtain the (deprecated) EngChange with the same name + ItemRevision MOD200281 = query.findAll().get(0); + TcChangeNoticeRevision changeRequest = new TcChangeNoticeRevision(getSession(), MOD200281); + Assert.assertNotNull("pv4_ligne_produit was not loaded on the Change!", changeRequest.getLignesProduit()); + Assert.assertFalse("pv4_ligne_poduit was empty", changeRequest.getLignesProduit().isEmpty()); + Assert.assertEquals("pv4_ligne_poduit did not contain the expected element", "ATAR 08K50 ETAT", changeRequest.getLignesProduit().get(0)); + } + + @Test + public void testActorStatusOnTask() throws ServiceException, NoTeamcenterConnectionException { + ChangeRequestQuery query = new ChangeRequestQuery(getSession()); + query.searchID("MOD200411"); + ItemRevision crMOD20411_AA = query.findAll().get(0); + TcChangeRequestRevision changeRequest = new TcChangeRequestRevision(getSession(), crMOD20411_AA); + Assert.assertNotNull(changeRequest.getWkfList()); + Assert.assertFalse(changeRequest.getWkfList().isEmpty()); // Should be 1 workflow with 1 active task + Task wkf = changeRequest.getWkfList().get(0); + Assert.assertNotNull(wkf); + Assert.assertFalse(wkf.getActiveChildTasks().isEmpty()); + } + + @Test + public void testChangeWithOrWithoutRupture() throws ServiceException, NoTeamcenterConnectionException { + ItemRevisionQuery query = new ItemRevisionQuery(getSession()).searchID("Change952"); + ItemRevision r201_051 = query.findAll().get(0); + TcChangeRequestRevision changeRequest = new TcChangeRequestRevision(getSession(), r201_051); + List without = changeRequest.getListOfGenericRevWithOrWithoutRupture(); + Assert.assertNotNull(without); + Assert.assertFalse(without.isEmpty()); + Assert.assertNotNull(without.get(0)); + } + + @Test + public void testReleaseStatusWithMaturity() throws ServiceException, NoTeamcenterConnectionException { + ChangeRequestQuery query = new ChangeRequestQuery(getSession()); + query.searchID("MOD200497"); + ItemRevision crMOD200497 = query.findAll().get(0); + TcChangeRequestRevision changeRequest = new TcChangeRequestRevision(getSession(), crMOD200497); + Assert.assertFalse(changeRequest.getReleaseStatusContainingEffectivity().isEmpty()); + for (TcReleaseStatus status : changeRequest.getReleaseStatusContainingEffectivity()) { + Assert.assertNotNull(status); + Assert.assertTrue(status.isEffectivity()); + Assert.assertFalse(status.isChangeMaturity()); + } + Assert.assertFalse(changeRequest.getReleaseStatusContainingMaturity().isEmpty()); + for (TcReleaseStatus status : changeRequest.getReleaseStatusContainingMaturity()) { + Assert.assertNotNull(status); + Assert.assertTrue(status.isChangeMaturity()); + Assert.assertFalse(status.isEffectivity()); + } + } + + @Test + public void testReleaseStatusWithInterfaceTODO() throws ServiceException, NoTeamcenterConnectionException { + ChangeRequestQuery query = new ChangeRequestQuery(getSession()); + query.searchID("MOD200330"); + ItemRevision crMOD200497 = query.findAll().get(0); + TcChangeRequestRevision changeRequest = new TcChangeRequestRevision(getSession(), crMOD200497); + Assert.assertFalse(changeRequest.getReleaseStatusContainingEffectivity().isEmpty()); + for (TcReleaseStatus status : changeRequest.getReleaseStatusContainingEffectivity()) { + Assert.assertNotNull(status); + Assert.assertTrue(status.isEffectivity()); + Assert.assertFalse(status.isChangeMaturity()); + } + Assert.assertFalse(changeRequest.getReleaseStatusContainingMaturity().isEmpty()); + for (TcReleaseStatus status : changeRequest.getReleaseStatusContainingMaturity()) { + Assert.assertNotNull(status); + Assert.assertTrue(status.isChangeMaturity()); + Assert.assertFalse(status.isEffectivity()); + } + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return R13_POLICY_FULL; + } +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/changeobjects/UnitRevisionTest.java b/teamcenter/src/test/java/com/capgemini/reports/changeobjects/UnitRevisionTest.java new file mode 100644 index 0000000..d95ee81 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/changeobjects/UnitRevisionTest.java @@ -0,0 +1,215 @@ +package com.capgemini.reports.changeobjects; + +import com.capgemini.framework.common.TeamcenterDateFormatter; +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.capgemini.reports.changeobjects.change.TcChangeRequestRevision; +import com.capgemini.reports.snecmaobjects.product.ProductRevision; +import com.capgemini.reports.teamcenter.queries.saved.UnitQuery; +import com.capgemini.reports.workflows.Task; +import com.teamcenter.schemas.soa._2006_03.exceptions.ServiceException; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + + +@Slf4j +public class UnitRevisionTest extends AbstractTeamcenterTest { + + private static final String UNIT_REV = "C"; + private static final String UNIT_ID = "MOD163427"; + private static final String UNIT_ID_WITH_GEL = "MOD120174";// "MOD143898"; // This one has a Workflow attached which is a 'Gel de Unit' + private static final String UNIT_ID_WITH_SO_CURRENT = "00041717"; // This one is currently going through a 'Unit-Validation UNIT par Services officiels' Workflow + private static final String UNIT_ID_WITH_SO_FINISHED = "00041694"; // This one has fully gone through a 'Unit-Validation UNIT par Services officiels' Workflow + + /** + * JUnit test. + * + * @throws NoTeamcenterConnectionException should not happen + */ + @Test + public void unitRevisionTest() throws NoTeamcenterConnectionException { + // Obtain the itemRev + List results = new ItemRevisionQuery(getSession()).searchIDAndRevision(UNIT_ID, UNIT_REV).findAll(); + Assert.assertFalse(results.isEmpty()); + ItemRevision tcUnit = results.get(0); + // Build It + UnitRevision unit = UnitRevision.build(getSession(), tcUnit); + + // Test it + Assert.assertNotNull(unit.getItemId()); + log.info("getItemId= " + unit.getItemId()); + Assert.assertEquals(UNIT_ID, unit.getItemId()); + + Assert.assertNotNull(unit.getName()); + log.info("getName= " + unit.getName()); + Assert.assertFalse(unit.getName().isEmpty()); + + Assert.assertNotNull(unit.getRevision()); + log.info("getRevision= " + unit.getRevision()); + Assert.assertEquals(UNIT_REV, unit.getRevision()); + + Assert.assertNotNull(unit.getType()); + log.info("getType= " + unit.getType()); + Assert.assertFalse(unit.getType().isEmpty()); + + Assert.assertNotNull(unit.getUid()); + log.info("getUid= " + unit.getUid()); + Assert.assertFalse(unit.getUid().isEmpty()); + + Assert.assertNotNull(unit.getUnitRange()); + log.info("unitRange= " + unit.getUnitRange()); + Assert.assertFalse(unit.getUnitRange().isEmpty()); + + log.info("isExceptionnel= " + unit.isExceptionnel()); + Assert.assertTrue(unit.isExceptionnel()); + + // Change request + Assert.assertNotNull(unit.getChangeRequestsList()); + log.info("getChangeRequestsList= " + unit.getChangeRequestsList()); + Assert.assertFalse(unit.getChangeRequestsList().isEmpty()); + for (TcChangeRequestRevision request : unit.getChangeRequestsList()) { + log.info(" + TcChangeRequestRevision ID = {}, Rev={}", request.getItemId(), request.getRevisionId()); + } + + // Generics + Assert.assertNotNull(unit.getGenerics()); + log.info("getGenerics= " + unit.getGenerics()); + Assert.assertFalse(unit.getGenerics().isEmpty()); + // Release status + Assert.assertNotNull(unit.getReleaseStatusContainingMaturity()); + log.info("getReleaseStatusContainingMaturity = " + unit.getReleaseStatusContainingMaturity()); + Assert.assertFalse(unit.getReleaseStatusContainingMaturity().isEmpty()); // there should be some maturity status + Assert.assertNotNull(unit.getTechnicalDocGel()); + log.info("getTechnicalDocGel = " + unit.getTechnicalDocGel()); + } + + /** + * JUnit test for max query size. + * + * @throws ServiceException should not happen + * @throws KurtException should not happen + */ + @Test + public void testUnitExceptionnel() throws ServiceException, KurtException { + getSession().setObjectPropPolicy(R20_POLICY_LIGHT); + // Fetch an EXCEPTIONAL Unit + List result = new UnitQuery(getSession()).searchID("00065685").findAll(); + ItemRevision unit = result.get(0); + // Build it + UnitRevision builtUnit = UnitRevision.build(getSession(), unit); + // Now test it + Assert.assertTrue(builtUnit.isExceptionnel()); + } + + /** + * JUnit test for max query size. + * + * @throws ServiceException should not happen + * @throws KurtException should not happen + */ + @Test + public void testUnit87() throws ServiceException, KurtException { + List result = new UnitQuery(getSession()).addEndItemID("35R0").findAll(); + Assert.assertTrue(result.size() > 50); + } + + /** + * JUnit test. + * + * @throws NoTeamcenterConnectionException should not happen + */ + @Test + public void loadWorkflowsValidationUnitParSOTest() throws NoTeamcenterConnectionException { + List results = new ItemRevisionQuery(getSession()).searchIDAndRevision(UNIT_ID_WITH_SO_FINISHED, "A").findAll(); + Assert.assertFalse(results.isEmpty()); + ItemRevision tcUnit = results.get(0); + UnitRevision unit = UnitRevision.build(getSession(), tcUnit); + + log.info("Building workflows..."); + Assert.assertFalse(unit.getWorkflowsValidationUnitParSO().isEmpty()); + + log.info("Browsing {} workflows", unit.getWorkflowsValidationUnitParSO().size()); + for (Task task : unit.getWorkflowsValidationUnitParSO()) { + Assert.assertNotNull(task); + String lastModDate = TeamcenterDateFormatter.formatCalendarToFrench(task.getLastModDate()); + String creationDate = TeamcenterDateFormatter.formatCalendarToFrench(task.getCreationDate()); + String owner = task.getOwningUser() == null ? null : task.getOwningUser().getName(); + String validator = task.getLastModUser() == null ? null : task.getLastModUser().getName(); + } + } + + /** + * JUnit test. + * + * @throws NoTeamcenterConnectionException should not happen + */ + @Test + public void loadWorkflowsValidationUnitParSOTestCURRENT() throws NoTeamcenterConnectionException { + List results = new ItemRevisionQuery(getSession()).searchIDAndRevision(UNIT_ID_WITH_SO_CURRENT, "A").findAll(); + Assert.assertFalse(results.isEmpty()); + ItemRevision tcUnit = results.get(0); + UnitRevision unit = UnitRevision.build(getSession(), tcUnit); + + log.info("Building workflows..."); + Assert.assertFalse(unit.getWorkflowsValidationUnitParSO().isEmpty()); + + log.info("Browsing {} workflows", unit.getWorkflowsValidationUnitParSO().size()); + for (Task task : unit.getWorkflowsValidationUnitParSO()) { + Assert.assertNotNull(task); + String lastModDate = TeamcenterDateFormatter.formatCalendarToFrench(task.getLastModDate()); + String creationDate = TeamcenterDateFormatter.formatCalendarToFrench(task.getCreationDate()); + String owner = task.getOwningUser() == null ? null : task.getOwningUser().getName(); + String validator = task.getLastModUser() == null ? null : task.getLastModUser().getName(); + } + } + + @Test + public void unitRevisionTestGel() throws NoTeamcenterConnectionException { + List results = new ItemRevisionQuery(getSession()).searchIDAndRevision(UNIT_ID_WITH_GEL, "D").findAll(); + Assert.assertFalse(results.isEmpty()); + ItemRevision tcUnit = results.get(0); + UnitRevision unit = UnitRevision.build(getSession(), tcUnit); + log.info("getItemId= " + unit.getItemId()); + Assert.assertNotNull(unit.getItemId()); + Assert.assertEquals(UNIT_ID_WITH_GEL, unit.getItemId()); + + Assert.assertNotNull(unit.getTechnicalDocGel()); + } + + @Test + public void testChooseRevisionOfUnitFromRange() throws NoTeamcenterConnectionException { + // Configuration + String productId = "29R0"; + String productRevisionId = "B"; + String range = "240"; + + // Query + List productRevisions = + new ItemRevisionQuery(getSession()).searchIDAndRevision(productId, productRevisionId).findAll(); + + // Build objects + ProductRevision product = new ProductRevision(getSession(), productRevisions.get(0)); + + // Method to test + UnitRevision result = UnitRevision.chooseRevisionOfUnitFromRange(range, product.getUnits(), StatusEnum.J3B); + + // Checks + Assert.assertNotNull(result); + Assert.assertEquals("Id is not equals to the expected value.", "MOD113586", result.getItemId()); + Assert.assertEquals("RevisionId is not equals to the expected value.", "E", result.getRevision()); + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return R20_POLICY_FULL; + } + +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/documentationobjects/DocDrawingTest.java b/teamcenter/src/test/java/com/capgemini/reports/documentationobjects/DocDrawingTest.java new file mode 100644 index 0000000..e661ae5 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/documentationobjects/DocDrawingTest.java @@ -0,0 +1,36 @@ +package com.capgemini.reports.documentationobjects; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +public class DocDrawingTest extends AbstractTeamcenterTest { + private final String id = "00037481"; + private final String revision = "--A"; + private final String name = "00037481"; + private final String designationEN = "FAN CASE"; + private final String indicePlan = "-A"; + + @Test + public void testBuild() throws NoTeamcenterConnectionException { + List results = new ItemRevisionQuery(getSession()).searchIDAndRevision(id, revision).findAll(); + DocDrawing test = new DocDrawing(getSession(), results.get(0)); + Assert.assertNotNull(test); + Assert.assertEquals(id, test.getDocId()); + Assert.assertEquals(revision, test.getRevision()); + Assert.assertEquals(name, test.getName()); + Assert.assertEquals(designationEN, test.getDesignationEn()); + Assert.assertEquals(indicePlan, test.getIndicePlan()); + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return R15_POLICY_FULL; + } +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/documentationobjects/DocGeometryTest.java b/teamcenter/src/test/java/com/capgemini/reports/documentationobjects/DocGeometryTest.java new file mode 100644 index 0000000..65aba07 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/documentationobjects/DocGeometryTest.java @@ -0,0 +1,37 @@ +package com.capgemini.reports.documentationobjects; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +public class DocGeometryTest extends AbstractTeamcenterTest { + + private final String id = "DOC-00237937"; + private final String revision = "--A"; + private final String name = "DOC-00237937"; + private final String designationEN = "WASHERS"; + private final String indiceCartouche = ""; + + @Test + public void testBuild() throws NoTeamcenterConnectionException { + List results = new ItemRevisionQuery(getSession()).searchIDAndRevision(id, revision).findAll(); + DocGeometry test = new DocGeometry(getSession(), results.get(0)); + Assert.assertNotNull(test); + Assert.assertEquals(id, test.getDocId()); + Assert.assertEquals(revision, test.getRevision()); + Assert.assertEquals(name, test.getName()); + Assert.assertEquals(designationEN, test.getDesignationEN()); + Assert.assertEquals(indiceCartouche, test.getIndiceCartouche()); + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return R15_POLICY_FULL; + } +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/documentationobjects/DocNormStandardTest.java b/teamcenter/src/test/java/com/capgemini/reports/documentationobjects/DocNormStandardTest.java new file mode 100644 index 0000000..6f74402 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/documentationobjects/DocNormStandardTest.java @@ -0,0 +1,37 @@ +package com.capgemini.reports.documentationobjects; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +public class DocNormStandardTest extends AbstractTeamcenterTest { + + private final String id = "000155"; + private final String revision = "A"; + private final String name = "RACCORD A BRIDE A SOUDER"; + private final String designationEN = "-"; + private final String idOrigine = "649-491-010/032-0"; + + @Test + public void testBuild() throws NoTeamcenterConnectionException { + List results = new ItemRevisionQuery(getSession()).searchIDAndRevision(id, revision).findAll(); + DocNormStandard test = new DocNormStandard(getSession(), results.get(0)); + Assert.assertNotNull(test); + Assert.assertEquals(id, test.getDocId()); + Assert.assertEquals(revision, test.getRevision()); + Assert.assertEquals(name, test.getName()); + Assert.assertEquals(designationEN, test.getDesignationEn()); + Assert.assertEquals(idOrigine, test.getIdOrigine()); + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return R15_POLICY_FULL; + } +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/documentationobjects/DocNormTest.java b/teamcenter/src/test/java/com/capgemini/reports/documentationobjects/DocNormTest.java new file mode 100644 index 0000000..e4d7df6 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/documentationobjects/DocNormTest.java @@ -0,0 +1,40 @@ +package com.capgemini.reports.documentationobjects; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +public class DocNormTest extends AbstractTeamcenterTest { + + private final String id = "000189"; + private final String revision = "A"; + private final String name = "PLAN SUPPORT"; + private final String designationEN = "-"; + private final String idOrigine = "PLAN-888-370-100-104"; + private final String securite = ""; + + @Test + public void testBuild() throws NoTeamcenterConnectionException { + List results = new ItemRevisionQuery(getSession()).searchIDAndRevision(id, revision).findAll(); + Assert.assertFalse(results.isEmpty()); + DocNorm test = new DocNorm(getSession(), results.get(0)); + Assert.assertNotNull(test); + Assert.assertEquals(id, test.getDocId()); + Assert.assertEquals(revision, test.getRevision()); + Assert.assertEquals(name, test.getName()); + Assert.assertEquals(designationEN, test.getDesignationEn()); + Assert.assertEquals(idOrigine, test.getIdOrigine()); + Assert.assertEquals(securite, test.getSensibiliteSecurite()); + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return R15_POLICY_FULL; + } +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/documentationobjects/DocTechnicTest.java b/teamcenter/src/test/java/com/capgemini/reports/documentationobjects/DocTechnicTest.java new file mode 100644 index 0000000..bd9197f --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/documentationobjects/DocTechnicTest.java @@ -0,0 +1,51 @@ +package com.capgemini.reports.documentationobjects; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +@Slf4j +public class DocTechnicTest extends AbstractTeamcenterTest { + + private static final String DOC_REV = "B"; + private static final String DOC_ID = "DOC-00264940"; + + @Test + public void testBuild() throws NoTeamcenterConnectionException { + List results = new ItemRevisionQuery(getSession()).searchIDAndRevision(DOC_ID, DOC_REV).findAll(); + Assert.assertFalse(results.isEmpty()); + ItemRevision techItemRev = results.get(0); + DocTechnic docTechnic = new DocTechnic(getSession(), techItemRev); + log.info("Name = " + docTechnic.getName()); + Assert.assertNotNull(docTechnic.getName()); + Assert.assertFalse(docTechnic.getName().isEmpty()); + log.info("Revision = " + docTechnic.getRevision()); + Assert.assertNotNull(docTechnic.getRevision()); + Assert.assertEquals(DOC_REV, docTechnic.getRevision()); + log.info("Indice = " + docTechnic.getIndice()); + Assert.assertNotNull(docTechnic.getIndice()); + Assert.assertFalse(docTechnic.getIndice().isEmpty()); + log.info("Reference = " + docTechnic.getReference()); + Assert.assertNotNull(docTechnic.getReference()); + Assert.assertFalse(docTechnic.getReference().isEmpty()); + log.info("Type = " + docTechnic.getType()); + Assert.assertNotNull(docTechnic.getType()); + Assert.assertFalse(docTechnic.getType().isEmpty()); + log.info("Typedoctechnic = " + docTechnic.getTypeDocTechnic1()); + Assert.assertNotNull(docTechnic.getTypeDocTechnic1()); + Assert.assertTrue(docTechnic.getTypeDocTechnic1().contains("Freeze document")); + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return R20_POLICY_FULL; + } + +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/releasestatus/TcReleaseStatusTest.java b/teamcenter/src/test/java/com/capgemini/reports/releasestatus/TcReleaseStatusTest.java new file mode 100644 index 0000000..10bb680 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/releasestatus/TcReleaseStatusTest.java @@ -0,0 +1,58 @@ +package com.capgemini.reports.releasestatus; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.object.pom.status.TcReleaseStatus; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.ReleaseStatus; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + + +public class TcReleaseStatusTest extends AbstractTeamcenterTest { + + private static final String DET_ID = "620-037-104-0"; + + @Test + public void testGetChosenStatus() throws NoTeamcenterConnectionException { + // GET ALTERNATE REVISION LIST + List detRevisionList = new ItemRevisionQuery(getSession()).searchIDAndRevision(DET_ID, "A").findAll(); + Assert.assertNotNull(detRevisionList); + Assert.assertFalse(detRevisionList.isEmpty()); + + List releaseStatusList = TcReleaseStatus.getChosenStatus(getSession(), detRevisionList.get(0), StatusEnum.J3A); + if (!releaseStatusList.isEmpty()) { + for (ReleaseStatus status : releaseStatusList) { + Assert.assertEquals(StatusEnum.J3A.getIdentifier(), status.get_name()); + } + } + } + + @Test + public void testGetAllStatusExceptSome() throws NoTeamcenterConnectionException { + // GET ALTERNATE REVISION LIST + List detRevisionList = new ItemRevisionQuery(getSession()).searchIDAndRevision(DET_ID, "A").findAll(); + Assert.assertNotNull(detRevisionList); + Assert.assertFalse(detRevisionList.isEmpty()); + + List releaseStatusList = + TcReleaseStatus.getAllStatusExceptSome(getSession(), detRevisionList.get(0), StatusEnum.J3A, StatusEnum.J3B, StatusEnum.EFFECTIVITY); + if (!releaseStatusList.isEmpty()) { + for (ReleaseStatus status : releaseStatusList) { + Assert.assertNotSame(StatusEnum.J3A.getIdentifier(), status.get_name()); + Assert.assertNotSame(StatusEnum.J3B.getIdentifier(), status.get_name()); + Assert.assertNotSame(StatusEnum.EFFECTIVITY.getIdentifier(), status.get_name()); + } + } + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return DEFAULT_POLICY; + } +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/DualsGenericsTest.java b/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/DualsGenericsTest.java new file mode 100644 index 0000000..d0e81bd --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/DualsGenericsTest.java @@ -0,0 +1,47 @@ +package com.capgemini.reports.reports.parameters; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import lombok.extern.slf4j.Slf4j; +import org.junit.Test; + +/** + * @author JMONTOUT + * + */ +@Slf4j +public class DualsGenericsTest { + + private static final String PRODUCT_97R0 = "97R0"; + private static final String GENERIC_U22 = "U22"; + private static final String GENERIC_ASSEMB_22U = "22U"; + private static final int UNIT_520 = 520; + + + private ProductUnit getProductUnit() { + return new ProductUnit(PRODUCT_97R0, UNIT_520); + } + + /** + * JUNIT Test + * + * @throws KurtException should not happen + */ + @Test + public void testCreateDualGenerics() throws KurtException { + log.info("testCreateDualGenerics ...."); + + DualGenerics dualGenerics = new DualGenerics(getProductUnit(), GENERIC_U22, GENERIC_ASSEMB_22U); + log.info("###############################"); + log.info("Type : " + dualGenerics.asGeneric().getType()); + log.info("ID : " + dualGenerics.asGeneric().getID()); + log.info("toString : " + dualGenerics.asGeneric().toString()); + log.info("BOMLine : " + dualGenerics.asGeneric().getType().getBomLinkType()); + log.info("###############################"); + log.info("Type : " + dualGenerics.asGenericAssemb().getType()); + log.info("ID : " + dualGenerics.asGenericAssemb().getID()); + log.info("toString : " + dualGenerics.asGenericAssemb().toString()); + log.info("BOMLine : " + dualGenerics.asGenericAssemb().getType().getBomLinkType()); + } + + +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/GenericsTest.java b/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/GenericsTest.java new file mode 100644 index 0000000..87cd566 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/GenericsTest.java @@ -0,0 +1,58 @@ +package com.capgemini.reports.reports.parameters; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.capgemini.reports.exceptions.NotFoundException; +import lombok.extern.slf4j.Slf4j; +import org.junit.Test; + +/** + * @author JMONTOUT + */ +@Slf4j +public class GenericsTest extends AbstractTeamcenterTest { + + private static final String PRODUCT_97R0 = "97R0"; + private static final String GENERIC_U22 = "U22"; + private static final String GENERIC_EMPTY = ""; + private static final String GENERIC_ASSEMB_22U = "22U"; + private static final String GENERIC_ASSEMB_EMPTY = ""; + private static final int UNIT_520 = 520; + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return DEFAULT_POLICY; + } + + @Test + public void testGeneric() throws NotFoundException, NoTeamcenterConnectionException { + log.info("testGeneric ...."); + log.info("GENERIC ID {" + GENERIC_U22 + "} AND GENERIC_ASSEMB {" + GENERIC_ASSEMB_EMPTY + "} EMPTY "); + Generics generic = new Generics(getProductUnit(), GENERIC_U22, GENERIC_ASSEMB_EMPTY); + + log.info("EXPECTED type {" + generic.getType() + "}"); + log.info("EXPECTED ID {" + generic.getID() + "}"); + log.info("EXPECTED BOM line type {" + generic.getType().getBomLinkType() + "}"); + log.info("EXPECTED getItemID {" + generic.getItem(getSession()).get_item_id() + "}"); + + } + + @Test + public void testGenericAssemb() throws NotFoundException, NoTeamcenterConnectionException { + log.info("testGenericAssemb ...."); + log.info("GENERIC ID {" + GENERIC_EMPTY + "} EMPTY AND GENERIC_ASSEMB {" + GENERIC_ASSEMB_22U + "}"); + Generics genericAssemb = new Generics(getProductUnit(), GENERIC_EMPTY, GENERIC_ASSEMB_22U); + + log.info("EXPECTED type {" + genericAssemb.getType() + "}"); + log.info("EXPECTED ID {" + genericAssemb.getID() + "}"); + log.info("EXPECTED BOM line type {" + genericAssemb.getType().getBomLinkType() + "}"); + log.info("EXPECTED getItemID {" + genericAssemb.getItem(getSession()).get_item_id() + "}"); + } + + + private ProductUnit getProductUnit() { + return new ProductUnit(PRODUCT_97R0, UNIT_520); + } + +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/ProductUnitTest.java b/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/ProductUnitTest.java new file mode 100644 index 0000000..373d4da --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/ProductUnitTest.java @@ -0,0 +1,56 @@ +package com.capgemini.reports.reports.parameters; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.teamcenter.soa.client.model.strong.Item; +import org.junit.Assert; +import org.junit.Test; + + +public class ProductUnitTest extends AbstractTeamcenterTest { + + private static final String PRODUCT_ID = "97R0"; + + private static final int GOOD_UNIT = 520; + private static final String GOOD_UNIT_STR = "520"; + private static final String BAD_UNIT_STR = "520adf"; + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return DEFAULT_POLICY; + } + + /** + * JUnit test. + * + * @throws InvalidUserInputException should not happen + */ + @Test + public void parseUserUnitTest() throws InvalidUserInputException { + ProductUnit productUnit = new ProductUnit(PRODUCT_ID, GOOD_UNIT_STR); + productUnit.parseUserUnit(); + Assert.assertEquals(GOOD_UNIT, productUnit.getUnit()); + } + + /** + * JUnit test. + * + * @throws InvalidUserInputException should not happen + */ + @Test(expected = InvalidUserInputException.class) + public void parseUserUnitTestFail() throws InvalidUserInputException { + ProductUnit productUnit = new ProductUnit(PRODUCT_ID, BAD_UNIT_STR); + productUnit.parseUserUnit(); + } + + @Test + public void getProductTest() throws NotFoundException, NoTeamcenterConnectionException { + ProductUnit productUnit = new ProductUnit(PRODUCT_ID, BAD_UNIT_STR); + Item item = productUnit.getProduct(getSession()); + Assert.assertEquals(PRODUCT_ID, item.get_item_id()); + } + +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/TcEffectivityDateTest.java b/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/TcEffectivityDateTest.java new file mode 100644 index 0000000..a2dff25 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/TcEffectivityDateTest.java @@ -0,0 +1,76 @@ +package com.capgemini.reports.reports.parameters; + +import com.capgemini.framework.common.TeamcenterDateFormatter; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Calendar; + + +@Slf4j +public class TcEffectivityDateTest { + + + private static final String DATE_USER_INPUT = "08-12-2014"; + private static final String DATE_USER_INPUT_EMPTY = ""; + + + @Test + public void testEffectivityDateWithUserInput() { + log.info("testEffectivityDateWithUserInputNotEmpty..."); + log.info("User Input: " + DATE_USER_INPUT); + String formattedDate = TeamcenterDateFormatter.translateDateFormatForRequest(DATE_USER_INPUT); + Calendar userInputDate = TeamcenterDateFormatter.makeTeamcenterCalendar(DATE_USER_INPUT); + + EffectivityDate effectivityDate = new EffectivityDate(userInputDate); + + Assert.assertFalse(effectivityDate.isNow()); + Assert.assertNotNull(effectivityDate.getDateTime()); + + log.info("Expected object Calendar = {}", effectivityDate.getDateTime()); + log.info("Expected isNow = {}", effectivityDate.isNow()); + Assert.assertEquals(formattedDate, effectivityDate.getFormattedDateForTcRequest()); + + } + + + @Test + public void testEffectivityDateWithoutUserInput() { + log.info("testEffectivityDateWithUserInputNotEmpty..."); + log.info("User Input: " + DATE_USER_INPUT); + + EffectivityDate effectivityDate = new EffectivityDate(); + + Assert.assertTrue(effectivityDate.isNow()); + Assert.assertNull(effectivityDate.getDateTime()); + + log.info("Expected object Calendar = {}", effectivityDate.getDateTime()); + log.info("Expected isNow = {}", effectivityDate.isNow()); + } + + + @Test + public void testEffectivityDateWithEmptyUserInput() { + log.info("testEffectivityDateWITHOUTUserInputNotEmpty..."); + log.info("USER INPUT {" + DATE_USER_INPUT_EMPTY + "} EMPTY"); + + EffectivityDate effectivityDate = new EffectivityDate(DATE_USER_INPUT_EMPTY); + + Assert.assertTrue(effectivityDate.isNow()); + Assert.assertNull(effectivityDate.getDateTime()); + + log.info("Expected object Calendar TODAY = {}", effectivityDate.getDateTime()); + log.info("Expected isNow = {}", effectivityDate.isNow()); + } + + + @Test + public void testIsNowTRUE() { + log.info("testIsNowTRUE ...."); + EffectivityDate effectivityDate = new EffectivityDate(); + Assert.assertTrue(effectivityDate.isNow()); + log.info("Expected isNow = {}", effectivityDate.isNow()); + } + +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/checker/GenericExistenceCheckTest.java b/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/checker/GenericExistenceCheckTest.java new file mode 100644 index 0000000..26aa5db --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/checker/GenericExistenceCheckTest.java @@ -0,0 +1,55 @@ +package com.capgemini.reports.reports.parameters.checker; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.reports.parameters.Generics; +import com.capgemini.reports.reports.parameters.ProductUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Test; + + +@Slf4j +public class GenericExistenceCheckTest extends AbstractTeamcenterTest { + + private static final String PRODUCT_ID_FOR_GENERIC_ASSEMB = "97R0"; + private static final String UNIT_FOR_GENERIC_ASSEMB = "520"; + private static final String GENERIC_ASSEMB_ID = "22U"; + + private static final String PRODUCT_ID_FOR_GENERIC = "65A1"; + private static final String GENERIC_ID = "A29"; + private static final String UNIT_FOR_GENERIC = "20"; + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return DEFAULT_POLICY; + } + + /** + * JUnit Test. + * + * @throws InvalidUserInputException should not happen + * @throws NoTeamcenterConnectionException should not happen + */ + @Test + public void checkTest() throws InvalidUserInputException, NoTeamcenterConnectionException { + log.info("Checking Product-Unit Alone..."); + ProductUnit productUnitAlone = new ProductUnit(PRODUCT_ID_FOR_GENERIC, UNIT_FOR_GENERIC); + Generics productAlone = new Generics(productUnitAlone, null, null); + new GenericExistenceChecker(productAlone).check(getSession()); + log.info(" Product-Unit Alone OK"); + + log.info("Checking Generic Assemb..."); + ProductUnit productUnitForGenericAssemb = new ProductUnit(PRODUCT_ID_FOR_GENERIC_ASSEMB, UNIT_FOR_GENERIC_ASSEMB); + Generics genericAssemb = new Generics(productUnitForGenericAssemb, null, GENERIC_ASSEMB_ID); + new GenericExistenceChecker(genericAssemb).check(getSession()); + log.info(" Generic Assemb OK"); + + log.info("Checking Generic..."); + ProductUnit productUnitForGeneric = new ProductUnit(PRODUCT_ID_FOR_GENERIC, UNIT_FOR_GENERIC); + Generics generic = new Generics(productUnitForGeneric, GENERIC_ID, null); + new GenericExistenceChecker(generic).check(getSession()); + log.info(" Generic OK"); + } +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/checker/ObjectTypeCheckerTest.java b/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/checker/ObjectTypeCheckerTest.java new file mode 100644 index 0000000..ea06064 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/checker/ObjectTypeCheckerTest.java @@ -0,0 +1,86 @@ +package com.capgemini.reports.reports.parameters.checker; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import org.junit.Test; + + +public class ObjectTypeCheckerTest extends AbstractTeamcenterTest { + + private static final String PART_ID = "350-290-601-0"; + + /** + * JUnit test. + * + * @throws InvalidUserInputException should not happen + * @throws NoTeamcenterConnectionException should not happen + */ + @Test + public void testCheckPartPass() throws InvalidUserInputException, NoTeamcenterConnectionException { + new ObjectTypeChecker(PART_ID, "Part").check(getSession()); + } + + /** + * JUnit test. + * + * @throws InvalidUserInputException should not happen + * @throws NoTeamcenterConnectionException should not happen + */ + @Test + public void testCheckPartAeroPass() throws InvalidUserInputException, NoTeamcenterConnectionException { + new ObjectTypeChecker(PART_ID, "Part Aero").check(getSession()); + } + + /** + * JUnit test. + * + * @throws InvalidUserInputException should not happen + * @throws NoTeamcenterConnectionException should not happen + */ + @Test + public void testCheckMultiPass() throws InvalidUserInputException, NoTeamcenterConnectionException { + new ObjectTypeChecker(PART_ID, "Truc", "Machin", "Part Aero").check(getSession()); + } + + /** + * JUnit test. + * + * @throws InvalidUserInputException SHOULD HAPPEN! + * @throws NoTeamcenterConnectionException should not happen + */ + @Test(expected = InvalidUserInputException.class) + public void testCheckPartAeroRevisionFail() throws InvalidUserInputException, NoTeamcenterConnectionException { + new ObjectTypeChecker(PART_ID, "Part Aero Revision").check(getSession()); + } + + + /** + * JUnit test. + * + * @throws InvalidUserInputException SHOULD HAPPEN! + * @throws NoTeamcenterConnectionException should not happen + */ + @Test(expected = InvalidUserInputException.class) + public void testCheckPartFailNofilter() throws InvalidUserInputException, NoTeamcenterConnectionException { + new ObjectTypeChecker(PART_ID).check(getSession()); + } + + /** + * JUnit test. + * + * @throws InvalidUserInputException SHOULD HAPPEN! + * @throws NoTeamcenterConnectionException should not happen + */ + @Test(expected = InvalidUserInputException.class) + public void testCheckPartFail() throws InvalidUserInputException, NoTeamcenterConnectionException { + new ObjectTypeChecker(PART_ID, "Truc", "Bidule").check(getSession()); + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return DEFAULT_POLICY; + } + +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/checker/ProductCheckTest.java b/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/checker/ProductCheckTest.java new file mode 100644 index 0000000..7d5eb1e --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/checker/ProductCheckTest.java @@ -0,0 +1,31 @@ +package com.capgemini.reports.reports.parameters.checker; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import org.junit.Test; + +/** + * JUnit test class. + */ +public class ProductCheckTest extends AbstractTeamcenterTest { + + private static final String PRODUCT_ID_FOR_GENERIC_ASSEMB = "97R0"; + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return DEFAULT_POLICY; + } + + /** + * JUnit test. + * + * @throws InvalidUserInputException should not happen + * @throws NoTeamcenterConnectionException should not happen + */ + @Test + public void checkTest() throws InvalidUserInputException, NoTeamcenterConnectionException { + new ProductChecker(PRODUCT_ID_FOR_GENERIC_ASSEMB).check(getSession()); + } +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/checker/ProductUnitCheckTest.java b/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/checker/ProductUnitCheckTest.java new file mode 100644 index 0000000..2913708 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/checker/ProductUnitCheckTest.java @@ -0,0 +1,40 @@ +package com.capgemini.reports.reports.parameters.checker; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.reports.parameters.ProductUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.junit.Test; + +/** + * JUnit test class. + */ +@Slf4j +public class ProductUnitCheckTest extends AbstractTeamcenterTest { + + private static final String PRODUCT_ID_FOR_GENERIC_ASSEMB = "97R0"; + private static final String UNIT_FOR_GENERIC_ASSEMB_STR = "520"; + private static final int UNIT_FOR_GENERIC_ASSEMB = 520; + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return DEFAULT_POLICY; + } + + /** + * JUnit test. + * + * @throws InvalidUserInputException should not happen + * @throws NoTeamcenterConnectionException should not happen + */ + @Test + public void checkTest() throws InvalidUserInputException, NoTeamcenterConnectionException { + log.info("Checking existence of product Id=" + PRODUCT_ID_FOR_GENERIC_ASSEMB); + ProductUnit productUnit = new ProductUnit(PRODUCT_ID_FOR_GENERIC_ASSEMB, UNIT_FOR_GENERIC_ASSEMB_STR); + new ProductUnitChecker(productUnit).check(getSession()); + Assert.assertEquals(UNIT_FOR_GENERIC_ASSEMB, productUnit.getUnit()); + } +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/checker/TcEffectivityCheckerTest.java b/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/checker/TcEffectivityCheckerTest.java new file mode 100644 index 0000000..43e67c2 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/reports/parameters/checker/TcEffectivityCheckerTest.java @@ -0,0 +1,41 @@ +package com.capgemini.reports.reports.parameters.checker; + +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.reports.parameters.EffectivityDate; +import org.junit.Test; + +import java.util.Calendar; + + +public class TcEffectivityCheckerTest { + + /** + * JUnit test. + * + * @throws InvalidUserInputException should not happen + */ + @Test + public void checkSuccess() throws InvalidUserInputException { + // Check for 'now' : should not throw an exception + EffectivityDate now = new EffectivityDate(); + new EffectivityChecker(now).check(null); // no need for a session + + // Check for a date in the past: should not throw an exception + Calendar fiveDaysAgo = Calendar.getInstance(); + fiveDaysAgo.add(Calendar.DAY_OF_MONTH, -5); + new EffectivityChecker(new EffectivityDate(fiveDaysAgo)).check(null); + } + + /** + * JUnit test. + * + * @throws InvalidUserInputException should not happen + */ + public void checkNullDateNotNow() throws InvalidUserInputException { + // Give no or null input, still obtain a valid date representing the current date + new EffectivityChecker(new EffectivityDate()).check(null); + new EffectivityChecker(new EffectivityDate((String) null)).check(null); + new EffectivityChecker(new EffectivityDate((Calendar) null)).check(null); + } + +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/teamcenter/ObjectInfoHelperTest.java b/teamcenter/src/test/java/com/capgemini/reports/teamcenter/ObjectInfoHelperTest.java new file mode 100644 index 0000000..c99a3a7 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/teamcenter/ObjectInfoHelperTest.java @@ -0,0 +1,217 @@ +package com.capgemini.reports.teamcenter; + +import com.capgemini.framework.teamcenter.exceptions.KurtException; +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.capgemini.reports.exceptions.InvalidUserInputException; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.releasestatus.RevisionStatusAndDate; +import com.capgemini.reports.reports.parameters.Generics; +import com.capgemini.reports.reports.parameters.ProductUnit; +import com.google.common.base.Optional; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.Item; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.ReleaseStatus; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Calendar; +import java.util.List; + +@Slf4j +public class ObjectInfoHelperTest extends AbstractTeamcenterTest { + + private static final String PRODUCT_35R0 = "35R0"; + private static final String GENERIC_N24 = "N24"; + private static final String GENERIC_ASSEMB_24N = "24N"; + private static final int UNIT_60 = 60; + + // ************ For Alternate and DET tests ************** + private static final String[] EXPECTED_PARTS_ID_OF_ALTERNATE = {"1688M69P01", "1688M69P07"}; + private static final String[] EXPECTED_PARTS_ID_OF_DET = {"327-701-088-0", "327-701-105-0"}; + private static final String ALTERNATE_ID = "ART00010127"; + private static final String DET_ID = "620-037-104-0"; + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return DEFAULT_POLICY; + } + + @Test + public void testGetPartsInPseudoFolderOfAlternateRevision() throws KurtException { + log.info("testGetPartsOfAlternateRevision() with Alternate Revision : " + ALTERNATE_ID); + + // GET ALTERNATE REVISION + List alternateRevisionList = new ItemRevisionQuery(getSession()).searchIDAndRevision(ALTERNATE_ID, "A").findAll(); + Assert.assertNotNull(alternateRevisionList); + Assert.assertFalse(alternateRevisionList.isEmpty()); + + // GET ALTERNATE REVISION + ItemRevision itemRevision = alternateRevisionList.get(0); + Assert.assertNotNull(itemRevision); + + List listPartsOfAlternate = ObjectInfoHelper.getPartsInPseudoFolderOfAltOrDetRevision(getSession(), itemRevision); + + Assert.assertEquals(EXPECTED_PARTS_ID_OF_ALTERNATE.length, listPartsOfAlternate.size()); + + String parts = "[ "; + for (ModelObject modelObject : listPartsOfAlternate) { + parts += modelObject.getPropertyDisplayableValue("item_id") + " "; + } + parts += "]"; + log.info("Found IDs = {}", parts); + log.info("Expected IDs = {}", Arrays.toString(EXPECTED_PARTS_ID_OF_ALTERNATE)); + } + + @Test + public void testGetClosestGenerics() + throws NotFoundException, InvalidUserInputException, NoTeamcenterConnectionException { + log.info("testGetClosestGenerics "); + ObjectInfoLoader infoLoader = new ObjectInfoLoader(getSession()); + ProductUnit product = new ProductUnit(PRODUCT_35R0, UNIT_60); + + // Test on a generic + Generics generic = new Generics(product, GENERIC_N24, ""); + log.info("check Generic " + generic.getID() + "with unit " + product.getUnit()); + List listGenericRevision = infoLoader.getGenericUnderProduct(generic, product); + boolean isGenericHasAnUnitRevision = ObjectInfoHelper.getClosestGenerics(getSession(), generic.getID(), product.getUnit(), listGenericRevision); + Assert.assertTrue("FAILED : Check Generic is " + GENERIC_N24 + " hasn't an Unit Revision " + UNIT_60, isGenericHasAnUnitRevision); + log.info("SUCCESS : Generic " + GENERIC_N24 + " has an Unit Revision with " + UNIT_60 + " result " + isGenericHasAnUnitRevision); + + // Test on a generic assemb + Generics genericAssemb = new Generics(product, "", GENERIC_ASSEMB_24N); + log.info("check Generic Assemb " + generic.getID() + "with unit " + product.getUnit()); + List listGenericAssembRevision = infoLoader.getGenericUnderProduct(generic, product); + boolean isGenericAssembHasAnUnitRevision = + ObjectInfoHelper.getClosestGenerics(getSession(), genericAssemb.getID(), product.getUnit(), listGenericAssembRevision); + Assert.assertTrue("FAILED : Check Generic is " + GENERIC_N24 + " hasn't an Unit Revision " + UNIT_60, isGenericAssembHasAnUnitRevision); + log.info("SUCCESS : Generic " + GENERIC_N24 + " has an Unit Revision with " + UNIT_60 + " result " + isGenericAssembHasAnUnitRevision); + } + + @Test + public void testGetPartsInPseudoFolderOfAltOrDetRevision() throws KurtException { + log.info("testGetPartsInPseudoFolderOfAltOrDetRevision()"); + + ItemRevision alt = new ItemRevisionQuery(getSession()).searchIDAndRevision("351-403-051-0", "A").findAll().get(0); + Assert.assertNotNull(alt); + List list = ObjectInfoHelper.getPartsInPseudoFolderOfAltOrDetRevision(getSession(), alt); + Assert.assertNotNull(list); + Assert.assertTrue(!list.isEmpty()); + + for (Item item : list) { + log.info("Parts in the psudo-folder : {}\t{}", item.getUid(), item.get_item_id()); + } + } + + @Test + public void testGetPartsOfDETRevision() throws KurtException { + log.info("testGetPartsOfDETRevision() with DET Revision : " + DET_ID); + + // GET ALTERNATE REVISION LIST + List alternateRevisionList = new ItemRevisionQuery(getSession()).searchIDAndRevision(DET_ID, "A").findAll(); + Assert.assertNotNull(alternateRevisionList); + Assert.assertFalse(alternateRevisionList.isEmpty()); + + // GET ALTERNATE REVISION + ItemRevision itemRevision = alternateRevisionList.get(0); + Assert.assertNotNull(itemRevision); + + List listPartsOfDET = ObjectInfoHelper.getPartsInPseudoFolderOfAltOrDetRevision(getSession(), itemRevision); + Assert.assertNotNull(listPartsOfDET); + Assert.assertEquals(EXPECTED_PARTS_ID_OF_DET.length, listPartsOfDET.size()); + + String parts = "[ "; + for (Item item : listPartsOfDET) { + parts += item.get_item_id() + " "; + } + parts += "]"; + log.info("Found IDs = {}", parts); + log.info("Expected IDs = {}", Arrays.toString(EXPECTED_PARTS_ID_OF_DET)); + } + + @Test + public void testGetRevisionWithHighestRange() throws NoTeamcenterConnectionException { + List genericRevisions = new ItemRevisionQuery(getSession()).searchID("U24").findAll(); + List genericRevFiltered = ObjectInfoHelper.getRevisionWithHighestRange(getSession(), genericRevisions, "60"); + Assert.assertNotNull(genericRevFiltered); + Assert.assertFalse(genericRevFiltered.isEmpty()); + + // Verifying contents: 3 revisions have a unit range 10-UP: c, I, and K. no other revision have unit range between 10 and 60 (the limit) + Assert.assertEquals(3, genericRevFiltered.size()); + boolean foundRevisionC = false; + boolean foundRevisionI = false; + boolean foundRevisionK = false; + for (ItemRevision item : genericRevFiltered) { + foundRevisionC = foundRevisionC || "C".equals(item.get_item_revision_id()); + foundRevisionI = foundRevisionI || "I".equals(item.get_item_revision_id()); + foundRevisionK = foundRevisionK || "K".equals(item.get_item_revision_id()); + } + Assert.assertTrue(foundRevisionI && foundRevisionK); + } + + @Test + public void testGetModelObjectsInPseudoFolderUnderItemRevision() throws KurtException { + List rfGenericRevisions = new ItemRevisionQuery(getSession()).searchIDAndRevision("00014868", "I").findAll(); + ItemRevision rfGeneric = rfGenericRevisions.get(0); + Assert.assertNotNull(rfGeneric); + + List resultsPseudoFolder = ObjectInfoHelper.getModelObjectsInPseudoFolderUnderItemRevision(getSession(), rfGeneric, "RFGenericBom"); + Assert.assertNotNull(resultsPseudoFolder); + Assert.assertFalse(resultsPseudoFolder.isEmpty()); + } + + @Test + public void testGetRevisionAndStatusWithMostRecentReleaseDate() + throws NoTeamcenterConnectionException { + // There are 13 revisions of this object! + List revisions = new ItemRevisionQuery(getSession()).searchID("00014868").findAll(); + Optional selectStatus = ObjectInfoHelper.getRevisionAndStatusWithMostRecentReleaseDate(getSession(), revisions, null); + Assert.assertNotNull(selectStatus); + Assert.assertTrue(selectStatus.isPresent()); + Assert.assertNotNull(selectStatus.get()); + Assert.assertNotNull(selectStatus.get().getItemRevision()); + Assert.assertNotNull(selectStatus.get().getReleaseDate()); + Assert.assertNotNull(selectStatus.get().getReleaseStatus()); + Assert.assertEquals(selectStatus.get().getItemRevision().get_item_id(), "00014868"); + Assert.assertEquals(selectStatus.get().getItemRevision().get_item_revision_id(), "B"); + Assert.assertEquals(selectStatus.get().getReleaseStatus().get_name(), "J3B"); + } + + @Test + public void testGetRevisionAndStatusWithMostRecentReleaseDateNotFound() throws NoTeamcenterConnectionException { + List revisions = new ItemRevisionQuery(getSession()).searchID("00065682").findAll(); + Optional selectStatus = + ObjectInfoHelper.getRevisionAndStatusWithMostRecentReleaseDate(getSession(), revisions, Calendar.getInstance()); + Assert.assertNotNull(selectStatus); + Assert.assertFalse(selectStatus.isPresent()); + } + + @Test + public void testGetRevisionWithMostRecentModificationDate() throws NoTeamcenterConnectionException { + List revisions = new ItemRevisionQuery(getSession()).searchIDAndRevision("00014868", "I").findAll(); + Assert.assertNotNull(revisions); + Assert.assertFalse(revisions.isEmpty()); + + RevisionStatusAndDate selectedRevision = + ObjectInfoHelper.getRevisionAndStatusWithMostRecentModificationDate(revisions, Calendar.getInstance()); + Assert.assertNotNull(selectedRevision); + for (ItemRevision itemRev : revisions) { + Assert.assertFalse(itemRev.get_last_mod_date().getTime().after(selectedRevision.getItemRevision().get_last_mod_date().getTime())); + } + } + + @Test + public void testGetStatusWithMostRecentReleaseDate() throws NoTeamcenterConnectionException { + List revisions = new ItemRevisionQuery(getSession()).searchIDAndRevision("309-162-004-0", "D").findAll(); + ItemRevision itemRev = revisions.get(0); + ReleaseStatus selectStatus = ObjectInfoHelper.getStatusWithMostRecentReleaseDate(getSession(), itemRev, StatusEnum.EFFECTIVITY); + Assert.assertNotNull(selectStatus); + Assert.assertFalse(StatusEnum.EFFECTIVITY.getIdentifier().equals(selectStatus.get_name())); + } +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/teamcenter/TeamcenterConnectionTest.java b/teamcenter/src/test/java/com/capgemini/reports/teamcenter/TeamcenterConnectionTest.java new file mode 100644 index 0000000..0bf9d4b --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/teamcenter/TeamcenterConnectionTest.java @@ -0,0 +1,27 @@ +package com.capgemini.reports.teamcenter; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.AbstractTeamcenterTest; +import org.junit.Assert; +import org.junit.Test; + + +public class TeamcenterConnectionTest extends AbstractTeamcenterTest { + + /** + * JUnit test. + * + * @throws NoTeamcenterConnectionException should not happen + **/ + @Test + public void testLoginLogout() throws NoTeamcenterConnectionException { + // The inheritance of AbstractTeamcenterTest is sufficient to test the login() and logout() of TcSession . + Assert.assertNotNull(getSession()); + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return DEFAULT_POLICY; + } +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/TypeQueryTest.java b/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/TypeQueryTest.java new file mode 100644 index 0000000..076ed03 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/TypeQueryTest.java @@ -0,0 +1,44 @@ +package com.capgemini.reports.teamcenter.queries; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.teamcenter.soa.client.model.strong.RevisionRule; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +@Slf4j +public class TypeQueryTest extends AbstractTeamcenterTest { + + private static final String REVISION_RULE_NAME = " DMA Configuration Interface"; + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return DEFAULT_POLICY; + } + + @Test + public void testGetRevisionRule() throws NoTeamcenterConnectionException { + // Execute the query + List list = TypeQuery.getRevisionRule(getSession(), REVISION_RULE_NAME); + Assert.assertNotNull(list); + Assert.assertTrue(!list.isEmpty()); + + // Parse the content + for (RevisionRule rule : list) { + log.info("Revision rule name: \"{}\"", rule.get_object_name()); + Assert.assertEquals(REVISION_RULE_NAME, rule.get_object_name()); + } + } + + @Test + public void testGetRevisionRuleWrongName() throws NoTeamcenterConnectionException { + // Execute the query + List list = TypeQuery.getRevisionRule(getSession(), "babar"); + Assert.assertNotNull(list); + Assert.assertTrue(list.isEmpty()); + } +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/saved/AllSequencesQueryTest.java b/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/saved/AllSequencesQueryTest.java new file mode 100644 index 0000000..91ff208 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/saved/AllSequencesQueryTest.java @@ -0,0 +1,35 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +@Slf4j +public class AllSequencesQueryTest extends AbstractTeamcenterTest { + + @Test + public void testSearchAllSequancesOfItem() throws NoTeamcenterConnectionException { + AllSequencesOfItemQuery query = new AllSequencesOfItemQuery(getSession()); + query.searchID("002603"); + List result = query.findAll(); + + Assert.assertEquals("Check itemRevision existence", result.isEmpty(), false); + log.info("Query has found {} itemRevision(s)", result.size()); + + for (ItemRevision itemRevision : result) { + log.info("--> found " + itemRevision.get_item_id() + "/" + itemRevision.get_item_revision_id() + "." + itemRevision.get_sequence_id()); + } + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return DEFAULT_POLICY; + } + +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/saved/ChangeRequestQueryTest.java b/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/saved/ChangeRequestQueryTest.java new file mode 100644 index 0000000..df4915e --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/saved/ChangeRequestQueryTest.java @@ -0,0 +1,49 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.teamcenter.schemas.soa._2006_03.exceptions.ServiceException; +import com.teamcenter.soa.client.model.Property; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +@Slf4j +public class ChangeRequestQueryTest extends AbstractTeamcenterTest { + private static final String CHANGE_ID = "R201-012"; + + @Test + public void changeRequestQueryTest() throws NoTeamcenterConnectionException { + List list = new ChangeRequestQuery(getSession()).searchID(CHANGE_ID).findAll(); + Assert.assertNotNull(list); + Assert.assertFalse(list.isEmpty()); + log.info("{} ChangeRequest found with matching ID ({})", list.size(), CHANGE_ID); + for (ItemRevision itemRev : list) { + log.info(" + UID={}\tID={}\tRev={}", itemRev.getUid(), itemRev.get_item_id(), itemRev.get_item_revision_id()); + } + } + + @Test + public void changeRequestTypeModification() throws ServiceException, NoTeamcenterConnectionException { + List list = new ChangeRequestQuery(getSession()).searchID(CHANGE_ID).findAll(); + Assert.assertNotNull(list); + Assert.assertFalse(list.isEmpty()); + log.info("{} ChangeRequest found with matching ID ({})", list.size(), CHANGE_ID); + for (ItemRevision itemRev : list) { + Property prop = itemRev.getPropertyObject("pv4_type_modification"); + log.info(" + UID={}\tID={}\tRev={}", itemRev.getUid(), itemRev.get_item_id(), itemRev.get_item_revision_id()); + log.info(" -> ALL = {}", prop.getStringValue()); + log.info(" -> FR = {}", prop.getDisplayableValue()); + } + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return R07_POLICY_FULL; + } + +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/saved/UnitFromCRTest.java b/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/saved/UnitFromCRTest.java new file mode 100644 index 0000000..754faf8 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/saved/UnitFromCRTest.java @@ -0,0 +1,41 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +@Slf4j +public class UnitFromCRTest extends AbstractTeamcenterTest { + + private static final String CHANGE_ID = "report_change_id"; + private static final String MOD119895 = "MOD119895"; + private static final String UNIT_REVISION = "Unit Revision"; + + @Test + public void testSearchUnitFromCR() throws NoTeamcenterConnectionException { + UnitFromChangeRequestQuery query = new UnitFromChangeRequestQuery(getSession()); + query.addParam(CHANGE_ID, MOD119895); + + List result = query.findAll(); + Assert.assertEquals("Check unit existence", result.isEmpty(), false); + + log.info("Query has found {} item(s)", result.size()); + for (ItemRevision item : result) { + if (UNIT_REVISION.equals(item.get_object_type())) { + log.info(" + " + item.get_object_type() + " " + item.get_item_id()); + } + Assert.assertEquals(UNIT_REVISION, item.get_object_type()); + } + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return DEFAULT_POLICY; + } +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/saved/UnitQueryTest.java b/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/saved/UnitQueryTest.java new file mode 100644 index 0000000..9b4136f --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/saved/UnitQueryTest.java @@ -0,0 +1,44 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +@Slf4j +public class UnitQueryTest extends AbstractTeamcenterTest { + + @Test + public void testSearchUnit() throws NoTeamcenterConnectionException { + UnitQuery query = new UnitQuery(getSession()); + query.addEndItemID("65A1"); + + List result = query.findAll(); + Assert.assertEquals("Check unit existence", result.isEmpty(), false); + } + + @Test + public void testSearchUnitWithWorkflow() throws NoTeamcenterConnectionException { + UnitQuery query = new UnitQuery(getSession(), UnitQuery.UNIT_VALIDATION_UNIT_PAR_SO); + query.addEndItemID("*"); // Search any unit with this workflow + + List result = query.findAll(); + Assert.assertEquals("Check unit existence", result.isEmpty(), false); + + log.info("Query has found {} item(s)", result.size()); + for (ItemRevision item : result) { + log.info(" + " + item.get_item_id()); + } + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return DEFAULT_POLICY; + } + +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/saved/WorkflowOnChangeQueryTest.java b/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/saved/WorkflowOnChangeQueryTest.java new file mode 100644 index 0000000..8b218ad --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/saved/WorkflowOnChangeQueryTest.java @@ -0,0 +1,33 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.teamcenter.schemas.soa._2006_03.exceptions.ServiceException; +import com.teamcenter.soa.client.model.strong.EPMTask; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +public class WorkflowOnChangeQueryTest extends AbstractTeamcenterTest { + + @Test + public void testSearchWorkflow() throws ServiceException, NoTeamcenterConnectionException { + List result = new WorkflowOnChangeQuery(getSession()).searchIDAndRevision("MOD200381", "A").searchSequenceId("1").findAll(); + Assert.assertNotNull(result); + Assert.assertFalse(result.isEmpty()); + } + + @Test + public void testSearchWorkflow2() throws ServiceException, NoTeamcenterConnectionException { + List result = new WorkflowOnChangeQuery(getSession()).searchIDAndRevision("FPP0020016", "AA").searchSequenceId("1").findAll(); + Assert.assertNotNull(result); + Assert.assertFalse(result.isEmpty()); + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return R13_POLICY_FULL; + } +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/saved/WorkflowQueryTest.java b/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/saved/WorkflowQueryTest.java new file mode 100644 index 0000000..8305f06 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/teamcenter/queries/saved/WorkflowQueryTest.java @@ -0,0 +1,34 @@ +package com.capgemini.reports.teamcenter.queries.saved; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.teamcenter.soa.client.model.strong.EPMTask; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +@Slf4j +public class WorkflowQueryTest extends AbstractTeamcenterTest { + + @Test + public void testSearchValidationUnitParSO() throws NoTeamcenterConnectionException { + WorkflowOnUnitQuery query = WorkflowOnUnitQuery.searchValidationUnitParSO(getSession(), "00041717"); + List result = query.findAll(); + Assert.assertEquals("Check unit existence", result.isEmpty(), false); + + log.info("Query has found {} item(s)", result.size()); + for (EPMTask task : result) { + log.info(" + " + task.get_object_name()); + Assert.assertEquals("Task is not Validation Unit", WorkflowOnUnitQuery.UNIT_VALIDATION_UNIT_PAR_SO, task.get_object_name()); + } + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return DEFAULT_POLICY; + } + +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/users/SnecmaPersonTest.java b/teamcenter/src/test/java/com/capgemini/reports/users/SnecmaPersonTest.java new file mode 100644 index 0000000..ae10cf8 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/users/SnecmaPersonTest.java @@ -0,0 +1,41 @@ +package com.capgemini.reports.users; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.teamcenter.soa.client.model.ModelObject; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.Person; +import com.teamcenter.soa.client.model.strong.User; +import org.junit.Assert; +import org.junit.Test; + + +public class SnecmaPersonTest extends AbstractTeamcenterTest { + + /** + * JUnit test. + * @throws NoTeamcenterConnectionException Should not happen + */ + @Test + public void testBuild() throws NoTeamcenterConnectionException { + ItemRevision result = new ItemRevisionQuery(getSession()).searchIDAndRevision("INITB0204", "A").findAll().get(0); + Assert.assertNotNull(result); + + User user = (User) result.get_owning_user(); + Assert.assertNotNull(user); + + ModelObject personObject = user.get_person(); + Assert.assertNotNull(personObject); + + SnecmaPerson person = new SnecmaPerson((Person) personObject); + Assert.assertNotNull(person); + Assert.assertEquals("sp0mig11", person.getPersonName()); + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return R13_POLICY_FULL; + } +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/users/SnecmaUserTest.java b/teamcenter/src/test/java/com/capgemini/reports/users/SnecmaUserTest.java new file mode 100644 index 0000000..9de7d3d --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/users/SnecmaUserTest.java @@ -0,0 +1,38 @@ +package com.capgemini.reports.users; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemRevisionQuery; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.teamcenter.soa.client.model.strong.ItemRevision; +import com.teamcenter.soa.client.model.strong.User; +import org.junit.Assert; +import org.junit.Test; + + +public class SnecmaUserTest extends AbstractTeamcenterTest { + + /** + * JUnit test. + * @throws NoTeamcenterConnectionException Should not happen + */ + @Test + public void testBuild() throws NoTeamcenterConnectionException { + ItemRevision result = new ItemRevisionQuery(getSession()).searchIDAndRevision("INITB0204", "A").findAll().get(0); + Assert.assertNotNull(result); + + User userObject = (User) result.get_owning_user(); + Assert.assertNotNull(userObject); + + SnecmaUser user = new SnecmaUser(getSession(), userObject); + Assert.assertNotNull(user); + Assert.assertEquals("sp0mig11", user.getUserId()); + Assert.assertEquals("sp0mig11", user.getName()); + Assert.assertNotNull(user.getPerson()); + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return R13_POLICY_FULL; + } +} diff --git a/teamcenter/src/test/java/com/capgemini/reports/workflows/TaskTest.java b/teamcenter/src/test/java/com/capgemini/reports/workflows/TaskTest.java new file mode 100644 index 0000000..03b0005 --- /dev/null +++ b/teamcenter/src/test/java/com/capgemini/reports/workflows/TaskTest.java @@ -0,0 +1,87 @@ +package com.capgemini.reports.workflows; + +import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException; +import com.capgemini.framework.teamcenter.policies.PolicyLocation; +import com.capgemini.reports.AbstractTeamcenterTest; +import com.capgemini.reports.exceptions.NotFoundException; +import com.capgemini.reports.teamcenter.queries.DirectQuery; +import com.capgemini.reports.teamcenter.queries.saved.WorkflowOnChangeQuery; +import com.capgemini.reports.users.SnecmaUser; +import com.capgemini.reports.workflows.Task.TaskState; +import com.teamcenter.soa.client.model.strong.EPMTask; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +public class TaskTest extends AbstractTeamcenterTest { + + @Test + public void testBuildDaughterTask() throws NoTeamcenterConnectionException, NotFoundException { + DirectQuery taskQuery = new DirectQuery<>(getSession()); + EPMTask task = taskQuery.searchByUID("iOeZxqYwhLofXA"); // iOeZxqYwhLofXA <-- Add TcReleaseStatus Task + getSession().loadProperties(task,"state","creation_date","last_mod_date"); + Assert.assertNotNull(task); + Task motherTask = new Task(getSession(), task); + // State + Assert.assertEquals(TaskState.COMPLETED, motherTask.getState()); + // No active Tasks in this simple task + List activeTasks = motherTask.getActiveChildTasks(); + Assert.assertNotNull(activeTasks); + Assert.assertTrue(activeTasks.isEmpty()); + // Dates duly created + Assert.assertNotNull(motherTask.getCreationDate()); + Assert.assertNotNull(motherTask.getLastModDate()); + Assert.assertNotNull(motherTask.getLastModUser()); + // No Signoff users + Assert.assertNotNull(motherTask.getPendingSignoffsUser()); + Assert.assertTrue(motherTask.getPendingSignoffsUser().isEmpty()); + } + + @Test + public void testBuildTaskWithValidAndInvalidSignoffs() throws NoTeamcenterConnectionException, NotFoundException { + DirectQuery taskQuery = new DirectQuery<>(getSession()); + EPMTask task = taskQuery.searchByUID("jQXZxqYwhLofXA"); // jQXZxqYwhLofXA <-- EPMSelectSignoffTask select-signoff-team + Assert.assertNotNull(task); + getSession().loadProperties(task,"state","creation_date","last_mod_date"); + Task motherTask = new Task(getSession(), task); + // State + Assert.assertEquals(TaskState.COMPLETED, motherTask.getState()); + // No active Tasks in this simple task + List activeTasks = motherTask.getActiveChildTasks(); + Assert.assertNotNull(activeTasks); + Assert.assertTrue(activeTasks.isEmpty()); + // Mother task is its own parent + // Dates duly created + Assert.assertNotNull(motherTask.getCreationDate()); + Assert.assertNotNull(motherTask.getLastModDate()); + Assert.assertNotNull(motherTask.getLastModUser()); + // Signoff users: invalid + Assert.assertNotNull(motherTask.getPendingSignoffsUser()); + Assert.assertEquals(1, motherTask.getPendingSignoffsUser().size()); + for (SnecmaUser user : motherTask.getPendingSignoffsUser()) { + Assert.assertNotNull(user); + Assert.assertEquals("mbo", user.getUserId()); + } + } + + + @Test + public void testBuild() throws NoTeamcenterConnectionException { + WorkflowOnChangeQuery query = new WorkflowOnChangeQuery(getSession()); + query.searchIDAndRevision("MOD200478", "AA"); + List tasksList = query.findAll(); + EPMTask theMotherTask = null; + for (EPMTask epmTask : tasksList) { + if ("TEXZxqYwhLofXA".equals(epmTask.getUid())) { + theMotherTask = epmTask; + } + } + Assert.assertNotNull(theMotherTask); + } + + @Override + public PolicyLocation getPropertyPolicyIdentifier() { + return R13_POLICY_FULL; + } +} diff --git a/teamcenter/src/test/resources/TextFile.txt b/teamcenter/src/test/resources/TextFile.txt new file mode 100644 index 0000000..c57eff5 --- /dev/null +++ b/teamcenter/src/test/resources/TextFile.txt @@ -0,0 +1 @@ +Hello World! \ No newline at end of file diff --git a/teamcenter/src/test/resources/jasperPdfPrinterTest.pdf b/teamcenter/src/test/resources/jasperPdfPrinterTest.pdf new file mode 100644 index 0000000..42a49af Binary files /dev/null and b/teamcenter/src/test/resources/jasperPdfPrinterTest.pdf differ diff --git a/teamcenter/src/test/resources/log4j.properties b/teamcenter/src/test/resources/log4j.properties new file mode 100644 index 0000000..7b5ba65 --- /dev/null +++ b/teamcenter/src/test/resources/log4j.properties @@ -0,0 +1,22 @@ +log4j.logger.com.teamcenter.soa=WARN +log4j.logger.com.teamcenter.soa.internal.client.model=INFO +log4j.logger.org.apache=WARN +log4j.logger.httpclient=WARN + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.threshold=DEBUG +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %c{1}:%L - %m%n + +# Perso perfo +log4j.appender.perf=org.apache.log4j.FileAppender +log4j.appender.perf.File=C:/Users/Public/kurt/Jasper/output/perf.log +log4j.appender.perf.threshold=DEBUG +log4j.appender.perf.layout=org.apache.log4j.PatternLayout +log4j.appender.perf.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %c{1}:%L - %m%n + +# Root logger option +log4j.rootLogger=DEBUG, stdout, perf + diff --git a/teamcenter/src/test/resources/logging.properties b/teamcenter/src/test/resources/logging.properties new file mode 100644 index 0000000..1983b8d --- /dev/null +++ b/teamcenter/src/test/resources/logging.properties @@ -0,0 +1,3 @@ +handlers=java.util.logging.ConsoleHandler +java.util.logging.ConsoleHandler.level=FINEST +com.capgemini.level=FINEST diff --git a/teamcenter/src/test/resources/reporting.properties b/teamcenter/src/test/resources/reporting.properties new file mode 100644 index 0000000..76ff58e --- /dev/null +++ b/teamcenter/src/test/resources/reporting.properties @@ -0,0 +1,12 @@ +# Authentication to Teamcenter +com.capgemini.report.teamcenter.url=http://10.24.192.23:8888/tcitf +com.capgemini.report.teamcenter.session.login=infodba +com.capgemini.report.teamcenter.session.password=infodba +com.capgemini.report.teamcenter.session.discriminator=SoaAppX + +# FSC service data +com.capgemini.report.fsc.clientip=http://10.24.192.36:4544 +com.capgemini.report.fsc.cachedir=C:/Users/Public/kurt/FSCcache +# comma-separated, no need to end with coma +com.capgemini.report.fsc.assignedURI=http://10.24.192.36:4544 +com.capgemini.report.fsc.bootstrapURI=http://10.24.192.36:4544 diff --git a/teamcenter/src/test/resources/test_policy.xml b/teamcenter/src/test/resources/test_policy.xml new file mode 100644 index 0000000..5721f86 --- /dev/null +++ b/teamcenter/src/test/resources/test_policy.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/teamcenter/src/test/resources/xml/policies/PoliciesDomParserTest.xml b/teamcenter/src/test/resources/xml/policies/PoliciesDomParserTest.xml new file mode 100644 index 0000000..735c1ee --- /dev/null +++ b/teamcenter/src/test/resources/xml/policies/PoliciesDomParserTest.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/teamcenter/src/test/resources/xml/policies/bom_policy.xml b/teamcenter/src/test/resources/xml/policies/bom_policy.xml new file mode 100644 index 0000000..761b32a --- /dev/null +++ b/teamcenter/src/test/resources/xml/policies/bom_policy.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/teamcenter/src/test/resources/xml/policies/policy_full.xml b/teamcenter/src/test/resources/xml/policies/policy_full.xml new file mode 100644 index 0000000..ba90d89 --- /dev/null +++ b/teamcenter/src/test/resources/xml/policies/policy_full.xml @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/teamcenter/src/test/resources/xml/policies/policy_light.xml b/teamcenter/src/test/resources/xml/policies/policy_light.xml new file mode 100644 index 0000000..1354d8a --- /dev/null +++ b/teamcenter/src/test/resources/xml/policies/policy_light.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/teamcenter/src/test/resources/xml/policies/test_policy.xml b/teamcenter/src/test/resources/xml/policies/test_policy.xml new file mode 100644 index 0000000..6c3eadd --- /dev/null +++ b/teamcenter/src/test/resources/xml/policies/test_policy.xml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/teamcenter/src/test/resources/xml/ref/MultiStructureServiceCallerTest_item.xml b/teamcenter/src/test/resources/xml/ref/MultiStructureServiceCallerTest_item.xml new file mode 100644 index 0000000..330a174 --- /dev/null +++ b/teamcenter/src/test/resources/xml/ref/MultiStructureServiceCallerTest_item.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/teamcenter/src/test/resources/xml/ref/MultiStructureServiceCallerTest_item_revision.xml b/teamcenter/src/test/resources/xml/ref/MultiStructureServiceCallerTest_item_revision.xml new file mode 100644 index 0000000..7f03594 --- /dev/null +++ b/teamcenter/src/test/resources/xml/ref/MultiStructureServiceCallerTest_item_revision.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/teamcenter/src/test/resources/xml/ref/StructureServiceCallerTest_mono.xml b/teamcenter/src/test/resources/xml/ref/StructureServiceCallerTest_mono.xml new file mode 100644 index 0000000..173cb9c --- /dev/null +++ b/teamcenter/src/test/resources/xml/ref/StructureServiceCallerTest_mono.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + diff --git a/teamcenter/src/test/resources/xml/ref/StructureServiceCallerTest_multi.xml b/teamcenter/src/test/resources/xml/ref/StructureServiceCallerTest_multi.xml new file mode 100644 index 0000000..76289d3 --- /dev/null +++ b/teamcenter/src/test/resources/xml/ref/StructureServiceCallerTest_multi.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + diff --git a/teamcenter/src/test/resources/xml/ref/TripleStructureServiceCallerTest_item.xml b/teamcenter/src/test/resources/xml/ref/TripleStructureServiceCallerTest_item.xml new file mode 100644 index 0000000..7db0976 --- /dev/null +++ b/teamcenter/src/test/resources/xml/ref/TripleStructureServiceCallerTest_item.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + diff --git a/teamcenter/src/test/resources/xml/ref/TripleStructureServiceCallerTest_item_revision.xml b/teamcenter/src/test/resources/xml/ref/TripleStructureServiceCallerTest_item_revision.xml new file mode 100644 index 0000000..e69de29