initialize

This commit is contained in:
Pruefer
2025-06-06 09:15:13 +02:00
commit fa7c2730f1
5817 changed files with 1339670 additions and 0 deletions

View File

@@ -0,0 +1,241 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.application;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.itac.mes.datainterface.ConfigurationException;
import com.itac.mes.datainterface.annotations.AAutoHandler;
import com.itac.mes.datainterface.annotations.AInstantiationType;
import com.itac.mes.datainterface.annotations.InstantiationType;
import com.itac.mes.datainterface.data.AlarmEventResponse;
import com.itac.mes.datainterface.data.Duration;
import com.itac.mes.datainterface.data.E63FileUnit;
import com.itac.mes.datainterface.data.ReportResponse;
import com.itac.mes.datainterface.data.Toolbox;
import com.itac.mes.datainterface.factories.AConfigurableHandler;
import com.itac.mes.datainterface.filehandler.E63DirectoryHandler;
import com.itac.mes.datainterface.filehandler.Euromap63FileHandler;
import com.itac.mes.datainterface.parser.Euromap63Parser;
import com.itac.mes.datainterface.process.Euromap63Processor;
/**
*
* The application can run various commands. Every command is an own session.
*
* @author frankp
* @since 9.10.00
*/
@AInstantiationType(name = "euromap63", type = InstantiationType.APPLICATION)
public class E63Application extends AConfigurableHandler implements E63Receiver {
private static final String LOGGER = E63Application.class.getSimpleName();
/** set from configuration */
private Set<String> machineNames;
/** */
private List<E63ApplicationLayer> applicationLayers;
private Euromap63FileHandler fileHandler;
private Euromap63Parser parser;
private Duration dirPollingInterval;
@AAutoHandler(InstantiationType.TOOL)
private Toolbox toolbox;
private Euromap63Processor processor;
/**
* The application is responsible to subscribe for Report Data.
* <p>
* It is recommended to subscribe with mode "REWRITE" this means whenever new data is available a new File is written by the machine. <br>
* The report data should only be processed when a session is active, the machine is licensed, -..
*
* @param reportResponse
*/
@Override
public void processReportData(String machineName, ReportResponse reportResponse) {
try {
// Report filtern und parsen
E63FileUnit e63Unit = parser.parse(reportResponse, machineName);
// uploadUnti bauen
// verarbeiten (send)
// // backup file ...
} catch (E63ProcessException e) {
// TODO: handle exception
}
}
/**
* The application is rsponsible to process the received alarm responses.
*
* @param alarmEventResponse
*/
@Override
public void processAlarmResponse(String machineName, AlarmEventResponse alarmEventResponse) {
// parse responses
// create uploadUnit
// send to server
}
/**
* if no session is running and no session is about to be established try to start a new session
*/
public void start() {
// start all application layers...
for (E63ApplicationLayer e63ApplicationLayer : applicationLayers) {
e63ApplicationLayer.startSession();
}
}
/**
* @return
*/
private List<E63ApplicationLayer> getApplicationLayers() {
if (applicationLayers == null) {
applicationLayers = new ArrayList<>();
}
return applicationLayers;
}
/**
* @return
*/
private Set<String> getMachineNames() {
if (machineNames == null) {
machineNames = new HashSet<>();
}
return machineNames;
}
/**
* if a session is running or about to be established kill
*/
public void stop() {
// stop and kill all application Layers
for (E63ApplicationLayer applicationLayer : getApplicationLayers()) {
applicationLayer.stop();
}
}
/**
* @return
*/
public boolean isRunning() {
return false;
}
/**
* @param machineNames2
*/
public void setMachineNames(List<String> machineNames) {
// iterate over this machineName list and create a number of applicationLayers, one for each machineName
getMachineNames().addAll(machineNames);
}
public void initialize() throws ConfigurationException {
// create an own application layer for every configured machine
for (String machineName : machineNames) {
E63ApplicationLayer e63ApplicationLayer = new E63ApplicationLayer();
e63ApplicationLayer.setMachineName(machineName);
getApplicationLayers().add(e63ApplicationLayer);
}
// explicit called in order that machineNames and fileHandler both are set
for (E63ApplicationLayer e63ApplicationLayer : applicationLayers) {
// create directory handler for a machine and add it to the appLayer
E63DirectoryHandler e63DirectoryHandler = fileHandler.createDirectoryHandler(e63ApplicationLayer.getMachineName());
e63ApplicationLayer.setDirectoryHandler(e63DirectoryHandler);
e63ApplicationLayer.setMaxSession(fileHandler.getMaxSession());
e63ApplicationLayer.setSessionRetryInterval(fileHandler.getSessionRetryInterval());
// this could still throw ConfigurationException
e63ApplicationLayer.setDirectoryPollingInterval(dirPollingInterval);
// transfer parser settings
e63ApplicationLayer.setExecutionType(parser.getExecutionType());
e63ApplicationLayer.setExecutionInterval(parser.getExecutionInterval());
e63ApplicationLayer.setExecutionCounter(parser.getExecutionCounter());
e63ApplicationLayer.setReportParameter(parser.getReportParameter());
e63ApplicationLayer.setE63Receiver(this);
}
// configuration seems to be ok, ready to init now
for (E63ApplicationLayer e63ApplicationLayer : applicationLayers) {
// definieren der Jobs (Report, Alarms, Connect, etc)
e63ApplicationLayer.initSession();
e63ApplicationLayer.startSession();
}
}
/**
*
*/
public void startPause() {
for (E63ApplicationLayer applicationLayer : getApplicationLayers()) {
applicationLayer.startPause();
}
}
/**
*
*/
public void endPause() {
// every application layer represents the communication with one separate machine
// all those communications share the same settigns
for (E63ApplicationLayer applicationLayer : getApplicationLayers()) {
applicationLayer.endPause();
}
}
/**
* @param euromap63FileHandler
* @param sessionDirectory
* @param presentationDirectory
* @param applicationDirectory
*/
public void setFileHandler(Euromap63FileHandler euromap63FileHandler, String sessionDirectory, String presentationDirectory,
String applicationDirectory) {
this.fileHandler = euromap63FileHandler;
fileHandler.setSessionDirectory(sessionDirectory);
fileHandler.setPresentationDirectory(presentationDirectory);
fileHandler.setApplicationDirectory(applicationDirectory);
}
public void setParser(Euromap63Parser parser) {
this.parser = parser;
}
/**
* @param dirPollingInterval
*/
public void setPollingInterval(Duration dirPollingInterval) {
this.dirPollingInterval = dirPollingInterval;
}
/**
* @param euromap63Processor
*/
public void setProcessor(Euromap63Processor euromap63Processor) {
this.processor = euromap63Processor;
;
}
}

View File

@@ -0,0 +1,407 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.application;
import static com.itac.util.logging.LogLevel.DEBUG;
import static com.itac.util.logging.LogLevel.ERROR;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import com.itac.mes.datainterface.data.AlarmEventResponse;
import com.itac.mes.datainterface.data.Duration;
import com.itac.mes.datainterface.data.E63BaseRequest;
import com.itac.mes.datainterface.data.E63SessionState;
import com.itac.mes.datainterface.data.EventRequest;
import com.itac.mes.datainterface.data.ExecuteJobCommand;
import com.itac.mes.datainterface.data.ExecutionType;
import com.itac.mes.datainterface.data.JobRequest;
import com.itac.mes.datainterface.data.ReportFileMode;
import com.itac.mes.datainterface.data.ReportRequest;
import com.itac.mes.datainterface.data.ReportResponse;
import com.itac.mes.datainterface.filehandler.E63DirectoryType;
import com.itac.util.logging.LogHandler;
/**
*
* Complete Handling for one Application, including session handling etc.
*
* <p>
* start / stop session, cleanunp session,<br>
* evaluate presentatione files<br>
* evaluate application messages<br>
*
* @author frankp
* @since 9.10.00
*/
public class E63ApplicationLayer extends E63PresentationLayer {
private static final String LOGGER = E63ApplicationLayer.class.getSimpleName();
private E63Receiver e63Receiver;
private ExecutionType executionType;
private Duration executionInterval;
private int executionCounter;
private List<String> reportParameter;
private Thread applicationFileobserveThread;
private List<String> applicationFileObserveList;
private Map<String, E63BaseRequest> applicationRequests;
/**
*
*/
public void stop() {
stopSession();
}
/**
* The presentation layer detected the positive confirmation for the report job.<br>
* Now it's necessary to observe this file, move it to work, process and backup the file.
*
* <p>
* FileHandler function...
*
* @param fileSpec
*/
@Override
protected void startApplicationObserveFile(String fileSpec) {
LogHandler.log(LOGGER, DEBUG, "add file {0} to application list (from request in job...)", fileSpec);
getApplicationFileObserveList().add(fileSpec);
if (applicationFileobserveThread == null) {
applicationFileobserveThread = new Thread() {
@Override
public void run() {
while (getSessionState() == E63SessionState.RUNNING) {
try {
Thread.sleep(getDirPollingInterval().getMillies());
} catch (InterruptedException e) {
// ignore this
}
String[] directoryContent = getE63DirectoryHandler().listFiles(E63DirectoryType.APPLICATION);
if (directoryContent.length == 0) {
continue;
}
// add all fil e names to map
Set<String> fileNameSet = new HashSet<>();
fileNameSet.addAll(Arrays.asList(directoryContent));
checkObservableFiles(fileNameSet);
// remove job response file
// remove job request file
}
}
};
applicationFileobserveThread.start();
}
}
/**
* @param fileNameSet
*
*/
protected void checkObservableFiles(Set<String> fileNameSet) {
// check observable files...
for (String observableFileName : getObserveList()) {
// check if this file should be observed
if (fileNameSet.contains(observableFileName)) {
// yes, wait for this file...
LogHandler.log(LOGGER, DEBUG, "found application response file {0}", observableFileName);
try {
processApplicationResponse(observableFileName);
} catch (E63FileException e) {
LogHandler.log(LOGGER, DEBUG, "can not read presentation response file {0}; try to delete it", observableFileName);
}
}
}
}
/**
* @param observableFileName
* @throws E63FileException
*/
protected void processApplicationResponse(String observableFileName) throws E63FileException {
// read file
String fileContent = getFileContent(new File(getE63DirectoryHandler().getDirectory(E63DirectoryType.APPLICATION), observableFileName)).toString();
// create a response object
// move file to working directory
// process file:
// get the type from the request which generates this response
// AlarmEventResponse for a Event Request
// ReportResponse for a Report Request
E63BaseRequest k = getApplicationRequests().get(observableFileName);
if (k.getClass() == EventRequest.class) {
AlarmEventResponse alarmEventResponse = new AlarmEventResponse().setContent(fileContent);
newAlarmResponseAvailable(alarmEventResponse);
} else if (k.getClass() == ReportRequest.class) {
ReportResponse reportResponse = new ReportResponse().setContent(fileContent);
newReportResponseAvailable(reportResponse);
}
// post process File , move to backup directory
}
/**
* @return
*/
protected List<String> getApplicationFileObserveList() {
if (applicationFileObserveList == null) {
applicationFileObserveList = new ArrayList<>();
}
return applicationFileObserveList;
}
public void newAlarmResponseAvailable(AlarmEventResponse alarmEventResponse) {
getE63Receiver().processAlarmResponse(getMachineName(), alarmEventResponse);
}
public void newReportResponseAvailable(ReportResponse reportResponse) {
getE63Receiver().processReportData(getMachineName(), reportResponse);
}
/**
* @return
*/
private E63Receiver getE63Receiver() {
if (e63Receiver == null) {
e63Receiver = new E63Receiver() {};
}
return e63Receiver;
}
/**
*
*/
public void startPause() {
// no longer check for application layer files (neither reports nor alarms)
// CHECK how to continue application after pause
}
/**
*
*/
public void endPause() {
// CHECK how to pause application
}
@Override
public void onSessionConfirmed() {
LogHandler.log(LOGGER, DEBUG, "session confirmed, start job subscriptions now ");
// before session started define session to execute a job
// create a job request in presentation directory
// create a job file
createReportJob();
// create this job file in the presentation directory
// the preLayRespFile appears in the presentation directory
// New Job File
// JOB reportJob RESPONSE "jobResponse.log"
//
// define a report result file. the report application file will occur in the application directory.
// REPORT process REWRITE "reportApplicationFile"
// START IMMEDIATE
// STOP NEVER
// create a job for the alarms
// append this alarms to be executed in the session
// create the full qualified file name
createAlarmJob();
}
@Override
public void onSessionDenied() {
LogHandler.log(LOGGER, ERROR, "SESSION CONFIRMED WITH ERROR; NOT USABLE {0}");
}
/**
*
*/
private void createAlarmJob() {
LogHandler.log(LOGGER, DEBUG, "create a alarm job for machine {0}", getMachineName());
try {
ExecuteJobCommand jobCmd = new ExecuteJobCommand();
JobRequest alarmJobRequest = new JobRequest().setJobName("alarmJob");
jobCmd.setPresentationRequest(alarmJobRequest);
File directory = getE63DirectoryHandler().getDirectory(E63DirectoryType.PRESENTATION);
String resultFile = directory.getCanonicalPath() + File.separator + "alarmJobResponse.log";
alarmJobRequest.setFileSpec(resultFile);
StringBuilder alarmJobFileContent = new StringBuilder(alarmJobRequest.getRequestContent());
alarmJobFileContent.append("\n");
// Alarm reqeustss
EventRequest eventRequest = new EventRequest();
eventRequest.setEventName("alarmLog");
eventRequest.setEventType("ALARMS");
String reportResultFile = getE63DirectoryHandler().getDirectory(E63DirectoryType.APPLICATION).getCanonicalPath() + File.separator
+ "alarms.dat";
eventRequest.setFileSpec(reportResultFile);
eventRequest.setReportMode(ReportFileMode.REWRITE);
eventRequest.setStartSpec("IMMEDIATE");
eventRequest.setStopSpec("NEVER");
// all configured parameter
alarmJobFileContent.append(eventRequest.getRequestContent());
jobCmd.setApplicationRequest(eventRequest);
String jobFileName = "Alarms_" + UUID.randomUUID() + ".JOB";
jobCmd.setFileSpec(jobFileName);
scheduleJob(jobCmd);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
*
*/
private void createReportJob() {
LogHandler.log(LOGGER, DEBUG, "create a report job for machine {0}", getMachineName());
try {
ExecuteJobCommand cmd = new ExecuteJobCommand();
// create the full qualified file name
JobRequest jobRequest = new JobRequest().setJobName("reportJob");
File directory = getE63DirectoryHandler().getDirectory(E63DirectoryType.PRESENTATION);
String resultFile = directory.getCanonicalPath() + File.separator + "reportJobResponse.log";
jobRequest.setFileSpec(resultFile);
cmd.setPresentationRequest(jobRequest);
StringBuilder jobFileContent = new StringBuilder(jobRequest.getRequestContent());
jobFileContent.append("\n");
ReportRequest reportRequest = new ReportRequest();
reportRequest.setReportName("reportRequest");
String reportResultFile = getE63DirectoryHandler().getDirectory(E63DirectoryType.APPLICATION).getCanonicalPath() + File.separator
+ "reportResponse.dat";
reportRequest.setFileSpec(reportResultFile);
reportRequest.setReportMode(ReportFileMode.REWRITE);
reportRequest.setExecution(executionType, executionInterval, executionCounter);
reportRequest.setStartSpec("IMMEDIATE");
reportRequest.setStopSpec("NEVER");
// all configured parameter
for (String reportParam : reportParameter) {
reportRequest.addParameter(reportParam);
}
jobFileContent.append(reportRequest.getRequestContent());
cmd.setApplicationRequest(reportRequest);
String jobFileName = "Report_" + UUID.randomUUID() + ".JOB";
cmd.setFileSpec(jobFileName);
scheduleJob(cmd);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* @param cmd
*/
@Override
public void scheduleJob(ExecuteJobCommand cmd) {
LogHandler.log(LOGGER, DEBUG, "schedule job {0} for machine {1}", cmd.getFileSpec(), getMachineName());
super.scheduleJob(cmd);
// merken, mit welchen Parametern ein Job ausgeführt werden soll.
// oder besser den Report zu einem applicationResponseFile speichern!!!
LogHandler.log(LOGGER, DEBUG, "register job {0} for machine {1}", cmd.getFileSpec(), getMachineName());
getApplicationRequests().put(cmd.getApplicationRequest().getFileSpecFile().getName(), cmd.getApplicationRequest());
super.executeSessionCommand(cmd.getContent());
}
/**
* @return
*/
private Map<String, E63BaseRequest> getApplicationRequests() {
if (applicationRequests == null) {
applicationRequests = new HashMap<>();
}
return applicationRequests;
}
/**
* @param e63Application
*/
public void setE63Receiver(E63Receiver e63Receiver) {
this.e63Receiver = e63Receiver;
}
/**
* @param executionType
*/
public void setExecutionType(ExecutionType executionType) {
this.executionType = executionType;
}
/**
* @param executionInterval
*/
public void setExecutionInterval(Duration executionInterval) {
this.executionInterval = executionInterval;
}
/**
* @param executionCounter
*/
public void setExecutionCounter(int executionCounter) {
this.executionCounter = executionCounter;
}
/**
* @param parameter
*/
public void setReportParameter(List<String> reportParameter) {
this.reportParameter = reportParameter;
}
}

View File

@@ -0,0 +1,18 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.application;
/**
* @author frankp
* @since 9.10.00
*/
public interface E63Command {
public String getContent();
}

View File

@@ -0,0 +1,24 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.application;
/**
* @author frankp
* @since 9.10.00
*/
public class E63FileException extends Exception {
/**
* @param message
* @param e
*/
public E63FileException(String message, Exception e) {
super(message, e);
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.application;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.text.MessageFormat;
/**
* @author frankp
* @since 9.10.00
*/
public class E63FileLayer {
/**
* Getting the content of a file.
*
* @param file the file to be read
* @return
* @throws E63FileException
*/
protected StringBuilder getFileContent(File file) throws E63FileException {
StringBuilder filecontent = new StringBuilder();
try (FileReader fr = new FileReader(file);
BufferedReader f = new BufferedReader(fr);) {
String line;
while ((line = f.readLine()) != null) {
filecontent.append(line).append("\n");
}
} catch (Exception e) {
throw new E63FileException(MessageFormat.format("Error reading the file {0}", file.getName()), e);
}
return filecontent;
}
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.application;
/**
* @author frankp
* @since 9.10.00
*/
public class E63FormatException extends Exception {
/**
* @param string
*/
public E63FormatException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,289 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.application;
import static com.itac.util.logging.LogLevel.DEBUG;
import static com.itac.util.logging.LogLevel.ERROR;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.itac.mes.datainterface.data.E63PresentationResponseFile;
import com.itac.mes.datainterface.data.E63SessionState;
import com.itac.mes.datainterface.data.ExecuteJobCommand;
import com.itac.mes.datainterface.data.PresentationResponse;
import com.itac.mes.datainterface.filehandler.E63DirectoryType;
import com.itac.util.logging.LogHandler;
/**
* @author frankp
* @since 9.10.00
*/
public class E63PresentationLayer extends E63SessionLayer {
private static final String LOGGER = E63PresentationLayer.class.getSimpleName();
public String getPresentationError(int code) {
switch (code) {
case 0:
return "NO error.";
case 1:
case 2:
return "Reserved.";
case 3:
return "Too many active JOBS.";
case 4:
return "Unable to create/open destination file.";
case 5:
return "Invalid REPORT command syntax.";
case 6:
return "Unknown REPORT parameter.";
case 7:
return "Too many active REPORTS.";
case 8:
return "Invalid EVENT command syntax.";
case 9:
return "Too many active EVENTS.";
case 10:
return "Unknown EVENT token.";
case 11:
return "Invalid ABORT command syntax.";
case 12:
return "Invalid UPLOAD command syntax.";
case 13:
return "Unable to create/open UPLOAD destination directory/file.";
case 14:
return "Invalid DOWNLOAD command syntax.";
case 15:
return "Unable to open DOWNLOAD source directory/file.";
case 16:
return "DOWNLOAD operation denied.";
case 17:
return "Invalid GETINFO command syntax.";
case 18:
return "Invalid GETID command syntax.";
case 19:
return "Invalid SET command syntax.";
case 20:
return "SET operation of parameter denied.";
case 21:
return "SET value out of range.";
case 22:
return "Unknown SET parameter.";
case 23:
return "Unsupported command.";
case 24:
return "Invalid START parameter syntax.";
case 25:
return "Invalid STOP parameter syntax.";
case 26:
return "Application parameter or constant parameter to long.";
case 27:
return "Invalid numeric format.";
case 28:
return "Invalid comparison operator.";
case 29:
return "Invalid time format.";
case 30:
return "Invalid date format.";
case 31:
return "End of command expected.";
case 32:
return "Unknown error.";
case 33:
return "REPORT with the same name and type is already running.";
case 34:
return "EVENT with the same name and type is already running.";
case 35:
return "DOWNLOAD is already running.";
case 36:
return "The specified command to abort, is not active.";
case 37:
return "Error during command processing.";
default:
// 00000038 -
// 00009999
// reserved
// 00010000 -
// 99999999
// Open for manufacture specific error codes
break;
}
return "";
}
private Thread observeThread;
private List<String> fileObserveList;
private Map<String, ExecuteJobCommand> jobMap;
/**
* Scheduling a job at presentation layer means that a presentation or application request file is written and a presentation response file is
* defined.<br>
*
*
*
* @param cmd
* the job to be scheduled
*
*/
public void scheduleJob(ExecuteJobCommand cmd) {
try {
// create the job request file
getE63DirectoryHandler().writeFile(E63DirectoryType.PRESENTATION, cmd.getFileSpecFile().getName(), cmd.getContent());
// append this job to the session
executeSessionCommand(cmd.getContent());
// create observer for presenetation layer response file
startObservePresentationFile(cmd.getPresentationRequest().getFileSpecFile().getName());
// add the job to the map; key is the name of the presentation response file
getJobMap().put(cmd.getPresentationRequest().getFileSpecFile().getName(), cmd);
} catch (FileNotFoundException e) {
LogHandler.log(LOGGER, ERROR, "failed to create the file {0}", cmd.getFileSpecFile().getName());
}
}
/**
* @return
*/
private Map<String, ExecuteJobCommand> getJobMap() {
if (jobMap == null) {
jobMap = new HashMap<>();
}
return jobMap;
}
/**
* @param fileSpec
*/
protected void startObservePresentationFile(String fileSpec) {
LogHandler.log(LOGGER, DEBUG, "add file {0} to presentation observe list (from request in job...)", fileSpec);
getObserveList().add(fileSpec);
if (observeThread == null) {
observeThread = new Thread() {
@Override
public void run() {
while (getSessionState() == E63SessionState.RUNNING) {
try {
Thread.sleep(getDirPollingInterval().getMillies());
} catch (InterruptedException e) {
// ignore this
}
String[] directoryContent = getE63DirectoryHandler().listFiles(E63DirectoryType.PRESENTATION);
if (directoryContent.length == 0) {
continue;
}
// afdd all fil e names to map
Set<String> fileNameSet = new HashSet<>();
for (String fileName : directoryContent) {
fileNameSet.add(fileName);
}
// check observable files...
for (String observableFileName : getObserveList()) {
// check if this file should be observed
if (fileNameSet.contains(observableFileName)) {
// yes, wait for this file...
LogHandler.log(LOGGER, DEBUG, "found presentation response file {0}", observableFileName);
try {
processPresentationResponse(observableFileName);
} catch (E63FileException | E63FormatException e) {
LogHandler.log(LOGGER, DEBUG, "can not read presentation response file {0}; try to delete it", observableFileName);
if (!new File(getE63DirectoryHandler().getDirectory(E63DirectoryType.PRESENTATION), observableFileName).delete()) {
LogHandler.log(LOGGER, DEBUG, "presentation response file {0}not deleted", observableFileName);
}
}
}
}
// remove job response file
// remove job request file
}
}
};
observeThread.start();
}
}
/**
* @param observableFileName
* @throws E63FileException
* @throws E63FormatException
*/
protected void processPresentationResponse(String observableFileName) throws E63FileException, E63FormatException {
File observableFile = new File(getE63DirectoryHandler().getDirectory(E63DirectoryType.PRESENTATION), observableFileName);
StringBuilder observableFilecontent = getFileContent(observableFile);
try {
PresentationResponse presentationResponse = new PresentationResponse(observableFilecontent.toString());
LogHandler.log(LOGGER, DEBUG, "presentation response code = {0}", presentationResponse.getResult());
} catch (Exception e) {
LogHandler.log(LOGGER, ERROR, "presentation file not read properly", e);
}
// rename observable file (rename the presentation response file in order to process it only once)
try {
if (!observableFile.renameTo(new File(observableFile.getCanonicalFile() + ".prc"))) {
LogHandler.log(LOGGER, DEBUG, "file not renamed from {0} to {0}", observableFile.getCanonicalFile());
}
} catch (IOException e) {
LogHandler.log(LOGGER, ERROR, "problem renaming file from.. to ..{0}", observableFile, e);
}
ExecuteJobCommand execJobCommand = getJobMap().get(observableFileName);
startApplicationObserveFile(execJobCommand.getApplicationRequest().getFileSpec());
}
/**
* @param fileSpec
*/
protected void startApplicationObserveFile(String fileSpec) {
// should be overridden by application layer
}
/**
* @return
*/
protected List<String> getObserveList() {
if (fileObserveList == null) {
fileObserveList = new ArrayList<>();
}
return fileObserveList;
}
public void onPresentationResponse(E63PresentationResponseFile rpl) {
// wenn ein Response eingeht (mit OK ) für einen jobRequest dann das entsprechende Job-Command suchen
// warten bis das report-Result-File da ist
// Report result auswerten! und report result löschen
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.application;
import java.text.MessageFormat;
/**
* @author frankp
* @since 9.10.00
*/
public class E63ProcessException extends Exception {
/**
* @param message
* @param machineName
*/
public E63ProcessException(String message, String machineName) {
super(MessageFormat.format(message, machineName));
}
/**
* @param message
*/
public E63ProcessException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.application;
import com.itac.mes.datainterface.data.AlarmEventResponse;
import com.itac.mes.datainterface.data.ReportResponse;
/**
* @author frankp
* @since 9.10.00
*/
public interface E63Receiver {
public default void processReportData(String machineName, ReportResponse reportResponse) {}
/**
* The application is rsponsible to process the received alarm responses.
*
* @param alarmEventResponse
*/
public default void processAlarmResponse(String machineName, AlarmEventResponse alarmEventResponse) {}
}

View File

@@ -0,0 +1,469 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.application;
import static com.itac.util.logging.LogLevel.DEBUG;
import static com.itac.util.logging.LogLevel.ERROR;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.Thread.State;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import com.itac.mes.datainterface.annotations.AInit;
import com.itac.mes.datainterface.data.ConnectSessionCommand;
import com.itac.mes.datainterface.data.Duration;
import com.itac.mes.datainterface.data.E63ResponseCode;
import com.itac.mes.datainterface.data.E63SessionResponseFile;
import com.itac.mes.datainterface.data.E63SessionState;
import com.itac.mes.datainterface.data.SessionRequest;
import com.itac.mes.datainterface.data.SessionResponse;
import com.itac.mes.datainterface.filehandler.E63DirectoryHandler;
import com.itac.mes.datainterface.filehandler.E63DirectoryType;
import com.itac.util.logging.LogHandler;
/**
*
* Starts session, writes files and observes directory for session responses, evaluate response files
*
* @author frankp
* @since 9.10.00
*/
public class E63SessionLayer extends E63FileLayer {
private static final String LOGGER = E63SessionLayer.class.getSimpleName();
private E63SessionState sessionState = E63SessionState.INIT;
private int maxSession; // value from file handler configuration
private String[] requestSessionFiles;
private String machineName;
private E63DirectoryHandler e63DirectoryHandler;
protected File sessionRequestFile;
private AtomicInteger commandNumber = new AtomicInteger(0);
private File sessionResponseFile;
private long sessionResponsefileSize;
private Thread waitForSessionResponse;
public String getMachineName() {
return machineName;
}
public void setMachineName(String machineName) {
this.machineName = machineName;
}
/**
* @param observer
*/
public void setDirectoryHandler(E63DirectoryHandler e63DirectoryHandler) {
// can create files in sessiondir, presentationDir, applicationDir
this.e63DirectoryHandler = e63DirectoryHandler;
}
public E63DirectoryHandler getE63DirectoryHandler() {
return e63DirectoryHandler;
}
// from requesting a session to get any response the maximum time is this.
// if the time is expiring the session request is
// private Duration sessionResponseTimePeriod
private Thread sessionEstablishThread;
private Duration sessionRetryInterval;
protected SessionRequest sessionRequest;
protected Thread sessionResponseObserveThread;
private Duration dirPollingInterval;
/**
* Ths limits the number of max Sessions, fro configuration, value is in Range 0..9999
*
* @param maxSession
*/
public void setMaxSession(int maxSession) {
this.maxSession = maxSession;
}
/**
* Setting the names of all files (requests ansd responses) in this directory .<br>
* All responses are filtered, only requests remain and will be kept for further processing
*
* @param sessionFileNames
* a sorted or unsorted array with all file names
*/
public void setSessionFileNames(String[] sessionFileNames) {
List<String> sessionFileList = new ArrayList<>();
for (String n : sessionFileNames) {
if (n.endsWith(".REQ")) {
sessionFileList.add(n);
}
}
// keep all request file names
this.requestSessionFiles = sessionFileList.toArray(new String[sessionFileList.size()]);
}
/**
* The directory consists of a number of session request files. The minimum Session number is 0, the maximum session number is {@link #maxSession}
* -1;
*
* @return the next free session number or -1 if no free session number is available.
*/
public int getNextSessionNumber() {
// find a unused session id < the max number
String[] names = getRequestSessionFiles();
Arrays.sort(names);
for (int i = 0; i < maxSession; i++) {
if (i >= names.length) {
return i;
}
int fileNumber = SessionRequest.getRequestNumber(names[i]);
if (i < fileNumber) {
return i;
}
}
return -1;
}
/**
* Get the names for all session files
*
* @return all request session file names read by directory handler
*/
private String[] getRequestSessionFiles() {
if (requestSessionFiles == null) {
requestSessionFiles = new String[0];
}
return requestSessionFiles;
}
@AInit
public void initSession() {
setState(E63SessionState.STOPPED);
}
/**
* sets the new state and logs the state transition
*
* @param newState
*/
public void setState(E63SessionState newState) {
if (sessionState == newState) {
return;
}
LogHandler.log(LOGGER, DEBUG, "changed session state for machine {0} from {1} to {2}", getMachineName(), sessionState, newState);
sessionState = newState;
}
public void startSession() {
if (sessionState != E63SessionState.STOPPED) {
LogHandler.log(LOGGER, DEBUG, "session for machine {0} is in wrong state {1}", getMachineName(), sessionState);
return;
}
// start initiating a new session
setState(E63SessionState.ESTABLISHING);
sessionEstablishThread = createSessionEstablishThread();
sessionEstablishThread.start();
}
/**
* @return
*/
private Thread createSessionEstablishThread() {
return new Thread("establishSession_" + getMachineName()) {
@Override
public void run() {
LogHandler.log(LOGGER, DEBUG, "started establishing thread {1}", getMachineName());
int nextSession = -1;
do {
// do this in a loop as long as no new or free session number is available
LogHandler.log(LOGGER, DEBUG, "find session number for machine {0}", getMachineName());
// restrict to session request files "*.REQ"
setSessionFileNames(e63DirectoryHandler.listFiles(E63DirectoryType.SESSION));
nextSession = getNextSessionNumber();
if (nextSession >= 0) {
LogHandler.log(LOGGER, DEBUG, "found free session number {0} for machine {1}", nextSession, getMachineName());
createSessionRequest(nextSession, getMachineName());
} else {
LogHandler.log(LOGGER, DEBUG, "no free session number found for machine {0}", getMachineName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// ignore sleep exceptions
}
}
} while (nextSession == -1 && sessionState == E63SessionState.ESTABLISHING);
if (sessionState == E63SessionState.ESTABLISHING) {
waitForSessionResponse = getWaitForSessionResponseThread();
waitForSessionResponse.start();
}
}
};
}
/**
* @param nextSession
* @param fileName
* @param machineName2
*/
protected void createSessionRequest(int nextSession, String machineName) {
sessionRequest = new SessionRequest();
sessionRequest.setSessionNumber(nextSession);
try {
LogHandler.log(LOGGER, DEBUG, "create session file {0} for machine {1}", sessionRequest.getFileName(), machineName);
sessionRequestFile = e63DirectoryHandler.writeFile(E63DirectoryType.SESSION, sessionRequest.getFileName(), sessionRequest.getFileContent());
// start session connect
String commandId = executeSessionCommand(new ConnectSessionCommand().getContent());
if (commandId == null) {// not executed
stopSession();
}
sessionResponseFile = new File(e63DirectoryHandler.getDirectory(E63DirectoryType.SESSION), sessionRequest.getFileName().replace(".REQ", ".RSP"));
} catch (FileNotFoundException e) {
// CHECK improve logging
LogHandler.log(LOGGER, DEBUG, "creating session for {0} failed", sessionRequest.getFileName(), e);
}
}
protected Thread getWaitForSessionResponseThread() {
return new Thread("WaitForSessionResponse_" + getMachineName() + "_" + sessionRequest.getSessionNumber()) {
@Override
public void run() {
LogHandler.log(LOGGER, DEBUG, "start wait for session response file {0}", sessionResponseFile.getName());
while (sessionState == E63SessionState.ESTABLISHING) {
try {
Thread.sleep(getDirPollingInterval().getMillies());
} catch (InterruptedException e) {
// ignore sleep exceptions
}
// check for existance of response file
if (sessionResponseFile.exists()) {
setState(E63SessionState.RUNNING);
}
}
if (sessionState == E63SessionState.RUNNING) {
// session was at least confirmed, foudn a sessxxxx.rsp file
try {
startConfirmSession();
} catch (E63FileException e) {
LogHandler.log(LOGGER, ERROR, "session confirmation not processed properly", e);
}
}
}
};
}
/**
* @throws E63FileException
*/
protected void startConfirmSession() throws E63FileException {
try {
LogHandler.log(LOGGER, DEBUG, "session response file {0} found, session is confirmed", sessionResponseFile.getName());
E63SessionResponseFile sr = new E63SessionResponseFile().setContent(sessionResponseFile.getName(), getFileContent(sessionResponseFile)
.toString());
// evaluate sr (session response) for the session Request command identifier
SessionResponse sessionResponse = sr.getResponses().get(sessionRequest.getSessionCommandIdentifier());
LogHandler.log(LOGGER, DEBUG, "session request command id {0} confirmed with {1}", sessionRequest.getSessionCommandIdentifier(), sessionResponse
.getProcessedState());
if (sessionResponse.getProcessedState() == E63ResponseCode.PROCESSED) {
sessionResponseObserveThread = getObserveSessionResponseFileThread();
sessionResponseObserveThread.start();
sessionResponsefileSize = sessionResponseFile.length();
// calls at application layer!!!
onSessionConfirmed();
} else {
// Session connect confirmed with error, stop datasource
onSessionDenied();
}
} catch (E63FormatException e) {
// CHECK WHAT to do when session command file could not be parserd = --> praobably stop session
LogHandler.log(LOGGER, ERROR, "unable to parse session response file {0}", sessionResponseFile.getName(), e);
}
}
public void onSessionConfirmed() {
LogHandler.log(LOGGER, DEBUG, "session confirmed, start job subscriptions now ");
}
public void onSessionDenied() {
LogHandler.log(LOGGER, ERROR, "SESSION CONFIRMED WITH ERROR; NOT USABLE {0}", sessionResponseFile.getName());
}
protected Thread getObserveSessionResponseFileThread() {
return new Thread("ObserverSession_" + getMachineName() + "_" + sessionRequest.getSessionNumber()) {
@Override
public void run() {
LogHandler.log(LOGGER, DEBUG, "observe session response file {0}", sessionResponseFile.getName());
while (sessionState == E63SessionState.RUNNING) {
try {
Thread.sleep(dirPollingInterval.getMillies());
} catch (InterruptedException e) {
// ignore this InterruptedException
}
if (!sessionResponseFile.exists()) {
// CHECK: wenn viele Zyklen das File nicht mehr existiert Fehler melden
continue;
}
try {
long newFileSize = sessionResponseFile.length();
if (newFileSize != sessionResponsefileSize) {
sessionResponsefileSize = newFileSize;
setNewSessionResponseFile(getSessionResponse());
}
} catch (E63FormatException | E63FileException e) {
LogHandler.log(LOGGER, ERROR, MessageFormat.format("failed to set session response file {0}", sessionResponseFile.getName()), e);
}
}
}
};
}
/**
* @param sessionResponseFile
* @throws E63FormatException
*/
protected void setNewSessionResponseFile(E63SessionResponseFile sessionResponseFile) throws E63FormatException {
LogHandler.log(LOGGER, DEBUG, "detected change of session response file {0}", sessionResponseFile.getFileSpec());
// zuordnen der Ergebnisse zu den Requests !!!
}
private E63SessionResponseFile getSessionResponse() throws E63FormatException, E63FileException {
StringBuilder filecontent = getFileContent(sessionResponseFile);
// apply content to the E63 Response File
return new E63SessionResponseFile().setContent(sessionResponseFile.getName(), filecontent.toString());
}
/**
* Open the session request file for writing and append a new line with the content of the command
*
* @param content
* @return
*/
protected String executeSessionCommand(String content) {
// get a new session Command identifier
if (sessionRequestFile == null) {
return "";
}
LogHandler.log(LOGGER, DEBUG, "session {0} execute command {1}", sessionRequest.getSessionNumber(), content);
String sessionCommandIdentifier = MessageFormat.format("{0,number,00000000} {1};\n", commandNumber.getAndIncrement(), content);
// write to file with append-mode
try (BufferedWriter logWriter = new BufferedWriter(new FileWriter(sessionRequestFile, true))) {
logWriter.write(sessionCommandIdentifier);
logWriter.flush();
} catch (IOException e) {
LogHandler.log(LOGGER, ERROR, "Writing command {0} to sessionRequest file {1} failed, command not executed", sessionRequest.getSessionNumber(),
content, e);
return null;
}
return sessionCommandIdentifier;
}
public void stopSession() {
switch (sessionState) {
case STOPPED:
setState(E63SessionState.FINISHED);
break;
case RUNNING:
setState(E63SessionState.STOPPING);
break;
case ESTABLISHING:
// stop establishing thread and wait until thread has ended
setState(E63SessionState.STOPPING);
while (sessionEstablishThread.getState() != State.TERMINATED) {
try {
Thread.sleep(getDirPollingInterval().getMillies());
} catch (InterruptedException e) {
// ignore thread interrupt exception
}
}
// kill definitively
sessionEstablishThread = null;
e63DirectoryHandler.deleteSessionRequestFile();
// if req. File exists kill request file
break;
default:
break;
}
}
/**
*
*/
protected boolean checkSession() {
return false;
}
/**
* @param sessionRetryInterval
*/
public void setSessionRetryInterval(Duration sessionRetryInterval) {
this.sessionRetryInterval = sessionRetryInterval;
}
/**
* @param dirPollingInterval
*/
public void setDirectoryPollingInterval(Duration dirPollingInterval) {
this.dirPollingInterval = dirPollingInterval;
}
protected Duration getDirPollingInterval() {
return dirPollingInterval;
}
public E63SessionState getSessionState() {
return sessionState;
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
/**
* <code>
{{base EVENT response} LD {alarm_set} LD {alarm_number} LD {alarm_text} EOL} ...
</code>
*
* @author frankp
* @since 9.10.00
*
*/
public class AlarmEventRecord extends BaseEventRecord {
private int alarmSet;
private int alarmNumber;
private String alarmText;
/**
* @param line
* @return
*/
@Override
public AlarmEventRecord setContent(String line) {
setItems(line.split("\\,"));
return this;
}
/**
* @param split
*/
@Override
protected void setItems(String[] items) {
super.setItems(items);
this.alarmSet = Integer.parseInt(items[4]);
this.alarmNumber = Integer.parseInt(items[5]);
// TODO check variant:
// text limited with \"
this.alarmText = items[6];
}
public int getAlarmSet() {
return alarmSet;
}
public int getAlarmNumber() {
return alarmNumber;
}
public String getAlarmText() {
return alarmText == null ? "" : alarmText;
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import java.util.ArrayList;
import java.util.List;
/**
* <code>
{{base EVENT response} LD {alarm_set} LD {alarm_number} LD {alarm_text} EOL} ...
</code>
*
* @author frankp
* @since 9.10.00
*
*/
public class AlarmEventResponse {
List<BaseEventRecord> eventRecords;
public AlarmEventResponse setContent(String fileContent) {
String[] lines = fileContent.split("\\n");
for (String sLine : lines) {
BaseEventRecord evtRec = new AlarmEventRecord();
evtRec.setContent(sLine);
getEventRecords().add(evtRec);
}
return this;
}
public List<BaseEventRecord> getEventRecords() {
if (eventRecords == null) {
eventRecords = new ArrayList<>();
}
return eventRecords;
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author frankp
* @since 9.10.00
*/
public abstract class BaseEventRecord {
private int uniqueNumber;
private String date;
private String time;
private int cycleCounter;
/**
* @return
*/
public Date getDate() {
String dateTime = date + time;
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHH:mm:ss");
try {
return sdf.parse(dateTime);
} catch (ParseException e) {
return new Date(0);
}
}
/**
* @param line
* @return
*/
public BaseEventRecord setContent(String line) {
setItems(line.split("\\,"));
return this;
}
/**
* @param split
*/
protected void setItems(String[] items) {
this.uniqueNumber = Integer.parseInt(items[0].trim());
this.date = items[1].trim();
this.time = items[2].trim();
this.cycleCounter = Integer.parseInt(items[3].trim());
}
public int getUniqueNumber() {
return uniqueNumber;
}
public int getCycleCounter() {
return cycleCounter;
}
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import com.itac.mes.datainterface.application.E63Command;
/**
* @author frankp
* @since 9.10.00
*/
public class ConnectSessionCommand implements E63Command {
@Override
public String getContent() {
return "CONNECT";
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import java.io.File;
import com.itac.mes.datainterface.application.E63FormatException;
/**
* @author frankp
* @since 9.10.00
*/
public class E63BaseRequest {
private String fileName;
// define the output file Name for this report
public void setFileSpec(String fileName) throws E63FormatException {
if (fileName == null) {
throw new E63FormatException("It is not allowed to set null as a fileName");
}
if (fileName.trim().startsWith("\"") ) {
int endIndex = fileName.indexOf("\"", 2);
if (endIndex == -1) {endIndex = fileName.length();}
this.fileName = fileName.substring(1, endIndex);
} else {
this.fileName = fileName;
}
}
public String getFileSpec() throws E63FormatException {
if (fileName == null) {
throw new E63FormatException("filename is not set");
}
return "\"" + fileName + "\"";
}
public File getFileSpecFile() {
return new File(fileName);
}
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import java.util.ArrayList;
/**
*
* @author frankp
* @since 9.10
*/
public class E63FileUnit extends FileUnit {
public E63FileUnit() {
super();
processResultList = new ArrayList<ProcessResult>();
uploadUnitList = new ArrayList<BasicUploadUnit>();
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import java.util.ArrayList;
import java.util.List;
import com.itac.mes.datainterface.application.E63FormatException;
/**
* Description of a Presentation Layer Response File
* <p>
* available variants :<br>
* 1. COMMAND {n} PROCESSED {command response} {date_spec} {time_spec} ;<br>
* 2. COMMAND {n} ERROR {class} {xxxxxx} {errorDescription} {date_spec} {time_spec};<br>
*
* @author frankp
* @since 9.10.00
*/
public class E63PresentationResponseFile extends E63BaseRequest {
private List<PresentationResponse> responses;
public void set(String fileName, String content) throws E63FormatException {
super.setFileSpec(fileName);
setFileContent(content);
}
/**
* @param content
*/
private void setFileContent(String content) {
if (content == null || content.isEmpty()) {
return;
}
// split content by line delimiter ;_
// create an extra item per line
String[] lines = content.split("\\;");
for (String line : lines) {
getResponses().add(new PresentationResponse(line));
}
}
/**
* @return
*/
public List<PresentationResponse> getResponses() {
if (responses == null) {
responses = new ArrayList<>();
}
return responses;
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
/**
* @author frankp
* @since 9.10.00
*
*/
public enum E63ResponseCode {
PROCESSED("PROCESSED"),
ERROR("ERROR"),
UNDEFINED("undef");
private String key;
private E63ResponseCode(String key) {
this.key = key;
}
public String key() {
return key;
}
public static E63ResponseCode forKey(String keyValue) {
for (E63ResponseCode code : E63ResponseCode.values()) {
if (code.key().equalsIgnoreCase(keyValue)) {
return code;
}
}
return E63ResponseCode.UNDEFINED;
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import java.util.HashMap;
import java.util.Map;
import com.itac.mes.datainterface.application.E63FormatException;
/**
* Base for a request file.
* <p>
* A request file could contain a sequence of commands with parameters
*
* @author frankp
* @since 9.10.00
*
*/
public class E63SessionResponseFile extends E63BaseRequest {
private Map<Integer, SessionResponse> responses;
private int sessionNumber;
public E63SessionResponseFile setContent(String fileName, String content) throws E63FormatException {
// analyze file name
if (fileName == null || fileName.isEmpty()) {
throw new E63FormatException("filename for session file is invalid");
}
// analyze file Name
try {
String sNumber = fileName.substring(4, 8);
setSessionNumber(Integer.parseInt(sNumber));
} catch (Exception e) {
throw new E63FormatException("filename for session file is invalid");
}
if (content == null || content.isEmpty()) {
return this;
}
// split by lines..
String[] lines = content.split("\\n");
for (String line : lines) {
SessionResponse sr = new SessionResponse().setContent(line);
getResponses().put(sr.getSessionCommandIdentifier(), sr);
}
return this;
}
/**
* @param parseInt
*/
public void setSessionNumber(int sessionNumber) {
this.sessionNumber = sessionNumber;
}
public int getSessionNumber() {
return sessionNumber;
}
/**
* @return
*/
public Map<Integer, SessionResponse> getResponses() {
if (responses == null) {
responses = new HashMap<>();
}
return responses;
}
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
/**
* @author frankp
* @since 9.10.00
*/
public enum E63SessionState {
INIT,
STOPPED,
ESTABLISHING,
RUNNING,
CLOSING,
STOPPING,
FINISHED
}

View File

@@ -0,0 +1,153 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import com.itac.mes.datainterface.application.E63FormatException;
/**
* <code>
EVENT {name} {type} [APPEND | REWRITE] {fspec} {start_spec} {stop_spec};
EVENT The keyword EVENT indicating the start of the Event Log
request.
name The name of the event. This VSTRING(16) parameter (without
quotation marks) is used to identify the event. The event name
must be unique from that of any other active event at the
responder station.
type A token which specifies the type of event to log. The actual
event types are specified at the application layer.
APPEND The optional keyword APPEND. If specified, the event data is
appended to the end of any existing event file. If omitted, any
existing event file is deleted.
REWRITE The optional keyword REWRITE. If specified, any existing
report data is overwritten with new data each cycle or time
period. If omitted, all new data is added to the end of the report.
Note that this option is not valid with the APPEND option.
fspec A network file specification which specifies the event file. All
reported information is written to this file.
start_spec A valid START specification clause used to indicate when event
data generation will be started.
stop_spec A valid STOP specification clause used to indicate when event
data generation will be stopped.
</code>
*
*
* @author frankp
* @since 9.10.00
*/
public class EventRequest extends E63BaseRequest {
private String eventName;
private ReportFileMode reportMode = ReportFileMode.REWRITE;
private String startSpec;
private String stopSpec;
private String eventType = "ALARMS";
// specify a name for the report; automatically create with a timestamp, max 16 chrs
public void setEventName(String eventName) {
this.eventName = eventName;
}
/**
* from spec page 39 <code>
APPEND The optional keyword APPEND. If specified, the report data is
appended to the end of any existing report file. If omitted, any
existing report file is deleted. Note that this option is not valid
with the REWRITE option. If the response was deleted by the
host, the header line has to written again.
REWRITE The optional keyword REWRITE. If specified, any existing
report data is overwritten with new data each cycle or time
period. If omitted, all new data is added to the end of the report.
Note that this option is not valid with the APPEND option.
</code>
*/
public void setReportMode(ReportFileMode reportMode) {
this.reportMode = reportMode;
}
/**
* setting the event Type. If not set the default value is eventType
*
* @param eventType
* default is ALARMS
*/
public void setEventType(String eventType) {
this.eventType = eventType;
}
/**
* currently not used <code>
start_spec A valid START specification clause used to indicate when report
data generation will be started.
</code> default is START IMMEDIATE
*/
public void setStartSpec(String startSpec) {
this.startSpec = startSpec;
}
/**
* currently not used <code>
stop_spec A valid STOP specification clause used to indicate when report
data generation will be stopped.
</code> default is STOP NEVER
*/
public void setStopSpec(String stopSpec) {
this.stopSpec = stopSpec;
}
// a content as defined in the specification
public String getRequestContent() throws E63FormatException {
if (eventName == null) {
throw new E63FormatException("can not generate event request without Name");
}
if (getFileSpec() == null) {
throw new E63FormatException("can not generate event request without Filename");
}
StringBuilder stb = new StringBuilder();
stb.append("EVENT ");
stb.append(eventName);
stb.append(' ');
stb.append(eventType);
switch (reportMode) {
case APPEND:
stb.append(" APPEND ");
stb.append(getFileSpec());
break;
case REWRITE:
stb.append(" REWRITE ");
stb.append(getFileSpec());
break;
default:
throw new E63FormatException("Undefined report mode ");
}
stb.append(" START ");
stb.append(getStartSpec());
stb.append(" STOP ");
stb.append(getStopSpec());
stb.append(';');
return stb.toString();
}
/**
* @return
*/
private String getStartSpec() {
return startSpec == null ? "IMMEDIATE" : startSpec;
}
private String getStopSpec() {
return stopSpec == null ? "NEVER" : stopSpec;
}
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import java.io.File;
import java.text.MessageFormat;
import com.itac.mes.datainterface.application.E63Command;
/**
* @author frankp
* @since 9.10.00
*
*/
public class ExecuteJobCommand implements E63Command {
private String fileSpec;
private E63BaseRequest presentationRequest;
private E63BaseRequest applicationRequest;
/**
* @param fileSpec
* the applications job file name to be executed; do not need to put apos around
*/
public void setFileSpec(String fileName) {
if (fileName.startsWith("\"") && fileName.endsWith("\"")) {
this.fileSpec = fileName.substring(1, fileName.length() - 2);
} else {
this.fileSpec = fileName;
}
}
public String getFileSpec() {
return "\"" + fileSpec + "\"";
}
public File getFileSpecFile() {
return new File(fileSpec);
}
@Override
public String getContent() {
return MessageFormat.format("EXECUTE {0}", fileSpec);
}
/**
* @param jobRequest
*/
public void setPresentationRequest(E63BaseRequest presentationRequest) {
this.presentationRequest = presentationRequest;
}
public E63BaseRequest getPresentationRequest() {
return presentationRequest;
}
/**
* @param reportRequest
*/
public void setApplicationRequest(E63BaseRequest applicationRequest) {
this.applicationRequest = applicationRequest;
}
public E63BaseRequest getApplicationRequest() {
return applicationRequest;
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
/**
* For the configuration: define how a report should be generated
*
* @author frankp
* @since 9.10.00
*/
public enum ExecutionType {
OFF("off"),
CYCLIC("cyclic execution"),
COUNTER("execution after shots");
private String text;
private ExecutionType(String text) {
this.text = text;
}
public String text() {
return text;
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
/**
* @author frankp
* @since 9.10.00
*/
public enum FunctionToken {
INJ("Inj", "Injection", "Injection function."),
EJE("Eje", "Ejector", "Ejector function."),
MLD("Mld", "Mold", "Mold function."),
CLP("Clp", "Clamp", "Clamping unit function."),
BRL("Brl", "Barrel", "Barrel function."),
PLST("Plst", "Plasticise", "Plasticise or Recovery function."),
SCR("Scr", "Screw", "Screw function."),
XFR("Xfr", "Transfer", "Transfer, Switch Over, or Cut-off function."),
CAV("Cav", "Cavity", "Cavity function."),
HLD("Hld", "Hold", "Hold function."),
CSH("Csh", "Cushion", "Cushion function."),
DCMP("Dcmp", "Decompress", "Decompress function."),
MACH("Mach", "Machine", "Machine or System function."),
CYC("Cyc", "Cycle", "Cycle function."),
PRT("Prt", "Part", "Part function."),
JOB("Job", "Job", "Overall job or process function."),
OP("Op", "Operator", "Operator function."),
MAT("Mat", "Material", "Material function."),
OIL("Oil", "Oil", "Oil function."),
WTR("Wtr", "Water", "Water function."),
CAB("Cab", "Cabinet", "Control cabinet function."),
MLT("Mlt", "Melt", "Melt function.")
;
private String abbrev;
private String fullToken;
private String description;
private FunctionToken(String abbrev, String fullToken, String description) {
this.abbrev = abbrev;
this.fullToken = fullToken;
this.description = description;
}
public String description() {
return description;
}
public String fullToken() {
return fullToken;
}
public String abbreviation() {
return abbrev;
}
public static FunctionToken getByAbbreviation(String abbreviation) {
for (FunctionToken value : FunctionToken.values()) {
if (value.abbreviation().equals(abbreviation)) {
return value;
}
}
return null;
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import com.itac.mes.datainterface.application.E63FormatException;
/**
*
* A Job Request should be created to define a job for a session.<br>
* Set the jobName {@linkplain #setJobName(String)} and the fileSpec {@linkplain #setFileSpec(String)} to define a jobRequest. Without this a
* jobRequest is not valid.<br>
* Get the JobRequest text with {@linkplain #getRequestContent()}.
*
*
* <code>
JOB {name} RESPONSE {fspec};
</code>
*
*
* @author frankp
* @since 9.10.00
*/
public class JobRequest extends E63BaseRequest {
private String jobName;
/**
* specify a name for the report; automatically create with a timestamp, max 16 chrs
*
* @param jobName
* @return
* @throws E63FormatException
*/
public JobRequest setJobName(String jobName) throws E63FormatException {
if (jobName == null || jobName.isEmpty() || jobName.length() > 16) {
throw new E63FormatException("job name is not confirm to specification");
}
// no white space allowed
this.jobName = jobName;
return this;
}
/**
* a content as defined in the specification
*
* @return the line describing the job.
* @throws E63FormatException
* when neither report name nor fileSpec are set
*/
public String getRequestContent() throws E63FormatException {
if (jobName == null) {
throw new E63FormatException("can not generate report without Name");
}
if (getFileSpec() == null) {
throw new E63FormatException("can not generate report without FileSpec ");
}
StringBuilder stb = new StringBuilder();
stb.append("JOB ");
stb.append(jobName);
stb.append(" RESPONSE ");
stb.append(getFileSpec());
stb.append(';');
return stb.toString();
}
/**
* @return the job name set before, but never null
*/
public String getJobName() {
return jobName == null ? "" : jobName;
}
}

View File

@@ -0,0 +1,195 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.itac.mes.datainterface.application.E63FormatException;
/**
* @author frankp This file type can have two formats<br>
* COMMAND {Command Identifier} PROCESSED {Response Information} ;<br>
* COMMAND {Command Identifier} ERROR {class} {nnnnnn} {Error Description} ;<br>
* @since 9.10.00
*
*/
public class JobResponse extends E63BaseRequest {
private int sessionNumber;
private String sessionCommandIdentifier;
private E63ResponseCode processedState;
private String responseInformation;
private String errorClass;
private int responseErrorCode;
private int counter;
private Date date;
/**
* @param fileName
* @param content
* COMMAND {Command Identifier} PROCESSED {Response Information} ;<br>
* COMMAND {Command Identifier} ERROR {class} {nnnnnn} {Error Description} ;<br>
* @throws E63FormatException
*/
public void set(String fileName, String content) throws E63FormatException {
// file name does not have a meaning here
super.setFileSpec(fileName);
setFileContent(content);
}
/**
* @param content
*/
private void setFileContent(String content) {
String[] items = content.split("\\ ");
if (!items[0].equals("COMMAND")) {
throw new IllegalArgumentException("MISSING COMMAND");
}
counter = Integer.parseInt(items[1]);
E63ResponseCode respCode = E63ResponseCode.forKey(items[2]);
setProcessedState(respCode);
switch (respCode) {
case PROCESSED:
setContentProcessed(content);
break;
case ERROR:
setContentError(items, content);
break;
default:
setResponseInformation("");
setErrorClass("0");
setResponseErrorCode("0");
}
}
/**
* @param items
* @param content
*/
private void setContentError(String[] items, String content) {
setResponseInformation("");
setErrorClass(items[3]);
setResponseErrorCode(items[4]);
// error Description is delimited by
// starts at this position :
int startPos = content.indexOf('"');
int endPos = content.indexOf('"', startPos + 1) + 1;
setResponseInformation(content.substring(startPos, endPos));
String datetime = content.substring(endPos + 1, content.indexOf(';', endPos));
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
try {
date = sdf.parse(datetime);
} catch (ParseException e) {
date = new Date();
}
}
/**
* @param responseErrorCode
*/
private void setResponseErrorCode(String responseErrorCode) {
this.responseErrorCode = Integer.parseInt(responseErrorCode);
}
/**
* @param errorClass
*/
private void setErrorClass(String errorClass) {
this.errorClass = errorClass;
}
/**
* @param content
*/
private void setContentProcessed(String content) {
int startPos = content.indexOf('"');
int endPos = content.indexOf('"', startPos + 1) + 1;
setResponseInformation(content.substring(startPos, endPos));
String datetime = content.substring(endPos + 1, content.indexOf(';', endPos));
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
try {
date = sdf.parse(datetime);
} catch (ParseException e) {
date = new Date();
}
setErrorClass("");
setResponseErrorCode("0");
}
/**
* @param string
*/
private void setResponseInformation(String responseInformation) {
this.responseInformation = responseInformation;
}
/**
* @param processed
*/
private void setProcessedState(E63ResponseCode processed) {
this.processedState = processed;
}
/**
* @param parseInt
*/
public void setSessionNumber(int sessionNumber) {
this.sessionNumber = sessionNumber;
}
public int getSessionNumber() {
return sessionNumber;
}
public int getResponseErrorCode() {
return responseErrorCode;
}
public void setResponseErrorCode(int responseErrorCode) {
this.responseErrorCode = responseErrorCode;
}
public String getSessionCommandIdentifier() {
return sessionCommandIdentifier;
}
public E63ResponseCode getProcessedState() {
return processedState;
}
public String getResponseInformation() {
return responseInformation;
}
public String getErrorClass() {
return errorClass;
}
/**
* @return
*/
public int getCounter() {
return counter;
}
/**
* @return
*/
public Date getDate() {
return date;
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
/**
* @author frankp
* @since 9.10.00
*/
public enum Miscellaneous {
HDEV("Hdev", "High deviation", "High deviation limit - based relative to another token value."),
LDEV("Ldev", "Low Deviation", "Low deviation limit - based relative to another token value."),
HLMT("Hlmt", "High limit", "High absolute limit."),
LLMT("Llmt", "Low limit", "Low absolute limit."),
PRE("Pre", "Pre", "Used to specify the before state for functions which can occur both before and after another function (such as decompression)."),
PST("Pst", "Post", "Used to specify the after state for functions that can occur both before and after another function (such as decompression)."),
MAX("Max", "Maximum", "Used to specify the maximum value over a range of values or time."),
MIN("Min", "Minimum", "Used to specify the minimum value over a range of values or time."),
AVE("Ave", "Average", "Used to specify the average of values over a range or time."),
SPEC("Spec", "Specific", "Used to represent specific pressure."),
HYD("Hyd", "Hydraulic", "Used to represent hydraulic pressure."),
IN("In", "In", "Used to represent the input portion of a function."),
OUT("Out", "Out", "Used to represent the output portion of a function."),
REJ("Rej", "Reject", "Used to specify a rejected function."),
LOT("Lot", "Lot", "Used to represent a particular lot or group."),
NXT("Nxt", "Next", "Used to represent the next item in a group."),
BOX("Box", "Box", "Used to represent a single collection or group."),
ZN("Zn", "Zone", "Used to represent a zone of a function."),
STB("Stb", "Standby", "Used to represent the standby or alternate condition of a function.");
private String abbrev;
private String fullToken;
private String description;
private Miscellaneous(String abbrev, String fullToken, String description) {
this.abbrev = abbrev;
this.fullToken = fullToken;
this.description = description;
}
public String description() {
return description;
}
public String fullToken() {
return fullToken;
}
public String abbreviation() {
return abbrev;
}
public static Miscellaneous getByAbbreviation(String abbreviation) {
for (Miscellaneous value : Miscellaneous.values()) {
if (value.abbreviation().equals(abbreviation)) {
return value;
}
}
return null;
}
}

View File

@@ -0,0 +1,154 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* available variants :<br>
* 1. COMMAND {n} PROCESSED {command response} {date_spec} {time_spec} ;<br>
* 2. COMMAND {n} ERROR {class} {xxxxxx} {errorDescription} {date_spec} {time_spec};<br>
*
* @author frankp
* @since 9.10.00
*/
public class PresentationResponse {
private int responseNumber;
/**
* @param next
*/
E63ResponseCode result = E63ResponseCode.UNDEFINED;
private String sCommandResponse;
private String sClass;
private String sPresentationResponse;
private Date date;
private String sErrorDescription;
private String sRequestFileCommand;
public int getResponseNumber() {
return responseNumber;
}
public PresentationResponse(String content) {
int endIndex = content.indexOf(' ');
// String cmdIdentifier = content.substring(0, endIndex)
int startIndex = endIndex + 1;
endIndex = content.indexOf(' ', startIndex + 1);
sRequestFileCommand = content.substring(startIndex, endIndex);
startIndex = endIndex + 1;
endIndex = content.indexOf(' ', startIndex + 1);
String sResult = content.substring(startIndex, endIndex);
result = E63ResponseCode.forKey(sResult);
switch (result) {
case PROCESSED:
startIndex = endIndex + 1;
endIndex = content.indexOf('\"', startIndex + 1) + 1;
sCommandResponse = content.substring(startIndex, endIndex);
break;
case ERROR:
startIndex = endIndex + 1;
endIndex = content.indexOf(' ', startIndex + 1);
sClass = content.substring(startIndex, endIndex);
startIndex = endIndex + 1;
endIndex = content.indexOf(' ', startIndex + 1);
sErrorDescription = content.substring(startIndex, endIndex);
startIndex = endIndex + 1;
endIndex = content.indexOf('\"', startIndex + 1);
sPresentationResponse = content.substring(startIndex, endIndex);
break;
default:
// invalid format
break;
}
startIndex = endIndex + 1;
endIndex = content.indexOf(' ', startIndex + 1);
String sDate = content.substring(startIndex, endIndex);
startIndex = endIndex + 1;
endIndex = content.indexOf(';', startIndex + 1);
if (endIndex == -1) {endIndex = content.length()-2;}
String sTime = content.substring(startIndex, endIndex);
// parse Date
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHH:mm:ss");
try {
date = sdf.parse(sDate + sTime);
} catch (ParseException e) {
date = new Date();
}
}
/**
* @return
*/
public E63ResponseCode getResult() {
return result;
}
/**
* only available if the command was processed successfull ("PROCESSED")
*
* @return
*/
public String getCommandResponse() {
if (result != E63ResponseCode.PROCESSED) {
return "";
}
return sCommandResponse == null ? "" : sCommandResponse;
}
/**
* @return
*/
public Date getDate() {
return date == null ? new Date() : date;
}
/**
* @return
*/
public String getErrorClass() {
return sClass == null ? "" : sClass;
}
/**
* @return
*/
public String getErrorDescription() {
return sErrorDescription == null ? "" : sErrorDescription;
}
/**
* @return
*/
public String getPresentationResponseErrorCode() {
return sPresentationResponse == null ? "" : sPresentationResponse;
}
/**
* @return
*/
public int getRequestFileCommand() {
try {
return Integer.parseInt(sRequestFileCommand);
} catch (Exception e) {
// unable to
return -1;
}
}
}

View File

@@ -0,0 +1,19 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
/**
* @author frankp
* @since 9.10.00
*/
public enum ReportFileMode {
OFF,
APPEND,
REWRITE;
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author frankp
* @since 9.10.00
*/
public class ReportRecord {
private Map<String, String> valueMap = new HashMap<>();
public void add(String key, String value) {
valueMap.put(key, value);
}
public String get(String key) {
return valueMap.get(key);
}
/**
* @return
*/
public Date getDate() {
String dateTime = get("DATE") + get("TIME");
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHH:mm:ss");
try {
return sdf.parse(dateTime);
} catch (ParseException e) {
return new Date(0);
}
}
}

View File

@@ -0,0 +1,232 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import java.util.ArrayList;
import java.util.List;
/**
* <code>
REPORT {name} [APPEND | REWRITE] {fspec} {start_spec}
{stop_spec}
[IF [NOT] {parm_id} [{compare_op} {num_const} |
{string_const} | {bool_const} | CHANGE]]
[CYCLIC [TIME {time_const} | SHOT {num_const}]
[SAMPLES {num_const}]
[SESSIONS {num_const}]]
PARAMETERS
{parm_id} | TIME | DATE | COUNT
[, {parm_id} | TIME | DATE | COUNT ...] ;
</code>
*
*
* @author frankp
* @since 9.10.00
*/
public class ReportRequest extends E63BaseRequest {
private String reportName;
private ReportFileMode reportMode = ReportFileMode.APPEND;
private ExecutionType cyclicMode = ExecutionType.CYCLIC;
private Duration cyclicDuration = new Duration("00:01:00,000");
private int cyclicShots = 0;
private List<String> parameters;
private String startSpec;
private String stopSpec;
// specify a name for the report; automatically create with a timestamp, max 16 chrs
public void setReportName(String reportName) {
this.reportName = reportName;
}
/**
* from spec page 39 <code>
APPEND The optional keyword APPEND. If specified, the report data is
appended to the end of any existing report file. If omitted, any
existing report file is deleted. Note that this option is not valid
with the REWRITE option. If the response was deleted by the
host, the header line has to written again.
REWRITE The optional keyword REWRITE. If specified, any existing
report data is overwritten with new data each cycle or time
period. If omitted, all new data is added to the end of the report.
Note that this option is not valid with the APPEND option.
start_spec A valid START specification clause used to indicate when report
data generation will be started.
stop_spec A valid STOP specification clause used to indicate when report
data generation will be stopped.
</code>
*/
public void setReportMode(ReportFileMode reportMode) {
this.reportMode = reportMode;
}
/**
* from spec page 39 <code>
CYCLIC This optional keyword is used to specify whether the report
parameters are recorded only once or whether they are recorded
on a cyclic basis. If the CYCLIC keyword is omitted, the data is
recorded only once. If the CYCLIC keyword is present, the data
is recorded by default every machine cycle. If an optional TIME
or SHOT clause is provided the data is recorded according to the
clause specification. Note that it is up to the application layer to
Note: One record corresponds to one line in the answer file.
TIME {time const} The optional CYCLIC clause TIME keyword indicating that data
is to be recorded based on a time interval. The time constant
SHOT{num_const}
The optional CYCLIC clause SHOT keyword indicating that
data is to be recorded based on a shot count interval. The
numeric constant specifies the number of shots in each recording
interval.
</code>
*/
public void setExecution(ExecutionType cyclicMode, Duration duration, int shots) {
this.cyclicMode = cyclicMode;
this.cyclicDuration = duration;
this.cyclicShots = shots;
}
/**
* currently not used <code>
start_spec A valid START specification clause used to indicate when report
data generation will be started.
</code> default is START IMMEDIATE
*/
public void setStartSpec(String startSpec) {
this.startSpec = startSpec;
}
/**
* currently not used <code>
stop_spec A valid STOP specification clause used to indicate when report
data generation will be stopped.
</code> default is STOP NEVER
*/
public void setStopSpec(String stopSpec) {
this.stopSpec = stopSpec;
}
//
/**
* currently not used <code>
SAMPLES {num_const} The optional SAMPLES keyword specifies the number of
successive recording samples to issue. If omitted, a single
recording sample is issued each cyclic period. If present, the
specified number of samples are recorded each cyclic period.
</code>
*/
public void setSamples(int samples) {}
/**
* currently not used from spec page 39 <code>
SESSIONS {num_const} The optional SESSIONS keyword specifies the total number of
recording sessions to report. If omitted, recording continues
until the STOP clause activates or the report is aborted. If
specified, recording is stopped once the specified number of
recording sessions have been completed.
</code>
*/
public void setSessions(int sessions) {}
/**
* currently not used from spec page 39 <code>
PARAMETERS The keyword PARAMETERS indicating the start of the list of
parameters to be reported. At least one parameter is required. A
parameter may be an application layer parameter ID token or a
pseudo parameter token. Each parameter is separated with a
comma (,) character. The order of the parameters specifies the
order of the data in the report records.
{parm_id} The application layer parameter ID token which specifies a
parameter to be monitored.
</code>
*
* @param paramId
*/
public void addParameter(String paramId) {
getParameters().add(paramId);
}
/**
* @return
*/
public List<String> getParameters() {
if (parameters == null) {
parameters = new ArrayList<>();
parameters.add("DATE");
parameters.add("TIME");
parameters.add("COUNT");
}
return parameters;
}
// a content as defined in the specification
public String getRequestContent() throws Exception {
if (reportName == null) {
throw new Exception("can not generate report without Name");
}
if (getFileSpec() == null) {
throw new Exception("can not generate report without Filename");
}
StringBuilder stb = new StringBuilder();
stb.append("REPORT ");
stb.append(reportName);
stb.append(' ');
switch (reportMode) {
case APPEND:
stb.append("APPEND ");
stb.append(getFileSpec());
break;
case REWRITE:
stb.append("REWRITE ");
stb.append(getFileSpec());
break;
default:
break;
}
stb.append(" \nSTART ");
if (startSpec == null) {
stb.append("IMMEDIATE");
} else {
stb.append(startSpec);
}
stb.append(" \nSTOP ");
if (stopSpec == null) {
stb.append("NEVER");
} else {
stb.append(stopSpec);
}
switch (cyclicMode) {
case CYCLIC:
stb.append(" CYCLIC TIME ");
stb.append(cyclicDuration.toString().substring(0, 8));
break;
case COUNTER:
stb.append(" CYCLIC SHOT ");
stb.append(cyclicShots);
break;
default:
break;
}
// all paramertes as comma separated list
stb.append(' ');
stb.append("\nPARAMETERS ");
stb.append(String.join(",", getParameters()));
stb.append(';');
return stb.toString();
}
}

View File

@@ -0,0 +1,126 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import java.util.ArrayList;
import java.util.List;
/**
* <code>
DATE,TIME,COUNT,ActCntCyc,ActCntCycRej,ActFrcClp,@ActMyPara
19971208,10:15:50,1,1000,5,800.4,30.6
19971208,10:16:10,2,1001,5,800.3,30.2
19971208,10:16:30,3,1002,6,799.9,31.0
19971208,10:16:50,4,1003,6,800.0,30.0
</code>
*
*
* @author frankp
* @since 9.10.00
*/
public class ReportResponse {
private List<ReportRecord> records;
private List<String> allParameters;
private List<String> customParameters;
/**
* Setting the complete file content.<br>
*
* @param content
* @return
*/
public ReportResponse setContent(String content) {
// anlyze line by line
String[] lines = content.split("\\n");
// first line contains all keys
setKeys(lines[0]);
for (int i = 1; i < lines.length; i++) {
setLine(lines[i]);
}
return this;
}
/**
* The first line in a ReportResponse describes the parameters in each line. <br>
* We should find DATE, TIME, COUNT in every row
*
* @param string
*/
private void setKeys(String line) {
allParameters = new ArrayList<>();
customParameters = new ArrayList<>();
String[] keys = line.split("\\,");
for (String paramKey : keys) {
String parameterKey = paramKey.trim();
allParameters.add(parameterKey);
if (parameterKey.equalsIgnoreCase("DATE") || parameterKey.equals("TIME") || parameterKey.equalsIgnoreCase("COUNT")) {
continue;
}
customParameters.add(parameterKey);
}
}
/**
* @param line
*/
private void setLine(String line) {
ReportRecord responseRecord = new ReportRecord();
String[] items = line.split("\\,");
// if request was set compare items in first line with parameters!!!
List<String> reqParams = getAllParameters();
int index = 0;
for (String rParams : reqParams) {
responseRecord.add(rParams, items[index].trim());
index++;
}
getRecords().add(responseRecord);
}
/**
* @return all parameters for this file. even DATE, TIME, COUNT are part of this result
* @see #getCustomParameters()
*/
public List<String> getAllParameters() {
if (allParameters == null) {
allParameters = new ArrayList<>();
}
return allParameters;
}
/**
* @return all parameters for this file excluding DATE, TIME, COUNT
* @see #getAllParameters()
*/
public List<String> getCustomParameters() {
if (customParameters == null) {
customParameters = new ArrayList<>();
}
return customParameters;
}
/**
* @return
*/
public List<ReportRecord> getRecords() {
if (records == null) {
records = new ArrayList<>();
}
return records;
}
}

View File

@@ -0,0 +1,127 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import java.text.MessageFormat;
/**
* @author frankp
* @since 9.10.00
*/
public class SessionRequest extends E63BaseRequest {
private int sessionNumber;
private int sessionCommandIdentifier;
private String requestCommand;
private String parameter;
// name: SESSnnnn.REQ, is case sensitive
// content: < SessionCommandIdentifier >
public void set(String fileName, String content) {
String sNumber = fileName.substring(4, 8);
setSessionNumber(Integer.parseInt(sNumber));
setFileContent(content);
}
/**
* the file name format is fix SESSxxxx.REQ.<br>
*
* @param fileName
* in the required format
* @return the number value for xxxx<br>
* -1 if the number cannot be extracted or the file name is not in the required format
*/
public static int getRequestNumber(String fileName) {
try {
return Integer.parseInt(fileName.substring(4, 8));
} catch (Exception e) {
return -1;
}
}
/**
* @param content
*/
private void setFileContent(String content) {
String[] items = content.split("\\ ");
setSessionCommandIdentifier(items[0]);
setRequestCommand(items[1]);
// items[2] to end of line (semicolon) are the parameters
int startPos = content.indexOf(items[2]);
int endPos = content.indexOf(';', startPos);
setParameter(content.substring(startPos, endPos));
}
/**
* @param parameter
*/
private void setParameter(String parameter) {
this.parameter = parameter.trim();
}
/**
* @param requestCommand
*/
private void setRequestCommand(String requestCommand) {
this.requestCommand = requestCommand;
}
/**
* @param sessionCommandIdentifier
*/
private void setSessionCommandIdentifier(String sessionCommandIdentifier) {
this.sessionCommandIdentifier = Integer.parseInt(sessionCommandIdentifier);
}
public void setSessionNumber(int sessionNumber) {
this.sessionNumber = sessionNumber;
}
public int getSessionNumber() {
return sessionNumber;
}
public String getFileName() {
return MessageFormat.format("SESS{0,number,0000}.REQ", sessionNumber);
}
/**
* @return
*/
public int getSessionCommandIdentifier() {
return sessionCommandIdentifier;
}
/**
* @return
*/
public String getRequestCommand() {
return requestCommand;
}
/**
* @return
*/
public String getParameter() {
return parameter;
}
/**
* The session request should not have a file content by default<br>
* The file content is generated be the presentationlayer or application lyer requests (like connect, subscribe reports, subscribe alarms).
*
* @return ""
*/
public String getFileContent() {
return "";
}
}

View File

@@ -0,0 +1,190 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import com.itac.mes.datainterface.application.E63FormatException;
/**
* This type can have two formats<br>
* {Session Command Identifier} PROCESSED {Response Information} ;<br>
* or<br>
* {Session Command Identifier} ERROR {class} {nnnnnn} {Error Description} ;<br>
*
* It is one line in a E63SessionResponseFile
*
* @author frankp
* @since 9.10.00
*/
public class SessionResponse {
private int sessionCommandIdentifier;
private E63ResponseCode processedState;
private String responseInformation;
private String errorClass;
private int responseErrorCode;
private String errorDescription;
public static String getSessionError(int code) {
switch (code) {
case 0:
return "NO error.";
case 1:
return "No response from network station.";
case 2:
return "Invalid syntax in session request command.";
case 3:
return "Unable to create/open JOB response file.";
case 4:
return "Interface was started";
case 5:
return "Interface is busy.";
case 6:
return "Machine is offline.";
case 7:
return "Invalid syntax in presentation request JOB command";
default:
if (code >= 8 && code <= 9999) {
return "Reserved " + code;
} else if (code >= 10000) {
return "manufacture specific error code: " + code;
}
}
return "unmapped / invalid code " + code;
}
/**
* @param content
* {Session Command Identifier} PROCESSED {Response Information} ;<br>
* {Session Command Identifier} ERROR {class} {nnnnnn} {Error Description} ;<br>
* @throws E63FormatException
*/
public SessionResponse setContent(String content) throws E63FormatException {
String[] items = content.split("\\ ");
setSessionCommandIdentifier(items[0]);
E63ResponseCode respCode = E63ResponseCode.forKey(items[1]);
setProcessedState(respCode);
switch (respCode) {
case PROCESSED:
setContentProcessed(items);
break;
case ERROR:
setContentError(items, content);
break;
default:
setResponseInformation("");
setErrorClass("0");
setResponseErrorCode("0");
setErrorDescription("");
}
return this;
}
/**
* @param items
* @param content
*/
private void setContentError(String[] items, String content) {
setResponseInformation("");
setErrorClass(items[2]);
setResponseErrorCode(items[3]);
// error Description is delimited by
// starts at this position :
int startPos = content.indexOf(items[4]) + 1;
int endPos = content.indexOf('\"', startPos);
setErrorDescription(content.substring(startPos, endPos));
}
/**
* @param errorDescription
*/
private void setErrorDescription(String errorDescription) {
this.errorDescription = errorDescription;
}
/**
* @param responseErrorCode
*/
private void setResponseErrorCode(String responseErrorCode) {
this.responseErrorCode = Integer.parseInt(responseErrorCode);
}
/**
* @param errorClass
*/
private void setErrorClass(String errorClass) {
this.errorClass = errorClass;
}
/**
* @param items
*/
private void setContentProcessed(String[] items) {
setResponseInformation(items[2]);
setErrorClass("");
setResponseErrorCode("0");
setErrorDescription("");
}
/**
* @param string
*/
private void setResponseInformation(String responseInformation) {
this.responseInformation = responseInformation;
}
/**
* @param processed
*/
private void setProcessedState(E63ResponseCode processed) {
this.processedState = processed;
}
/**
* @param sessionCommandIdentifier
* an 8 character code
* @throws E63FormatException
*/
private void setSessionCommandIdentifier(String sessionCommandIdentifier) throws E63FormatException {
try {
this.sessionCommandIdentifier = Integer.parseInt(sessionCommandIdentifier);
} catch (Exception e) {
throw new E63FormatException("session command identifier is not to integer");
}
}
public int getResponseErrorCode() {
return responseErrorCode;
}
public void setResponseErrorCode(int responseErrorCode) {
this.responseErrorCode = responseErrorCode;
}
public int getSessionCommandIdentifier() {
return sessionCommandIdentifier;
}
public E63ResponseCode getProcessedState() {
return processedState;
}
public String getResponseInformation() {
return responseInformation;
}
public String getErrorClass() {
return errorClass;
}
public String getErrorDescription() {
return errorDescription;
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
/**
* @author frankp
* @since 9.10.00
*/
public enum TypeToken {
SET("Set", "Set", "Specifies a value set at the machine."),
ACT("Act", "Act", "Specifies an actual value measured at the machine.");
private String abbrev;
private String fullToken;
private String description;
private TypeToken(String abbrev, String fullToken, String description) {
this.abbrev = abbrev;
this.fullToken = fullToken;
this.description = description;
}
public String description() {
return description;
}
public String fullToken() {
return fullToken;
}
public String abbreviation() {
return abbrev;
}
public static TypeToken getByAbbreviation(String abbreviation) {
for (TypeToken value : TypeToken.values()) {
if (value.abbreviation().equals(abbreviation)) {
return value;
}
}
return null;
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
/**
* @author frankp
* @since 9.10.00
*/
public enum UnitToken {
CFG("Cfg", "Configuration", "n/a", "Used to specify the configuration or setup of a function."),
VOL("Vol", "Volume", "ccm", "Used to specify a volumetric value."),
VELC("Vel", "Velocity", "mm/s", "Used to specify a velocity value."),
TIM("Tim", "Time", "s", "Used to specify a time measurement."),
TMP("Tmp", "Temperature", "C", "Used to specify a temperature measurement."),
SPD("Spd", "Speed", "1/min", "Used to specify a speed measurement."),
PRS("Prs", "Pressure", "bar", "Used to specify a pressure measurement."),
PWR("Pwr", "Power", "W", "Used to specify a power measurement."),
STR("Str", "Stroke", "mm", "Used to specify a stroke or linear position measurement."),
CNT("Cnt", "Count", "n/a", "Used to specify a count."),
FCE("Fce", "Force", "kN", "Used to specify a force measurement."),
DIA("Dia", "Diameter", "mm", "Used to specify the diameter."),
DESC("Desc", "Description", "n/a", "Used to describe something."),
STS("Sts", "Status", "n/a", "Used to specify the active status of a function."),
REC("Rec", "Recipe", "n/a", "Used to specify the recipe or setup of a function.");
private String abbrev;
private String fullToken;
private String description;
private UnitToken(String abbrev, String fullToken, String unit, String description) {
this.abbrev = abbrev;
this.fullToken = fullToken;
this.description = description;
}
public String description() {
return description;
}
public String fullToken() {
return fullToken;
}
public String abbreviation() {
return abbrev;
}
public static UnitToken getByAbbreviation(String abbreviation) {
for (UnitToken value : UnitToken.values()) {
if (value.abbreviation().equals(abbreviation)) {
return value;
}
}
return null;
}
}

View File

@@ -0,0 +1,243 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.datasource;
import static java.text.MessageFormat.format;
import java.util.List;
import com.itac.mes.datainterface.ConfigurationException;
import com.itac.mes.datainterface.ParameterUpdateTool;
import com.itac.mes.datainterface.annotations.AAutoHandler;
import com.itac.mes.datainterface.annotations.AInit;
import com.itac.mes.datainterface.annotations.AInstantiationType;
import com.itac.mes.datainterface.annotations.AParamValue;
import com.itac.mes.datainterface.annotations.AParameter;
import com.itac.mes.datainterface.annotations.InstantiationType;
import com.itac.mes.datainterface.application.E63Application;
import com.itac.mes.datainterface.data.Duration;
import com.itac.mes.datainterface.data.FileUnit;
import com.itac.mes.datainterface.data.Station;
import com.itac.mes.datainterface.data.Toolbox;
import com.itac.mes.datainterface.datasource.directory.IDirectoryObserver;
import com.itac.mes.datainterface.filehandler.Euromap63FileHandler;
import com.itac.mes.datainterface.filehandler.IFileHandler;
import com.itac.mes.datainterface.parser.Euromap63Parser;
import com.itac.mes.datainterface.parser.IParser;
import com.itac.mes.datainterface.process.Euromap63Processor;
import com.itac.mes.datainterface.process.IProcessor;
/**
* @author frankp
* @since 9.10.00
*/
@AInstantiationType(name = "euromap63", type = InstantiationType.DATASOURCE, inheritParameter = false)
public class Euromap63FileSource extends BasicDataSource implements IDirectoryObserver {
private static final String LOGGER = Euromap63FileSource.class.getSimpleName();
private static final String DATASOURCE_EUROMAP63 = "datasource.euromap63";
private static final String INTERVAL = DATASOURCE_EUROMAP63 + ".interval";
private static final String SESSION_DIR = DATASOURCE_EUROMAP63 + ".sessionDir";
private static final String PRESENTATION_DIR = DATASOURCE_EUROMAP63 + ".presentationDir";
private static final String APPLICATION_DIR = DATASOURCE_EUROMAP63 + ".applicationDir";
private static final String MACHINE_NAMES = DATASOURCE_EUROMAP63 + ".machineNames";
private static final String AUTORUN = DATASOURCE_EUROMAP63 + ".autorun";
// limits for directory polling
protected static final Duration MIN_POLLING_INTERVAL = new Duration("00:00:00,010");
protected static final Duration MAX_POLLING_INTERVAL = new Duration("01:00:00,000");
public static final String MACHINE_PATTERN = "{machine}";
private Duration dirPollingInterval;
// directories from configuration
private String sessionDirectory;
private String presentationDirectory;
private String applicationDirectory;
@AAutoHandler(InstantiationType.PARSER)
protected IParser parser;
@AAutoHandler(InstantiationType.PROCESSOR)
protected IProcessor processor;
@AAutoHandler(InstantiationType.FILEHANDLER)
protected IFileHandler filehandler;
@AAutoHandler(InstantiationType.TOOL)
protected Toolbox toolbox;
@AAutoHandler(InstantiationType.APPLICATION)
protected E63Application application;
private List<String> machineNames;
@AParameter(name = DATASOURCE_EUROMAP63, description = "Euromap63 File source",
visibility = "DataSource=com.itac.mes.datainterface.datasource.Euromap63FileSource",
dimPath = ParameterUpdateTool.DEFAULT_DIM_PATH)
@AParameter(name = INTERVAL, parent = DATASOURCE_EUROMAP63, description = "directory polling interval", type = Duration.class, ordering = "010")
@AParameter(name = SESSION_DIR, parent = DATASOURCE_EUROMAP63, description = "directory for session layer files", type = String.class,
ordering = "100")
@AParameter(name = PRESENTATION_DIR, parent = DATASOURCE_EUROMAP63, description = "directory for presentation layer files", type = String.class,
ordering = "110")
@AParameter(name = APPLICATION_DIR, parent = DATASOURCE_EUROMAP63, description = "directory for application layer files", type = String.class,
ordering = "120")
@AParameter(name = MACHINE_NAMES, parent = DATASOURCE_EUROMAP63, description = "list with machine names", type = List.class, ordering = "150",
metaType = String.class)
@AParameter(name = AUTORUN, parent = DATASOURCE_EUROMAP63, description = "should datasource start automatically", type = Boolean.class,
ordering = "200")
public Euromap63FileSource() {
super();
}
@AInit
protected void init() throws ConfigurationException {
if (!(parser instanceof Euromap63Parser)) {
throw new ConfigurationException("parser is not of expected type {0}", Euromap63Parser.class.getSimpleName());
}
if (!(processor instanceof Euromap63Processor)) {
throw new ConfigurationException("processor is not of expected type {0}", Euromap63Processor.class.getSimpleName());
}
if (!(filehandler instanceof Euromap63FileHandler)) {
throw new ConfigurationException("fileHandler is not of expected type {0}", Euromap63FileHandler.class.getSimpleName());
}
// Check that at least one machine is configured
if (machineNames == null || machineNames.isEmpty()) {
throw new ConfigurationException("parameter {0} requires at least one specified machine!", MACHINE_NAMES);
}
// for euromap we have 3 directories to observer and to work on
if (sessionDirectory == null) {
throw new ConfigurationException("Missing or invalid session directory");
}
if (presentationDirectory == null) {
throw new ConfigurationException("Missing or invalid presentation directory");
}
if (applicationDirectory == null) {
throw new ConfigurationException("Missing or invalid applicationDirectory directory");
}
// check station mappings
for (String machineName : machineNames) {
Station st = toolbox.getStation(machineName);
if (st == null) {
throw new ConfigurationException(
"Missing station mapping for machine {0} configured in {1}.\nAdd a mapping for every machine in clients.accessibleClients",
machineName, LOGGER);
}
}
// check all directories names for pattern
if (machineNames.size() > 1) {
// all directories session, presentation, application must have the pattern
checkDirectoryName(sessionDirectory);
checkDirectoryName(presentationDirectory);
checkDirectoryName(applicationDirectory);
}
// set the values to the application
application.setMachineNames(machineNames);
application.setFileHandler(((Euromap63FileHandler) filehandler), sessionDirectory, presentationDirectory, applicationDirectory);
application.setParser(((Euromap63Parser) parser));
application.setProcessor(((Euromap63Processor) processor));
application.setPollingInterval(dirPollingInterval);
application.initialize();
setDescription(format("File: FileHandler={0}, Parser={1}, Processor={2}", filehandler.getName(), parser.getName(), processor.getName()));
}
/**
* @param applicationDirectory2
* @throws ConfigurationException
*/
private void checkDirectoryName(String directory) throws ConfigurationException {
if (sessionDirectory.indexOf(MACHINE_PATTERN) < 0) {
throw new ConfigurationException("Missing {0} in configured directory {1}", MACHINE_PATTERN, directory);
}
}
@AParamValue(value = MACHINE_NAMES)
protected void setMachineNames(List<String> machineNames) {
this.machineNames = machineNames;
}
@AParamValue(value = AUTORUN)
@Override
public void setAutorun(boolean value) {
super.setAutorun(value);
}
@AParamValue(value = INTERVAL)
protected void setDirectoryPollingInterval(Duration value) throws ConfigurationException {
this.dirPollingInterval = value;
if (value.getMillies() < MIN_POLLING_INTERVAL.getMillies()) {
throw new ConfigurationException("parameter {0} must be greater than {1}, but is currently {2}!", INTERVAL, MIN_POLLING_INTERVAL, value);
} else if (value.getMillies() > MAX_POLLING_INTERVAL.getMillies()) {
throw new ConfigurationException("parameter {0} must be less than {1}, but is currently {2}!", INTERVAL, MAX_POLLING_INTERVAL, value);
}
}
@AParamValue(value = SESSION_DIR)
protected void setSessionDir(String value) {
this.sessionDirectory = value;
}
@AParamValue(value = PRESENTATION_DIR)
protected void setPresentationDir(String value) {
this.presentationDirectory = value;
}
@AParamValue(value = APPLICATION_DIR)
protected void setApplicationDir(String value) {
this.applicationDirectory = value;
}
@Override
public void start() {
application.start();
}
@Override
public void stop() {
application.stop();
}
/**
* Beginn einer Pause. Diese Methode muss von den Datasourcen &uuml;berschrieben werden
*/
@Override
public void startPause() {
application.startPause();
}
/**
* Ende einer Pause. Diese Methode muss von den Datasourcen &uuml;berschrieben werden.
*/
@Override
public void endPause() {
application.endPause();
}
@Override
public void newFileAvailable(FileUnit fileUnit) {
// this method remains unused ..
}
/*
* (non-Javadoc)
* @see com.itac.mes.datainterface.datasource.BasicDataSource#isRunning()
*/
@Override
public boolean isRunning() {
return application.isRunning();
}
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.filehandler;
import static com.itac.util.logging.LogLevel.DEBUG;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import com.itac.mes.datainterface.ConfigurationException;
import com.itac.util.logging.LogHandler;
/**
* @author frankp
* @since 9.10.00
*/
public class E63DirectoryHandler {
private static final String LOGGER = E63DirectoryHandler.class.getSimpleName();
private String machineName;
private File sessionDir;
private File presentationDir;
private File applicationDir;
private File sessionRequestFile; // if not null a this is the session request file
public E63DirectoryHandler(String machineName) {
super();
this.machineName = machineName;
}
/**
* the real names, pattern replaced by the machine name in the directory names
*
* @param sessionDir
* @param presentationDir
* @param applicationDir
* @throws ConfigurationException
*/
public void setDirectoryNames(String sessionDir, String presentationDir, String applicationDir) throws ConfigurationException {
LogHandler.log(LOGGER, DEBUG, "setting working directories for machine {0}:\n Session: {1}\n Presentation: {2}\n Application:{3}", machineName,
sessionDir, presentationDir, applicationDir);
this.sessionDir = new File(sessionDir);
checkDirectory(this.sessionDir);
this.presentationDir = new File(presentationDir);
checkDirectory(this.presentationDir);
this.applicationDir = new File(applicationDir);
checkDirectory(this.applicationDir);
}
protected void checkDirectory(File directory) throws ConfigurationException {
String canonicalName = directory.getName();
if (!directory.exists()) {
throw new ConfigurationException("directory {0} does not exist for machine {1}!", canonicalName);
}
if (!directory.isDirectory()) {
throw new ConfigurationException("directory {0} is not a directory!", canonicalName);
}
if (!directory.canWrite()) {
throw new ConfigurationException("directory {0} is not writeable!", canonicalName);
}
}
public File getDirectory(E63DirectoryType directoryType) {
File dir;
switch (directoryType) {
case SESSION:
dir = sessionDir;
break;
case PRESENTATION:
dir = presentationDir;
break;
case APPLICATION:
dir = applicationDir;
break;
default:
dir = null;
break;
}
return dir;
}
public String[] listFiles(E63DirectoryType directoryType) {
return getDirectory(directoryType).list();
}
/**
* @param session
* @param fileName
* @param filecontent
* @throws FileNotFoundException
* @throws IOException
*/
public File writeFile(E63DirectoryType directoryType, String fileName, String fileContent) throws FileNotFoundException {
File directory = getDirectory(directoryType);
sessionRequestFile = new File(directory, fileName);
try (FileOutputStream fileOutputStream = new FileOutputStream(sessionRequestFile, true);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream, 128 * 100)) {
bufferedOutputStream.write(fileContent.getBytes(Charset.forName("ISO-8859-1")));
bufferedOutputStream.flush();
} catch (IOException e) {
}
return sessionRequestFile;
}
/**
*
*/
public void deleteSessionRequestFile() {
if (sessionRequestFile != null) {
try {
LogHandler.log(LOGGER, DEBUG, "deleting session request file {0}", sessionRequestFile.getCanonicalPath());
if (!sessionRequestFile.delete()) {
LogHandler.log(LOGGER, DEBUG, "request file {0} not deleted", sessionRequestFile.getCanonicalPath());
}
} catch (IOException e) {
LogHandler.log(LOGGER, DEBUG, "request file {0} not deleted", sessionRequestFile.getName(), e);
}
}
}
}

View File

@@ -0,0 +1,18 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.filehandler;
/**
* @author frankp
* @since 9.10.00
*/
public enum E63DirectoryType {
SESSION, PRESENTATION, APPLICATION;
}

View File

@@ -0,0 +1,174 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.filehandler;
import com.itac.mes.datainterface.ConfigurationException;
import com.itac.mes.datainterface.ParameterUpdateTool;
import com.itac.mes.datainterface.annotations.AInstantiationType;
import com.itac.mes.datainterface.annotations.AParamValue;
import com.itac.mes.datainterface.annotations.AParameter;
import com.itac.mes.datainterface.annotations.AParameterDefaultValue;
import com.itac.mes.datainterface.annotations.InstantiationType;
import com.itac.mes.datainterface.data.Duration;
import com.itac.mes.datainterface.data.FileUnit;
import com.itac.mes.datainterface.datasource.Euromap63FileSource;
/**
* @author frankp
* @since 9.10.00
*/
@AInstantiationType(name = "euromap63", type = InstantiationType.FILEHANDLER, inheritParameter = false)
public class Euromap63FileHandler extends IFileHandler {
private static final String LOGGER = Euromap63FileHandler.class.getSimpleName();
private static final String EUROMAP63_FILE_HANDLER = "filehandler.euromap63";
private static final String EUROMAP63_SESSION = EUROMAP63_FILE_HANDLER + ".session";
private static final String MAX_SESSION = EUROMAP63_SESSION + ".maxSession";
private static final String SESSION_RETRY = EUROMAP63_SESSION + ".sessionRetry";
private static final String SESSION_TIMEOUT = EUROMAP63_SESSION + ".sessionTimeout";
// 10 seconds to 24 hours
protected static final long MIN_SESSION_TIMEOUT = new Duration("00:00:10,000").getMillies();
protected static final long MAX_SESSION_TIMEOUT = new Duration("24:00:00,000").getMillies();
// 10 seconds to 10 hours
protected static final Duration MIN_SESSION_RETRY = new Duration("00:00:10,000");
protected static final Duration MAX_SESSION_RETRY = new Duration("00:10:00,000");
protected String sessionDirectory;
protected String presentationDirectory;
protected String applicationDirectory;
@AParamValue(value = MAX_SESSION)
@AParameterDefaultValue(name = MAX_SESSION)
private int maxSession = 1000;
private Duration sessionRetryInterval;
private Duration sessionTimeoutInterval;
@AParameter(name = EUROMAP63_FILE_HANDLER, description = "Euromap63 file handler",
visibility = "FileHandler=com.itac.mes.datainterface.filehandler.Euromap63FileHandler",
dimPath = ParameterUpdateTool.DEFAULT_DIM_PATH)
@AParameter(name = EUROMAP63_SESSION, parent = EUROMAP63_FILE_HANDLER, description = "Session Handling", type = Void.class)
@AParameter(name = MAX_SESSION, parent = EUROMAP63_SESSION, description = "max session number", type = Integer.class)
@AParameter(name = SESSION_RETRY, parent = EUROMAP63_SESSION, description = "retry to get a session when all sessions are in use",
type = Duration.class)
@AParameter(name = SESSION_TIMEOUT, parent = EUROMAP63_SESSION, description = "the time the session is removed when not answered from machine",
type = Duration.class)
// no default mode for file handling, nor copy neither move
public Euromap63FileHandler() {
super();
setDescription("Der Euromap63 FileHandler"
+ "Session Handling."
+ "Command Handling");
}
@AParamValue(value = SESSION_RETRY, storeDefault = true)
protected void setInterval(Duration value) throws ConfigurationException {
this.sessionRetryInterval = value;
if (value.getMillies() < MIN_SESSION_RETRY.getMillies()) {
throw new ConfigurationException("parameter {0} must be greater than {1}, but is currently {2}!", SESSION_RETRY, MIN_SESSION_RETRY, value);
} else if (value.getMillies() > MAX_SESSION_RETRY.getMillies()) {
throw new ConfigurationException("parameter {0} must be less than {1}, but is currently {2}!", SESSION_RETRY, MAX_SESSION_RETRY, value);
}
}
@AParamValue(value = SESSION_TIMEOUT, storeDefault = true)
protected void setSessionTimeout(Duration value) throws ConfigurationException {
this.sessionTimeoutInterval = value;
if (value.getMillies() < MIN_SESSION_TIMEOUT) {
throw new ConfigurationException("parameter {0} must be greater than {1}, but is currently {2}!", SESSION_TIMEOUT, MIN_SESSION_TIMEOUT, value);
} else if (value.getMillies() > MAX_SESSION_TIMEOUT) {
throw new ConfigurationException("parameter {0} must be less than {1}, but is currently {2}!", SESSION_TIMEOUT, MAX_SESSION_TIMEOUT, value);
}
}
@AParameterDefaultValue(name = SESSION_TIMEOUT)
protected Duration getSessionTimeoutDefault() {
return new Duration("01:00:00,000");
}
@AParameterDefaultValue(name = SESSION_RETRY)
protected Duration getSessionRetryDefault() {
return new Duration("00:01:00,000");
}
// unused in this file handler
@Override
public int startFile(FileUnit fileUnit) {
return OK;
}
@Override
public int endFile(FileUnit iFile) {
return OK;
}
public void initiateSession() {
// find a session number
// means list session directory
// and find the next free / unused session...
// write a session request file
}
public void setMaxSession(int maxSession) throws ConfigurationException {
this.maxSession = maxSession;
if (maxSession < 1 || maxSession > 9999) {
throw new ConfigurationException("valid range for parameter {0} is 1..9999", MAX_SESSION);
}
}
/**
* @param machineName
* @return
* @throws ConfigurationException
*/
public E63DirectoryHandler createDirectoryHandler(String machineName) throws ConfigurationException {
E63DirectoryHandler dirHandler = new E63DirectoryHandler(machineName);
dirHandler.setDirectoryNames(sessionDirectory.replace(Euromap63FileSource.MACHINE_PATTERN, machineName),
presentationDirectory.replace(Euromap63FileSource.MACHINE_PATTERN, machineName),
applicationDirectory.replace(Euromap63FileSource.MACHINE_PATTERN, machineName));
return dirHandler;
}
/**
* @param sessionDirectory2
*/
public void setSessionDirectory(String sessionDirectory) {
this.sessionDirectory = sessionDirectory;
}
/**
* @param presentationDirectory2
*/
public void setPresentationDirectory(String presentationDirectory) {
this.presentationDirectory = presentationDirectory;
}
/**
* @param applicationDirectory2
*/
public void setApplicationDirectory(String applicationDirectory) {
this.applicationDirectory = applicationDirectory;
}
/**
* @return
*/
public int getMaxSession() {
return maxSession;
}
public Duration getSessionRetryInterval() {
return sessionRetryInterval;
}
}

View File

@@ -0,0 +1,302 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.parser;
import static com.itac.util.logging.LogLevel.DEBUG;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.itac.mes.config.domain.ParameterEnumerationProperties;
import com.itac.mes.datainterface.ConfigurationException;
import com.itac.mes.datainterface.annotations.AAutoHandler;
import com.itac.mes.datainterface.annotations.AInit;
import com.itac.mes.datainterface.annotations.AInstantiationType;
import com.itac.mes.datainterface.annotations.AParamValue;
import com.itac.mes.datainterface.annotations.AParameter;
import com.itac.mes.datainterface.annotations.AParameterDefaultValue;
import com.itac.mes.datainterface.annotations.AParameterProperties;
import com.itac.mes.datainterface.annotations.InstantiationType;
import com.itac.mes.datainterface.annotations.StationLicenseCheck;
import com.itac.mes.datainterface.application.E63Application;
import com.itac.mes.datainterface.application.E63ProcessException;
import com.itac.mes.datainterface.data.BasicUploadUnit;
import com.itac.mes.datainterface.data.Duration;
import com.itac.mes.datainterface.data.E63FileUnit;
import com.itac.mes.datainterface.data.ExecutionType;
import com.itac.mes.datainterface.data.ReportRecord;
import com.itac.mes.datainterface.data.ReportResponse;
import com.itac.mes.datainterface.data.Station;
import com.itac.mes.datainterface.data.Toolbox;
import com.itac.mes.datainterface.data.UploadTrUploadStationResultUnit;
import com.itac.mes.datainterface.data.imsapi.StationResult;
import com.itac.util.logging.LogHandler;
/**
* @author frankp
* @since 9.10.00
*/
@StationLicenseCheck
@AInstantiationType(type = InstantiationType.PARSER, name = "euromap63")
public class Euromap63Parser extends IParser {
private static final String PARSER_EUROMAP63 = "parser.euromap63";
private static final String EXECUTION_TYPE = PARSER_EUROMAP63 + ".executionType"; // cyclic or counter
private static final String EXECUTION_INTERVAL = PARSER_EUROMAP63 + ".executionInterval";
private static final String EXECUTION_COUNT = PARSER_EUROMAP63 + ".executionCount";
private static final String EXECUTION_VALUES = PARSER_EUROMAP63 + ".executionValues";
private static final String MACHINE_NAMES = PARSER_EUROMAP63 + ".machineNames";
// 10 Sekunden
protected static final long MIN_INTERVAL = new Duration("00:00:10,000").getMillies();
// 24 Stunde
protected static final long MAX_INTERVAL = new Duration("24:00:00,000").getMillies();
private static final String LOGGER = Euromap63Parser.class.getSimpleName();
@AParamValue(value = EXECUTION_TYPE)
private int processLayer;
@AAutoHandler(InstantiationType.TOOL)
private Toolbox toolbox;
// value from configuration
private ExecutionType executionType;
private Duration executionInterval;
@AParamValue(value = EXECUTION_COUNT, allowEmpty = true, storeDefault = true)
@AParameterDefaultValue(name = EXECUTION_COUNT)
private int executionCounter = 10;
private List<String> reportGenerationParameters;
private Set<String> reportGenerationParameterNames;
@AAutoHandler(InstantiationType.APPLICATION)
private E63Application application;
// declaration of parameters
@AParameter(name = PARSER_EUROMAP63, description = "Euromap63 Parser", type = Void.class,
visibility = "Parser=com.itac.mes.datainterface.parser.Euromap63Parser")
@AParameter(name = EXECUTION_TYPE, parent = PARSER_EUROMAP63, description = "executionType", metaType = Integer.class, type = Enum.class,
ordering = "030")
@AParameter(name = EXECUTION_INTERVAL, parent = PARSER_EUROMAP63, description = "execution interval", type = Duration.class,
visibility = "parser.euromap63.executionType=1", ordering = "040")
@AParameter(name = EXECUTION_COUNT, parent = PARSER_EUROMAP63, description = "execution counter", type = Integer.class,
visibility = "parser.euromap63.executionType=2", ordering = "050")
@AParameter(name = EXECUTION_VALUES, parent = PARSER_EUROMAP63, description = "list with values to get", type = List.class, ordering = "100",
metaType = String.class)
public Euromap63Parser() {
super();
}
@AParameterProperties(name = EXECUTION_TYPE)
public static ParameterEnumerationProperties<Integer> getExecutionTypeEnumerationProperties() {
ParameterEnumerationProperties<Integer> enumProperties = new ParameterEnumerationProperties<Integer>(Integer.class);
for (ExecutionType execType : ExecutionType.values()) {
enumProperties.add(execType.ordinal(), execType.text());
}
return enumProperties;
}
@AParamValue(value = EXECUTION_TYPE, storeDefault = true)
protected void setExecutionType(Integer value) {
setExecutionType(ExecutionType.values()[value]);
}
@AParameterDefaultValue(name = EXECUTION_TYPE)
protected ExecutionType getExecutionTypeDefault() {
return ExecutionType.CYCLIC;
}
@AParameterDefaultValue(name = EXECUTION_INTERVAL)
protected Duration getSessionTimeoutDefault() {
return new Duration("00:01:00,000");
}
@AParamValue(value = EXECUTION_INTERVAL, allowEmpty = true, storeDefault = true)
protected void setInterval(Duration value) throws ConfigurationException {
this.executionInterval = value;
if (value.getMillies() < MIN_INTERVAL) {
throw new ConfigurationException("parameter {0} must be greater than {1}, but is currently {2}!", EXECUTION_INTERVAL, new Duration(MIN_INTERVAL),
executionInterval.toString());
} else if (value.getMillies() > MAX_INTERVAL) {
throw new ConfigurationException("parameter {0} must be less than {1}, but is currently {2}!", EXECUTION_INTERVAL, new Duration(MAX_INTERVAL),
executionInterval.toString());
}
}
@AParamValue(value = EXECUTION_VALUES)
protected void setReportParameterNames(List<String> valueList) {
reportGenerationParameters = new ArrayList<String>();
reportGenerationParameterNames = new HashSet<>();
for (String value : valueList) {
reportGenerationParameters.add(value);
reportGenerationParameterNames.add(value);
}
}
/**
* @param executionType
*/
private void setExecutionType(ExecutionType executionType) {
this.executionType = executionType;
}
public ExecutionType getExecutionType() {
return executionType;
}
public Duration getExecutionInterval() {
return executionInterval;
}
public void setExecutionCounter(int executionCounter) {
this.executionCounter = executionCounter;
}
public int getExecutionCounter() {
return executionCounter;
}
@AInit
protected void init() throws ConfigurationException {
// perform those checks at instance initialization; throw exception if one pref is not set
switch (executionType) {
case COUNTER:
// reqquired value in counter
if (executionCounter == 0 || executionCounter > 1000) {
throw new ConfigurationException("parameter {0} must be in range 0..1000 in mode {1}!", EXECUTION_COUNT, executionType);
}
break;
case CYCLIC:
if (executionInterval == null) {
throw new ConfigurationException("value {0} for parameter {1} requires a value for parameter {2}!", executionType, EXECUTION_TYPE,
EXECUTION_INTERVAL);
}
if (executionInterval.getMillies() < MIN_INTERVAL) {
throw new ConfigurationException("parameter {0} must be greater than {1}, but is currently {2} (mode={3})!", EXECUTION_INTERVAL, new Duration(
MIN_INTERVAL),
executionInterval.toString(), executionType);
} else if (executionInterval.getMillies() > MAX_INTERVAL) {
throw new ConfigurationException("parameter {0} must be less than {1}, but is currently {2}(mode={3})!", EXECUTION_INTERVAL, new Duration(
MAX_INTERVAL),
executionInterval.toString(), executionType);
}
break;
default:
break;
}
if (reportGenerationParameters == null || reportGenerationParameters.isEmpty()) {
throw new ConfigurationException("parameter {0} requires at least one specific value!", EXECUTION_VALUES);
}
// TODO wenn mehr als eine Maschine konfiguriert ist müssend ie VErzeichnisse den machine Pattern als Teil das Verzeichnisnamens enthalten
// Bei nur einer Maschine kann der Verzeichnispfad fest sein...
// Bsp: WorkDir = C:\temp\{$machine}\work
}
/**
* @param fileContent
* @param fileName
* @param uploadUnitList
* @param resultText
* @return
* @see com.itac.mes.datainterface.parser.IParser#parse(java.lang.StringBuffer)
*/
@Override
public Code parse(StringBuffer fileContent, String fileName, List<BasicUploadUnit> uploadUnitList, StringBuffer resultText) {
// check some preconditions
if (fileContent == null || fileContent.length() == 0) {
resultText.append("Can not parse file file without content.\n");
return Code.NOT_PARSED;
}
if (toolbox == null) {
resultText.append("Can not parse file file without toolbox.\n");
return Code.NOT_PARSED;
}
return Code.OK;
}
/**
* @return
*/
public List<String> getReportParameter() {
return reportGenerationParameters == null ? new ArrayList<>() : reportGenerationParameters;
}
public Set<String> getReportParameterNames() {
return reportGenerationParameterNames == null ? new HashSet<>() : reportGenerationParameterNames;
}
/**
* @param reportResponse
* @param machineName
* @return
* @throws E63ProcessException
*/
public E63FileUnit parse(ReportResponse reportResponse, String machineName) throws E63ProcessException {
if (reportResponse == null) {
throw new E63ProcessException("Unable to process null as a reportResponse");
}
// this is the unit which could be processed by an processor
E63FileUnit e63File = new E63FileUnit();
Station station = toolbox.getStation(machineName);
if (station == null) {
throw new E63ProcessException("No station mapping possible from {0} to station", machineName);
}
LogHandler.log(LOGGER, DEBUG, "found station {0} for machine {1}", station.getStationNumber(), machineName);
int lineNo = 0;
for (ReportRecord reportRecord : reportResponse.getRecords()) {
UploadTrUploadStationResultUnit uploadUnit = new UploadTrUploadStationResultUnit();
uploadUnit.setStationNumber(station.getStationNumber());
// no need to set any header value at all; use defaults !!
// uploadUnit.setBomIndex(bomIndex)
// uploadUnit.setBomVersion(bomVersion)
// uploadUnit.setBomVersionErp(bomVersionErp)
// uploadUnit.setBookDate(null)
// uploadUnit.setPartNumber(partNumber)
// uploadUnit.setSerialUnitTrace(serialUnitTrace)
// uploadUnit.setWorkOrderNumber(workOrderNumber)
// this are all parameters contained in the reportResponse
List<String> v = reportResponse.getCustomParameters();
for (String param : v) {
if (!getReportParameterNames().contains(param)) {
LogHandler.log(LOGGER, DEBUG, "line {1}: skip reported parameter {0} because it is not configured", param, lineNo);
continue;
}
StationResult stationResult = new StationResult();
stationResult.setMeasureFailCode("0");
stationResult.setMeasureName(param);
stationResult.setMeasureValue(reportRecord.get(param));
stationResult.setMeasureType("T");
stationResult.setType("D");
stationResult.setUnit("?");
uploadUnit.addStationResult(stationResult);
}
uploadUnit.setParseCode(IParser.Code.OK);
e63File.uploadUnitList.add(uploadUnit);
lineNo++;
}
return e63File;
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.process;
import static com.itac.resource.ResourcesIMSInterfaces.PROCESSOR_CLINK;
import com.itac.artes.ihas.LookupException;
import com.itac.mes.core.domain.mig.exception.ItacMesErrorCode;
import com.itac.mes.core.domain.mig.exception.ItacMesErrorCodeIMSApi;
import com.itac.mes.datainterface.ParameterUpdateTool;
import com.itac.mes.datainterface.annotations.AInit;
import com.itac.mes.datainterface.annotations.AInstantiationType;
import com.itac.mes.datainterface.annotations.AParameter;
import com.itac.mes.datainterface.annotations.Dispatch;
import com.itac.mes.datainterface.annotations.InstantiationType;
import com.itac.mes.datainterface.data.ProcessResult;
import com.itac.mes.datainterface.data.UploadTrUploadStationResultUnit;
import com.itac.mes.imsapi.domain.container.Result_trUploadStationResult;
/**
* @author frankp
* @since 9.10.00
*/
@AInstantiationType(type = InstantiationType.PROCESSOR, name = "euromap63")
public class Euromap63Processor extends DefaultProcessor {
private static final String PROCESSOR_IPC2547 = "processor.euromap63";
private static final String LOGGER = Euromap63Processor.class.getSimpleName();
@AParameter(name = PROCESSOR_IPC2547, description = "euromap63",
visibility = "Processor=com.itac.mes.datainterface.process.Euromap63Processor", dimPath = ParameterUpdateTool.DEFAULT_DIM_PATH,
resource = PROCESSOR_CLINK)
public Euromap63Processor() {
super();
}
/*
* Initialize this instance<br>
* @see com.itac.mes.datainterface.process.DefaultProcessor#initProcessor()
*/
@AInit
@Override
public void initProcessor() {
super.initProcessor();
}
@Dispatch(clazz = UploadTrUploadStationResultUnit.class)
protected Code sendUploadTrUploadStationResultUnit(UploadTrUploadStationResultUnit uploadUnit, ProcessResult processResult) throws LookupException {
Code sendCode = Code.OK;
try {
// call the desired ims api
Result_trUploadStationResult result = services.getIMSApiService().trUploadStationResult(getImsSession(), uploadUnit.getStationNumber(),
uploadUnit.getPartNumber(), uploadUnit.getBomVersion(), uploadUnit.getBomIndex(), uploadUnit.getBomVersionErp(),
uploadUnit.getWorkOrderNumber(), uploadUnit.getBookDate(), uploadUnit.getSerialUnitTrace(), uploadUnit.getStationResultUploadKeys(),
uploadUnit.getStationResultUploadValues());
if (result.return_value < 0) {
ItacMesErrorCode code = ItacMesErrorCodeIMSApi.get(result.return_value);
processResult.setDetailCode(result.return_value);
processResult.setDetailText("sendUploadTrUploadStationResultUnit() failed: " + code.getDefaultText());
} else if (result.return_value > 0) {
processResult.setDetailCode(result.return_value);
processResult.setDetailText("sendUploadTrUploadStationResultUnit() failed: " + getImsApiErrorMessage(result.return_value));
} else {
sendCode = Code.OK;
}
} catch (Exception t) {
handleException(t, getMethodDescription(), processResult);
sendCode = Code.NOT_SENT;
}
return sendCode;
}
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.application;
import static org.junit.Assert.assertEquals;
import java.io.File;
import org.junit.Test;
/**
* @author frankp
* @since 9.10.00
*/
public class E63SessionLayerTest {
@Test
public void test() {
E63SessionLayer testee = new E63SessionLayer();
testee.setMaxSession(3);
File tempDirectory = new File(System.getProperty("java.io.tmpdir"));
File subDir = new File(tempDirectory, "" + System.currentTimeMillis());
String f1 = new File(subDir, "SESS0000.REQ").getName();
String f2 = new File(subDir, "SESS0001.REQ").getName();
String f3 = new File(subDir, "SESS0002.REQ").getName();
String[] sessionFiles = new String[] { f1, f2, f3 };
testee.setSessionFileNames(sessionFiles);
assertEquals("no free session available", -1, testee.getNextSessionNumber());
subDir.delete();
}
@Test
public void shouldReturnNewSessionImmediately() {
E63SessionLayer testee = new E63SessionLayer();
testee.setMaxSession(3);
String f1 = "SESS0000.REQ";
String f2 = "SESS0001.REQ";
String f3 = "SESS0003.REQ";
String[] sessionFiles = new String[] { f1, f2, f3 };
testee.setSessionFileNames(sessionFiles);
assertEquals("next free session not calculated", 2, testee.getNextSessionNumber());
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import static org.junit.Assert.assertEquals;
import java.util.GregorianCalendar;
import org.junit.Test;
/**
* @author frankp
* @since 9.10.00
*/
public class AlarmEventRecordTest {
@Test
public void test() {
AlarmEventRecord testee = new AlarmEventRecord();
testee.setContent("1,19971208,11:50:31,1103,1,0003,\"Value ot of Range\"");
assertEquals(1, testee.getUniqueNumber());
assertEquals(new GregorianCalendar(1997, 11, 8, 11, 50, 31).getTime(), testee.getDate());
assertEquals(1103, testee.getCycleCounter());
assertEquals(1, testee.getAlarmSet());
assertEquals(3, testee.getAlarmNumber());
assertEquals("\"Value ot of Range\"", testee.getAlarmText());
}
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
/**
* @author frankp
* @since 9.10.00
*/
public class E63FileUnitTest {
@Test
public void shouldInitOnCreate() {
E63FileUnit testee = new E63FileUnit();
assertNotNull(testee.uploadUnitList);
assertNotNull(testee.processResultList);
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import com.itac.mes.datainterface.application.E63FormatException;
/**
* @author frankp
* @since 9.10.00
*/
public class E63PresentationResponseFileTest {
@Test
public void test() throws E63FormatException {
E63PresentationResponseFile testee = new E63PresentationResponseFile();
testee.set("", "");
assertEquals("No Commands in file", 0, testee.getResponses().size());
}
public void shouldCreateOneOkResponse() throws E63FormatException {
E63PresentationResponseFile testee = new E63PresentationResponseFile();
testee.set("", "COMMAND 1 PROCESSED \"JOB command\" 20181108 12:15:32 ;");
assertEquals(1, testee.getResponses().size());
}
@Test
public void shouldCreateMultipleOkResponse() throws E63FormatException {
E63PresentationResponseFile testee = new E63PresentationResponseFile();
testee.set("", "COMMAND 1 PROCESSED \"JOB command\" 20181108 12:15:32 ;\n" +
"COMMAND 2 PROCESSED \"JOB command\" 20181108 12:15:32 ;\n" +
"COMMAND 3 PROCESSED \"JOB command\" 20181108 12:15:32 ;\n" +
"COMMAND 4 PROCESSED \"JOB command\" 20181108 12:15:32 ;");
assertEquals(4, testee.getResponses().size());
assertEquals(1, testee.getResponses().get(0).getRequestFileCommand());
assertEquals(2, testee.getResponses().get(1).getRequestFileCommand());
assertEquals(3, testee.getResponses().get(2).getRequestFileCommand());
assertEquals(4, testee.getResponses().get(3).getRequestFileCommand());
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import com.itac.mes.datainterface.application.E63FormatException;
/**
* @author frankp
* @since 9.10.00
*/
public class E63SessionResponseFileTest {
@Test
public void shouldNotFailWithoutContent() throws E63FormatException {
E63SessionResponseFile testee = new E63SessionResponseFile().setContent("SESS0002.RSP", null);
assertEquals(2, testee.getSessionNumber());
assertEquals(0, testee.getResponses().size());
}
@Test(expected = E63FormatException.class)
public void shouldThrowWhenFileNameInvalid() throws E63FormatException {
new E63SessionResponseFile().setContent("", null);
}
@Test
public void test() throws E63FormatException {
String text = "00000000 PROCESSED \"alles ok\";\n" +
"00000001 PROCESSED \"alles ok\";";
E63SessionResponseFile testee = new E63SessionResponseFile().setContent("SESS0002.RSP", text);
assertEquals(2, testee.getResponses().size());
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import com.itac.mes.datainterface.application.E63FormatException;
/**
* @author frankp
* @since 9.10.00
*/
public class EventRequestTest {
@Test(expected = E63FormatException.class)
public void shouldFailWithoutEventName() throws E63FormatException {
EventRequest testee = new EventRequest();
testee.setFileSpec("\\\\itacsv11\\event.dat");
testee.getRequestContent();
}
@Test(expected = E63FormatException.class)
public void shouldFailWithoutEventFileName() throws E63FormatException {
EventRequest testee = new EventRequest();
testee.setEventName("myEventName");
testee.getRequestContent();
}
@Test(expected = E63FormatException.class)
public void shouldFailWithoutReportmode() throws E63FormatException {
EventRequest testee = new EventRequest();
testee.setEventName("myEventName");
testee.setFileSpec("\\\\itacsv11\\event.dat");
testee.setReportMode(ReportFileMode.OFF);
testee.getRequestContent();
}
@Test
public void test() throws E63FormatException {
EventRequest testee = new EventRequest();
testee.setEventName("myEventName");
testee.setFileSpec("\\\\itacsv11\\event.dat");
assertEquals("EVENT myEventName ALARMS REWRITE \"\\\\itacsv11\\event.dat\" START IMMEDIATE STOP NEVER;", testee.getRequestContent());
}
@Test
public void shouldCreateWithAppend() throws E63FormatException {
EventRequest testee = new EventRequest();
testee.setEventName("myEventName");
testee.setFileSpec("\\\\itacsv11\\event.dat");
testee.setReportMode(ReportFileMode.APPEND);
assertEquals("EVENT myEventName ALARMS APPEND \"\\\\itacsv11\\event.dat\" START IMMEDIATE STOP NEVER;", testee.getRequestContent());
}
@Test
public void shouldCreateWithStartStop() throws E63FormatException {
EventRequest testee = new EventRequest();
testee.setEventName("myEventName");
testee.setFileSpec("\\\\itacsv11\\event.dat");
testee.setStartSpec("yesterday");
testee.setStopSpec("tomorrow");
assertEquals("EVENT myEventName ALARMS REWRITE \"\\\\itacsv11\\event.dat\" START yesterday STOP tomorrow;", testee.getRequestContent());
}
@Test
public void shouldCreateWithEventType() throws E63FormatException {
EventRequest testee = new EventRequest();
testee.setEventName("myEventName");
testee.setFileSpec("\\\\itacsv11\\event.dat");
testee.setEventType("MESSAGES");
assertEquals("EVENT myEventName MESSAGES REWRITE \"\\\\itacsv11\\event.dat\" START IMMEDIATE STOP NEVER;", testee.getRequestContent());
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
/**
* @author frankp
* @since 9.10.00
*/
public class EventResponseTest {
@Test
public void shouldParseAlarmResponse() {
AlarmEventResponse testee = new AlarmEventResponse();
testee.setContent(" 1,19971208,11:50:31,1103,1,0003,\"Value ot of Range\"\n" +
" 2,19971208,11:50:31,1103,2,0010,\"Clamping force too high\"");
assertEquals(2, testee.getEventRecords().size());
AlarmEventRecord evtRec = (AlarmEventRecord) testee.getEventRecords().get(0);
assertEquals(1, evtRec.getAlarmSet());
assertEquals(3, evtRec.getAlarmNumber());
assertEquals("\"Value ot of Range\"", evtRec.getAlarmText());
AlarmEventRecord evtRec2 = (AlarmEventRecord) testee.getEventRecords().get(1);
assertEquals(2, evtRec2.getAlarmSet());
assertEquals(10, evtRec2.getAlarmNumber());
assertEquals("\"Clamping force too high\"", evtRec2.getAlarmText());
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
/**
* @author frankp
* @since 9.10.00
*/
public class FunctionTokenTest {
@Test
public void shouldGet() {
FunctionToken testee = FunctionToken.getByAbbreviation("Brl");
assertEquals(FunctionToken.BRL, testee);
}
@Test
public void shouldFail() {
FunctionToken testee = FunctionToken.getByAbbreviation("NOTAVAILABLE");
assertEquals(null, testee);
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import com.itac.mes.datainterface.application.E63FormatException;
/**
* @author frankp
* @since 9.10.00
*/
public class JobRequestTest {
@Test(expected = E63FormatException.class)
public void shouldThrowWithoutJobAndFileSpec() throws E63FormatException {
JobRequest testee = new JobRequest();
testee.getRequestContent();
}
@Test(expected = E63FormatException.class)
public void shouldThrowWithoutFileSpec() throws E63FormatException {
JobRequest testee = new JobRequest();
testee.setJobName("okjob");
testee.getRequestContent();
}
@Test(expected = E63FormatException.class)
public void shouldThrowWithJobTooLong() throws E63FormatException {
JobRequest testee = new JobRequest();
testee.setJobName("job too long job too long job too long");
}
@Test
public void shouldCretaeValidContent() throws E63FormatException {
JobRequest testee = new JobRequest();
testee.setJobName("jobok");
testee.setFileSpec("\\\\srv\\file.x");
String result = testee.getRequestContent();
assertNotNull(result);
assertEquals("JOB jobok RESPONSE \"\\\\srv\\file.x\";", result);
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import static org.junit.Assert.assertEquals;
import java.util.GregorianCalendar;
import org.junit.Test;
import com.itac.mes.datainterface.application.E63FormatException;
/**
* @author frankp
* @since 9.10.00
*/
public class JobResponseTest {
@Test
public void shouldParseValidOkResponse() throws E63FormatException {
String validResponse = "COMMAND 1 PROCESSED \"processed\" 20181104 12:34:56;";
JobResponse testee = new JobResponse();
testee.set("", validResponse);
assertEquals(1, testee.getCounter());
assertEquals(E63ResponseCode.PROCESSED, testee.getProcessedState());
assertEquals("\"processed\"", testee.getResponseInformation());
assertEquals( new GregorianCalendar(2018, 10, 4, 12, 34, 56).getTime() , testee.getDate());
}
@Test
public void shouldParseValidErrorResponse() throws E63FormatException {
String validResponse = "COMMAND 1 ERROR 06 00000001 \"not processed\" 20181104 12:34:56;";
JobResponse testee = new JobResponse();
testee.set("", validResponse);
assertEquals(1, testee.getCounter());
assertEquals(E63ResponseCode.ERROR , testee.getProcessedState());
assertEquals("\"not processed\"", testee.getResponseInformation());
assertEquals("06", testee.getErrorClass());
assertEquals(1, testee.getResponseErrorCode());
assertEquals( new GregorianCalendar(2018, 10, 4, 12, 34, 56).getTime() , testee.getDate());
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
/**
* @author frankp
* @since 9.10.00
*/
public class MiscellaneousTest {
@Test
public void shouldGet() {
Miscellaneous testee = Miscellaneous.getByAbbreviation("Ave");
assertEquals(Miscellaneous.AVE, testee);
}
@Test
public void shouldFail() {
Miscellaneous testee = Miscellaneous.getByAbbreviation("NOTAVAILABLE");
assertEquals(null, testee);
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.GregorianCalendar;
import org.junit.Test;
/**
* @author frankp
* @since 9.10.00
*/
public class PresentationResponseTest {
@Test
public void shouldParseOKFile() {
PresentationResponse testee = new PresentationResponse("COMMAND 2 PROCESSED \"JOB command\" 20181108 12:15:32 ;\n");
assertNotNull(testee);
assertEquals(E63ResponseCode.PROCESSED, testee.getResult());
assertEquals(2, testee.getRequestFileCommand());
assertEquals("\"JOB command\"", testee.getCommandResponse());
assertEquals(new GregorianCalendar(2018, 10, 8, 12, 15, 32).getTime(), testee.getDate());
}
public void shouldParseErrorFile() {
PresentationResponse testee = new PresentationResponse("COMMAND 4 ERROR 05 12345678 \"JOB error desc\" 20181108 12:15:32 ;\n");
assertNotNull(testee);
assertEquals(E63ResponseCode.ERROR, testee.getResult());
assertEquals(4, testee.getRequestFileCommand());
assertEquals("05", testee.getErrorClass());
assertEquals("\"JOB error desc\"", testee.getErrorDescription());
assertEquals("12345678", testee.getPresentationResponseErrorCode());
assertEquals(new GregorianCalendar(2018, 10, 8, 12, 15, 32).getTime(), testee.getDate());
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
/**
* @author frankp
* @since 9.10.00
*/
public class ReportRequestTest {
@Test
public void shouldSubscribeCyclicTime() throws Exception {
ReportRequest testee = new ReportRequest();
testee.setReportName("REPONAME");
testee.setFileSpec("\"\\itacsv11\\report.rep\"");
testee.setReportMode(ReportFileMode.APPEND);
testee.setExecution(ExecutionType.CYCLIC, new Duration("01:02:03"), 0);
testee.addParameter("ActValUnk");
assertEquals(
"REPORT REPONAME APPEND \"\\itacsv11\\report.rep\" \nSTART IMMEDIATE \nSTOP NEVER CYCLIC TIME 01:02:03 \nPARAMETERS DATE,TIME,COUNT,ActValUnk;",
testee.getRequestContent());
}
@Test
public void shouldSubscribeCyclicShots() throws Exception {
ReportRequest testee = new ReportRequest();
testee.setReportName("REPONAME");
testee.setFileSpec("\"\\itacsv11\\report.rep\"");
testee.setReportMode(ReportFileMode.APPEND);
testee.setExecution(ExecutionType.COUNTER, new Duration("01:02:03"), 4);
testee.addParameter("ActValUnk");
assertEquals(
"REPORT REPONAME APPEND \"\\itacsv11\\report.rep\" \nSTART IMMEDIATE \nSTOP NEVER CYCLIC SHOT 4 \nPARAMETERS DATE,TIME,COUNT,ActValUnk;",
testee.getRequestContent());
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import static org.junit.Assert.assertEquals;
import java.util.GregorianCalendar;
import org.junit.Test;
/**
* @author frankp
* @since 9.10.00
*/
public class ReportResponseTest {
@Test
public void test() {
// ReportRequest request = new ReportRequest();
// request.addParameter("ActCntCyc");
// request.addParameter("ActCntCycRej");
// request.addParameter("ActFrcClp");
// request.addParameter("@ActMyPara");
ReportResponse testee = new ReportResponse();
testee.setContent(
"DATE, TIME, COUNT ,ActCntCyc,ActCntCycRej,@ActMyPara\n " +
"19971208,10:15:50,1,1000,5,800.4,30.6\n" +
"19971208,10:16:10,2,1001,5,800.3,30.2\n" +
"19971208,10:16:30,3,1002,6,799.9,31.0\n" +
"19971208,10:16:50,4,1003,6,800.0,30.0\n" +
"19971208,10:17:10,5,1004,6,800.1,30.1");
assertEquals(5, testee.getRecords().size());
assertEquals("19971208", testee.getRecords().get(0).get("DATE"));
assertEquals("10:15:50", testee.getRecords().get(0).get("TIME"));
assertEquals(new GregorianCalendar(1997, 11, 8, 10, 15, 50).getTime(), testee.getRecords().get(0).getDate());
assertEquals("1", testee.getRecords().get(0).get("COUNT"));
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
/**
* @author frankp
* @since 9.10.00
*/
public class SessionRequestTest {
@Test
public void test() {
SessionRequest testee = new SessionRequest();
testee.setSessionNumber(4122);
assertEquals("SESS4122.REQ", testee.getFileName());
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import com.itac.mes.datainterface.application.E63FormatException;
/**
* @author frankp
* @since 9.10.00
*/
public class SessionResponseTest {
@Test
public void shouldCreatePassResponse() throws E63FormatException {
SessionResponse testee = new SessionResponse().setContent("01234567 PROCESSED processed ;");
assertEquals(1234567, testee.getSessionCommandIdentifier());
assertEquals(E63ResponseCode.PROCESSED, testee.getProcessedState());
assertEquals("ErrorClass should be undefined when result is processed", "", testee.getErrorClass());
assertEquals("ResponseErrorCode should be undefined when result is processed", 0, testee.getResponseErrorCode());
assertEquals("processed", testee.getResponseInformation());
assertEquals("Response Error description should be empty when result is processed", "", testee.getErrorDescription());
}
@Test
public void shouldCreateErrorResponse() throws E63FormatException {
SessionResponse testee = new SessionResponse().setContent("01234567 ERROR 05 00112233 \"Error with spaces\" ;");
assertEquals(1234567, testee.getSessionCommandIdentifier());
assertEquals("ResponseInformation should be empty when result is error", "", testee.getResponseInformation());
assertEquals(E63ResponseCode.ERROR, testee.getProcessedState());
assertEquals("05", testee.getErrorClass());
assertEquals(112233, testee.getResponseErrorCode());
assertEquals("Error with spaces", testee.getErrorDescription());
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
/**
* @author frankp
* @since 9.10.00
*/
public class TypeTokenTest {
@Test
public void shouldGet() {
TypeToken testee = TypeToken.getByAbbreviation("Set");
assertEquals(TypeToken.SET, testee);
}
@Test
public void shouldFail() {
TypeToken testee = TypeToken.getByAbbreviation("NOTAVAILABLE");
assertEquals(null, testee);
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.data;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
/**
* @author frankp
* @since 9.10.00
*/
public class UnitTokenTest {
@Test
public void shouldGet() {
UnitToken testee = UnitToken.getByAbbreviation("Cfg");
assertEquals(UnitToken.CFG, testee);
}
@Test
public void shouldFail() {
UnitToken testee = UnitToken.getByAbbreviation("NOTAVAILABLE");
assertEquals(null, testee);
}
}

View File

@@ -0,0 +1,138 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.datasource;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import org.junit.Test;
import com.itac.mes.datainterface.ConfigurationException;
import com.itac.mes.datainterface.DataInterfaceConfiguration;
import com.itac.mes.datainterface.application.E63Application;
import com.itac.mes.datainterface.data.Duration;
import com.itac.mes.datainterface.data.Station;
import com.itac.mes.datainterface.data.Toolbox;
import com.itac.mes.datainterface.filehandler.Euromap63FileHandler;
import com.itac.mes.datainterface.filehandler.IFileHandler;
import com.itac.mes.datainterface.parser.Euromap63Parser;
import com.itac.mes.datainterface.parser.IParser;
import com.itac.mes.datainterface.process.Euromap63Processor;
import com.itac.mes.datainterface.process.IProcessor;
/**
* @author frankp
*
*/
public class Euromap63FileSourceTest {
public Toolbox getToolboxMock() {
Toolbox mockObject = mock(Toolbox.class);
when(mockObject.hasConditionMapping()).thenReturn(true);
when(mockObject.hasMessageMapping()).thenReturn(true);
when(mockObject.getStatus("PASS")).thenReturn(0);
when(mockObject.getLayer(anyString())).thenReturn(-1);
when(mockObject.getLayer("_T")).thenReturn(0);
when(mockObject.getLayer("_B")).thenReturn(1);
when(mockObject.getLayer("_W")).thenReturn(3);
when(mockObject.getConditionCode("2")).thenReturn("Fuji2");
when(mockObject.getConditionCode("3")).thenReturn("Fuji3");
when(mockObject.getMessageCode("1")).thenReturn("Fuji_R1");
when(mockObject.getMessageCode("4")).thenReturn("-1");
when(mockObject.getMessageCode("5")).thenReturn("Fuji_R5");
when(mockObject.getFailcode("0")).thenReturn(0);
when(mockObject.getTextcode("0")).thenReturn("0");
when(mockObject.getStation("Machine1")).thenReturn(new Station("Machine1", "12012010", false));
when(mockObject.getStation("machine1")).thenReturn(new Station("machine1", "12012010", false));
when(mockObject.getStation("Machine2")).thenReturn(new Station("Machine2", "12012011", false));
when(mockObject.getStation("pmmachine1")).thenReturn(new Station("pmmachine1", "12012011", false));
when(mockObject.getStatusMap()).thenReturn(new Hashtable<>());
return mockObject;
}
@Test(expected = ConfigurationException.class)
public void shouldNotAcceptNullMachines() throws ConfigurationException {
Euromap63FileSource testee = new Euromap63FileSource();
DataInterfaceConfiguration config = mock(DataInterfaceConfiguration.class);
when(config.getValue("datasource.euromap63.interval", Duration.class)).thenReturn(new Duration("00:00:02,000"));
when(config.getValue("datasource.euromap63.sessionDir", String.class)).thenReturn("./session");
when(config.getValue("datasource.euromap63.presentationDir", String.class)).thenReturn(".presentation");
when(config.getValue("datasource.euromap63.applicationDir", String.class)).thenReturn(".application");
when(config.getValue("datasource.euromap63.machineNames", List.class)).thenReturn(new ArrayList<Object>());
when(config.getValue("datasource.euromap63.autorun", Boolean.class)).thenReturn(new Boolean(false));
testee.setHandler(config, DataInterfaceConfiguration.class);
testee.setHandler(getToolboxMock(), Toolbox.class);
testee.setHandler(mock(Euromap63Parser.class), IParser.class);
testee.setHandler(mock(Euromap63Processor.class), IProcessor.class);
testee.setHandler(mock(Euromap63FileHandler.class), IFileHandler.class);
testee.setHandler(mock(Toolbox.class), Toolbox.class);
testee.setHandler(mock(E63Application.class), E63Application.class);
testee.setMachineNames(null);
testee.configure();
testee.callAtInit();
}
@Test(expected = ConfigurationException.class)
public void shouldNotAcceptEmptyMachines() throws ConfigurationException {
Euromap63FileSource testee = new Euromap63FileSource();
DataInterfaceConfiguration config = mock(DataInterfaceConfiguration.class);
when(config.getValue("datasource.euromap63.interval", Duration.class)).thenReturn(new Duration("00:00:02,000"));
when(config.getValue("datasource.euromap63.sessionDir", String.class)).thenReturn("./session");
when(config.getValue("datasource.euromap63.presentationDir", String.class)).thenReturn(".presentation");
when(config.getValue("datasource.euromap63.applicationDir", String.class)).thenReturn(".application");
when(config.getValue("datasource.euromap63.machineNames", List.class)).thenReturn(new ArrayList<Object>());
when(config.getValue("datasource.euromap63.autorun", Boolean.class)).thenReturn(new Boolean(false));
testee.setHandler(config, DataInterfaceConfiguration.class);
testee.setHandler(getToolboxMock(), Toolbox.class);
testee.setHandler(mock(Euromap63Parser.class), IParser.class);
testee.setHandler(mock(Euromap63Processor.class), IProcessor.class);
testee.setHandler(mock(Euromap63FileHandler.class), IFileHandler.class);
testee.setHandler(mock(Toolbox.class), Toolbox.class);
testee.setHandler(mock(E63Application.class), E63Application.class);
testee.setMachineNames(new ArrayList<>());
testee.configure();
testee.callAtInit();
}
@Test
public void shouldAcceptSingleMachines() throws ConfigurationException {
Euromap63FileSource testee = new Euromap63FileSource();
DataInterfaceConfiguration config = mock(DataInterfaceConfiguration.class);
when(config.getValue("datasource.euromap63.interval", Duration.class)).thenReturn(new Duration("00:00:02,000"));
when(config.getValue("datasource.euromap63.sessionDir", String.class)).thenReturn("./session");
when(config.getValue("datasource.euromap63.presentationDir", String.class)).thenReturn(".presentation");
when(config.getValue("datasource.euromap63.applicationDir", String.class)).thenReturn(".application");
when(config.getValue("datasource.euromap63.machineNames", List.class)).thenReturn(new ArrayList<Object>());
when(config.getValue("datasource.euromap63.autorun", Boolean.class)).thenReturn(new Boolean(false));
testee.setHandler(config, DataInterfaceConfiguration.class);
testee.setHandler(getToolboxMock(), Toolbox.class);
testee.setHandler(mock(Euromap63Parser.class), IParser.class);
testee.setHandler(mock(Euromap63Processor.class), IProcessor.class);
testee.setHandler(mock(Euromap63FileHandler.class), IFileHandler.class);
testee.setHandler(mock(E63Application.class), E63Application.class);
testee.configure();
List<String> machineList = new ArrayList<>();
machineList.add("machine1");
testee.setMachineNames(machineList);
testee.callAtInit();
}
}

View File

@@ -0,0 +1,130 @@
/*
* Copyright (c) 2018 iTAC Software AG, Germany. All Rights Reserved.
*
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
* without the written permission of iTAC Software AG.
*/
package com.itac.mes.datainterface.parser;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import org.junit.Test;
import com.itac.mes.datainterface.ConfigurationException;
import com.itac.mes.datainterface.application.E63Application;
import com.itac.mes.datainterface.application.E63ProcessException;
import com.itac.mes.datainterface.data.Duration;
import com.itac.mes.datainterface.data.ExecutionType;
import com.itac.mes.datainterface.data.ReportResponse;
import com.itac.mes.datainterface.data.Station;
import com.itac.mes.datainterface.data.Toolbox;
/**
* @author frankp
*
*/
public class Euromap63ParserTest {
public Toolbox getToolboxMock() {
Toolbox mockObject = mock(Toolbox.class);
when(mockObject.hasConditionMapping()).thenReturn(true);
when(mockObject.hasMessageMapping()).thenReturn(true);
when(mockObject.getStatus("PASS")).thenReturn(0);
when(mockObject.getLayer(anyString())).thenReturn(-1);
when(mockObject.getLayer("_T")).thenReturn(0);
when(mockObject.getLayer("_B")).thenReturn(1);
when(mockObject.getLayer("_W")).thenReturn(3);
when(mockObject.getConditionCode("2")).thenReturn("Fuji2");
when(mockObject.getConditionCode("3")).thenReturn("Fuji3");
when(mockObject.getMessageCode("1")).thenReturn("Fuji_R1");
when(mockObject.getMessageCode("4")).thenReturn("-1");
when(mockObject.getMessageCode("5")).thenReturn("Fuji_R5");
when(mockObject.getFailcode("0")).thenReturn(0);
when(mockObject.getTextcode("0")).thenReturn("0");
when(mockObject.getStation("Machine1")).thenReturn(new Station("Machine1", "12012010", false));
when(mockObject.getStation("machine1")).thenReturn(new Station("machine1", "12012010", false));
when(mockObject.getStation("Machine2")).thenReturn(new Station("Machine2", "12012011", false));
when(mockObject.getStation("pmmachine1")).thenReturn(new Station("pmmachine1", "12012011", false));
when(mockObject.getStatusMap()).thenReturn(new Hashtable<>());
return mockObject;
}
@Test
public void shouldParse() throws ConfigurationException, E63ProcessException {
Euromap63Parser testee = new Euromap63Parser();
testee.setHandler(getToolboxMock(), Toolbox.class);
List<String> valueList = new ArrayList<>();
valueList.add("DATE");
valueList.add("TIME");
valueList.add("COUNT");
valueList.add("ActCntCyc");
valueList.add("@ActMyPara");
testee.setReportParameterNames(valueList) ;
assertEquals( 5, testee.getReportParameterNames().size()) ;
ReportResponse reportResponse = new ReportResponse();
reportResponse.setContent(
"DATE, TIME, COUNT ,ActCntCyc,ActCntCycRej,@ActMyPara\n " +
"19971208,10:15:50,1,1000,5,800.4,30.6,1.1\n" +
"19971208,10:16:10,2,1001,5,800.3,30.2,2.2\n" +
"19971208,10:16:30,3,1002,6,799.9,31.0,3.3\n" +
"19971208,10:16:50,4,1003,6,800.0,30.0,4.4\n" +
"19971208,10:17:10,5,1004,6,800.1,30.1,5.5");
testee.parse(reportResponse, "machine1");
}
@Test
public void shouldHaveDefault() throws ConfigurationException, E63ProcessException {
Euromap63Parser testee = new Euromap63Parser();
assertEquals(ExecutionType.CYCLIC, testee.getExecutionTypeDefault() );
testee.setExecutionType(ExecutionType.COUNTER.ordinal());
assertEquals(ExecutionType.COUNTER, testee.getExecutionType() );
testee.setInterval(new Duration("00:01:00,000"));
assertEquals(60000, testee.getExecutionInterval().getMillies());
}
@Test(expected = ConfigurationException.class)
public void shouldThrowTooShortInterval() throws ConfigurationException, E63ProcessException {
Euromap63Parser testee = new Euromap63Parser();
testee.setInterval(new Duration("00:00:01,000"));
}
@Test(expected = ConfigurationException.class)
public void shouldThrowTooLongInterval() throws ConfigurationException, E63ProcessException {
Euromap63Parser testee = new Euromap63Parser();
testee.setInterval(new Duration("100:00:00,000"));
}
@Test
public void shouldInitProperly() throws ConfigurationException, E63ProcessException {
Euromap63Parser testee = new Euromap63Parser();
testee.setExecutionType(ExecutionType.COUNTER.ordinal());
testee.setExecutionCounter(12);
testee.setInterval(new Duration ("00:01:00,000"));
List<String> valueList = new ArrayList<>();
valueList.add("DATE");
valueList.add("TIME");
valueList.add("COUNT");
valueList.add("ActCntCyc");
valueList.add("@ActMyPara");
testee.setReportParameterNames(valueList) ;
testee.setHandler(mock(E63Application.class), E63Application.class );
testee.init();
}
}