@p2olab/pimad-core
Version:
PiMAd (Process-industry-Modular-Automation-description) High level access to automation of modular plants.
264 lines (263 loc) • 11.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ZIPGate = exports.XMLGate = exports.MTPGate = exports.MockGate = exports.AMLGate = void 0;
const GateFactory_1 = require("./GateFactory");
const fileSystem = require("fs");
const xml2jsonParser = require("xml2json");
const rimraf = require("rimraf");
const Utils_1 = require("../../Utils");
const Backbone_1 = require("../../Backbone");
var PiMAdResponseVendor = Backbone_1.Backbone.PiMAdResponseVendor;
const AdmZip = require("adm-zip");
/**
* AGate is an abstract implementation of the Gate-Interface. Mainly this one reduces the code.
*/
class AGate {
constructor() {
this.initialized = false;
this.gateAddress = undefined;
this.responseVendor = new PiMAdResponseVendor();
}
send(instructions, callback) {
const localResponse = this.responseVendor.buyErrorResponse();
localResponse.initialize('Not implemented yet!', {});
callback(localResponse);
}
getGateAddress() {
return this.gateAddress;
}
initialize(address) {
if (!this.initialized) {
this.gateAddress = address;
this.initialized = (this.gateAddress == address);
return this.initialized;
}
else {
return false;
}
}
}
/**
* An AFileSystemGate allows the access to the local file system.
*/
class AFileSystemGate extends AGate {
constructor() {
super();
this.fileSystem = fileSystem;
}
/**
* This function cuts of the last four characters of the input string. F. ex.: test.xml -\> test
* @param fileName - The name of the file as String.
*/
static getFileType(fileName) {
return fileName.slice(-4);
}
}
/**
* A AMLGate is an abstraction layer to interact with AML-Files.
*/
class AMLGate extends AFileSystemGate {
constructor() {
super();
this.xmlGateFactory = new GateFactory_1.XMLGateFactory();
}
receive(instructions, callback) {
if (this.initialized) {
const xmlGate = this.xmlGateFactory.create();
xmlGate.initialize('' + this.gateAddress);
xmlGate.receive(instructions, response => {
if (response.constructor.name === this.responseVendor.buySuccessResponse().constructor.name) {
const content = response.getContent();
const localResponse = this.responseVendor.buySuccessResponse();
localResponse.initialize('Success!', { data: content.data });
Utils_1.logger.info('Successfully parsed the AML-File at ' + this.gateAddress);
callback(localResponse);
}
else {
Utils_1.logger.error('Could not parse the AML-File at ' + this.gateAddress);
callback(this.responseVendor.buyErrorResponse());
}
});
}
else {
const notInitialized = this.responseVendor.buyErrorResponse();
Utils_1.logger.error('Use of a non-initialized AML-Gate. This one rejects the Request!');
notInitialized.initialize('The Gate is not initialized yet! Aborting ... ', {});
callback(notInitialized);
}
}
}
exports.AMLGate = AMLGate;
/**
* A MockGate let test your implementation and converter logic. It has no relevant function.
*/
class MockGate extends AGate {
send(instructions, callback) {
Utils_1.logger.debug('Send ' + instructions + ' to ' + this.getGateAddress());
const response = this.responseVendor.buySuccessResponse();
response.initialize('This is a send-response of a mock gate.', instructions);
callback(response);
}
receive(instructions, callback) {
if (this.initialized) {
const response = this.responseVendor.buySuccessResponse();
response.initialize('This is a receive-response of a mock gate.', instructions);
callback(response);
}
else {
const notInitialized = this.responseVendor.buyErrorResponse();
Utils_1.logger.error('Use of a non-initialized Mock-Gate. This one rejects the Request!');
notInitialized.initialize('The Gate is not initialized yet! Aborting ... ', {});
callback(notInitialized);
}
}
constructor() {
super();
this.gateAddress = 'Valinor';
}
}
exports.MockGate = MockGate;
/**
* A MTPGate is an abstraction layer to interact with MTP-Archives.
*/
class MTPGate extends AFileSystemGate {
constructor() {
super();
this.zipGateFactory = new GateFactory_1.ZIPGateFactory();
}
receive(instructions, callback) {
if (this.initialized) {
const zipGate = this.zipGateFactory.create();
zipGate.initialize('' + this.gateAddress);
zipGate.receive({}, response => {
if (response.constructor.name === this.responseVendor.buySuccessResponse().constructor.name) {
const zipGateResponse = response.getContent();
const mtpGateResponse = this.responseVendor.buySuccessResponse();
mtpGateResponse.initialize('Success!', { data: zipGateResponse.data });
callback(mtpGateResponse);
}
else {
callback(this.responseVendor.buyErrorResponse());
}
});
}
else {
const notInitialized = this.responseVendor.buyErrorResponse();
Utils_1.logger.error('Use of a non initialized MTP-Gate. This one rejects the Request!');
notInitialized.initialize('The Gate is not initialized yet! Aborting ... ', {});
callback(notInitialized);
}
}
}
exports.MTPGate = MTPGate;
/**
* A XMLGate is an abstraction layer to interact with XML-Files.
*/
class XMLGate extends AFileSystemGate {
receive(instructions, callback) {
if (this.initialized) {
this.fileSystem.readFile('' + this.gateAddress, (error, data) => {
if (!error) {
const json = xml2jsonParser.toJson(data.toString(), { object: true });
const xmlGateResponse = this.responseVendor.buySuccessResponse();
xmlGateResponse.initialize('Success!', { data: json });
Utils_1.logger.info('Successfully parsed the XML-File at ' + this.gateAddress);
callback(xmlGateResponse);
}
else {
Utils_1.logger.error('Could not parse the XML-File at ' + this.gateAddress);
callback(this.responseVendor.buyErrorResponse());
}
});
}
else {
const notInitialized = this.responseVendor.buyErrorResponse();
Utils_1.logger.error('Use of a non initialized XML-Gate. This one rejects the Request!');
notInitialized.initialize('The Gate is not initialized yet! Aborting ... ', {});
callback(notInitialized);
}
}
}
exports.XMLGate = XMLGate;
/**
* A ZIPGate is an abstraction layer to interact with ZIP-Archives.
*/
class ZIPGate extends AFileSystemGate {
constructor() {
super();
this.xmlGateFactory = new GateFactory_1.XMLGateFactory();
this.amlGateFactory = new GateFactory_1.AMLGateFactory();
}
receive(instructions, callback) {
if (this.initialized) {
const zipHandler = new AdmZip(this.gateAddress);
const zipEntries = zipHandler.getEntries(); // an array of ZipEntry records
if (zipEntries.length >= 0) {
const responseData = [];
// this is the path, where files will be extracted to, e.g. uploads/Module (Module.zip)
const folderPath = ('' + this.gateAddress).substr(0, ('' + this.gateAddress).lastIndexOf('.'));
// make sure path does not exist yet (this path will be deleted later anyway)
if (!fileSystem.existsSync(folderPath)) {
// create directory with the filename, e.g. uploads/Module
fileSystem.mkdirSync(folderPath);
}
// extract the zip
zipHandler.extractAllTo(folderPath, true);
// parse the entries ...
zipEntries.forEach((entry) => {
// Supporting different file types
switch (ZIPGate.getFileType(entry.entryName)) {
// TODO: Coding > Generic one
case '.aml': {
const amlGate = this.amlGateFactory.create();
amlGate.initialize(folderPath + '/' + entry.entryName.replace('\\', '/'));
amlGate.receive({}, (response) => {
if (response.constructor.name === this.responseVendor.buySuccessResponse().constructor.name) {
responseData.push(response.getContent());
// Calling the callback in the last loop cycle
const zipGateResponse = this.responseVendor.buySuccessResponse();
zipGateResponse.initialize('Success!', { data: responseData });
// delete the extracted data
rimraf(folderPath, function () {
callback(zipGateResponse);
});
}
});
break;
}
case '.xml': {
const xmlGate = this.xmlGateFactory.create();
xmlGate.initialize(folderPath + '/' + entry.entryName);
xmlGate.receive({}, (response) => {
if (response.constructor.name === this.responseVendor.buySuccessResponse().constructor.name) {
responseData.push(response.getContent());
// Calling the callback in the last loop cycle
const zipGateResponse = this.responseVendor.buySuccessResponse();
zipGateResponse.initialize('Success!', { data: responseData });
// delete the extracted data
rimraf(folderPath, function () {
callback(zipGateResponse);
});
}
});
break;
}
default:
Utils_1.logger.warn('There is an unsupported file type. Ignoring...');
break;
}
});
}
else {
callback(this.responseVendor.buyErrorResponse());
}
}
else {
const notInitialized = this.responseVendor.buyErrorResponse();
Utils_1.logger.error('Use of a non initialized ZIP-Gate. This one rejects the Request!');
notInitialized.initialize('The Gate is not initialized yet! Aborting ... ', {});
callback(notInitialized);
}
}
}
exports.ZIPGate = ZIPGate;