load(__DIR__ + "/./../lib/ext/sha256.js");
console.clear();
//root folder must exist
const ROOT_FOLDER = "D:\\Users\\Simoncellojer\\Documents\\temp\\archistory\\testv1\\";
const DATA_FOLDER = "D:\\Users\\Simoncellojer\\Documents\\temp\\archistory\\";
const CHECKSUM_FILE = DATA_FOLDER + "testv1_checksum_file.txt"
const OUTPUT_FOLDER = ROOT_FOLDER + "site\\"
const HTML_FOLDER = OUTPUT_FOLDER + "views\\"
const IMAGES_FOLDER = OUTPUT_FOLDER + "images\\"
const HTML_BEGIN = "
"
const HTML_END = ""
const HTML_INSERT = "";
//D:\Users\simoncellojer\Documents\temp\archistory
createFolderIfNotExists(OUTPUT_FOLDER);
createFolderIfNotExists(HTML_FOLDER);
createFolderIfNotExists(IMAGES_FOLDER);
//load checksums from file
let checkSums = new Map();
checkSums = loadChecksumFile(CHECKSUM_FILE);
let newContent = "" + new Date().toISOString().split('T')[0] + "
"
//loop on each view of the model
$("archimate-diagram-model").each(function (view) {
if (view.prop("_hide_from_export_") !== "true") {
//compute checksum for this view
let newChecksum = computeChecksum(view)
let oldChecksum = checkSums.get(view.id);
//if checksum has changed
if (oldChecksum === null || oldChecksum === undefined || oldChecksum !== newChecksum.toString()) {
console.log("view changed : " + view.name + " " + oldChecksum + " " + newChecksum)
//add a link to the html page for this view
newContent += "" + view.name + "
" + "\r\n";
//create/update the html page associated with this page
addHistory(view);
//add/replace the checksum to the map
checkSums.set(view.id, newChecksum);
}
}
});
//read the index.html page
let indexFile = OUTPUT_FOLDER + "index.html"
let oldContent = readHistoryFile(indexFile);
//if index.html does not exist yet
if (oldContent.length < 1) {
oldContent = HTML_BEGIN + "History
" + HTML_INSERT + HTML_END;
}
//user a special tag to insert the new content in the html file
newContent = oldContent.replace(HTML_INSERT, HTML_INSERT + newContent);
//write the html file
writeHistoryToFile(indexFile, newContent)
//write the new checksums to file
writeChecksumToFile(CHECKSUM_FILE, checkSums);
console.log("finished");
/***
* Compute a SHA256 from
*
*/
function computeChecksum(view) {
//dumbest method : checksum from the png
//let bytes = $.model.renderViewAsBase64(view, "PNG"); // Get bytes
//compute checksum for this
//let newChecksum = CryptoJS.SHA256(bytes);
//less dumb
//build an array of all concept or element id used in the view
//does not take objet renaming or retyping or specialization changed into account
// but only the most major changes. Reshaping, moving elements in the view does not change the checksum
let viewContent = [];
$(view).find().each(function (el) {
if (el.concept !== null && el.concept !== undefined) {
viewContent.push(el.concept.id);
} else {
viewContent.push(el.id);
}
});
//sort the content in case find() did not return elements in the same order
viewContent = viewContent.sort();
//compute a sha 256
let newChecksum = CryptoJS.SHA256(viewContent.toString());
return newChecksum
}
/**
* log the change for the view in a dedicated file (one file per view)
* @param view
*/
function addHistory(view) {
//get the html file content associated with this view
let htmlFile = HTML_FOLDER + view.id + ".html"
let htmlContent = readHistoryFile(htmlFile);
//if no content, create a new file
if (htmlContent.length < 1) {
htmlContent = HTML_BEGIN + "" + view.name + "
" + HTML_INSERT + HTML_END;
}
// write the png (it is smaller than svg)
//scaling image by half to make comparisons between view versions easier
var options = { scale: 0.5 };
var viewFile = view.id + "-" + Date.now() + ".png"
$.model.renderViewToFile(view, IMAGES_FOLDER + viewFile, "PNG", options);
// replace the tag with the img tag at the beginning of the html content and the current date
let newContent = "" + new Date().toISOString().split('T')[0] + "
"
newContent += "" + "
" + "\r\n";
htmlContent = htmlContent.replace(HTML_INSERT, HTML_INSERT + newContent);
//write the html file if it does not exist yet
writeHistoryToFile(htmlFile, htmlContent)
}
/**
* write a file with one line per view : view.id = sha 256
* @param filePath
* @param checkSums
*/
function writeChecksumToFile(filePath, checkSums) {
let content = "";
for (var [key, value] of checkSums.entries()) {
content += key + "=" + value;
content += "\r\n";
}
writeHistoryToFile(filePath, content)
}
/**
* Read a file with one line per view : view.id = sha 256
* @param filePath
* @returns
*/
function loadChecksumFile(filePath) {
let properties = new Map();
try {
//use java classes to read the content of the properties file
if (checkFileExists(filePath)) {
var ReaderClass = Java.type('java.io.FileReader');
var reader = new ReaderClass(filePath);
var BufferedReaderClass = Java.type('java.io.BufferedReader');
var bf = new BufferedReaderClass(reader);
var line = "";
while ((line = bf.readLine()) != null) {
//ignore comments lines
if (!line.startsWith("#")) {
var idx;
if ((idx = line.indexOf("=")) > -1) {
//extract property name (left of equal sign) and value (right of equal sign)
var key = line.substring(0, idx)
var value = line.substring(idx + 1);
//add this new property
properties.set(key, value);
}
}
}
}
} catch (e) {
console.setTextColor(255, 0, 0)
console.log("loading error:")
console.log(e)
console.setTextColor(0, 0, 0)
exit()
} finally {
return properties;
}
}
function readHistoryFile(filePath) {
//console.log("loading from " + filePath)
let content = "";
try {
//use java classes to read the content of the properties file
if (checkFileExists(filePath)) {
var FileClass = Java.type("java.io.File");
var newModelFile = new FileClass(filePath);
var ReaderClass = Java.type('java.io.FileReader');
var reader = new ReaderClass(newModelFile);
var BufferedReaderClass = Java.type('java.io.BufferedReader');
var bf = new BufferedReaderClass(reader);
var line = "";
while ((line = bf.readLine()) != null) {
content += line
}
}
} catch (e) {
console.setTextColor(255, 0, 0)
console.log("loading error:")
console.log(e)
console.setTextColor(0, 0, 0)
} finally {
return content;
}
}
/**
* write a file with one line per view : view.id = sha 256
* @param filePath
* @param checkSums
*/
function writeHistoryToFile(filePath, content) {
var Stream = Java.type("java.io.FileOutputStream");
var Writer = Java.type("java.io.OutputStreamWriter");
var Buffered = Java.type("java.io.BufferedWriter");
var out = new Buffered(new Writer(new Stream(filePath), "UTF-8"))
try {
out.write(content);
} catch (e) {
console.setTextColor(255, 0, 0)
console.log("loading error:")
console.log(e)
console.setTextColor(0, 0, 0)
}
finally {
out.flush();
out.close();
}
}
function checkFileExists(fileName) {
var FileClass = Java.type('java.io.File');
var file = new FileClass(fileName)
if (file.exists()) {
return true;
} else {
return false;
}
}
function createFolderIfNotExists(folderName) {
console.log("creating", folderName)
if (!checkFileExists(folderName)) {
var FileClass = Java.type('java.io.File');
var folder = new FileClass(folderName)
folder.mkdirs()
while (!checkFileExists(folderName)) {
sleep(500)
//wait for folder to be created otherwise we may get an error when writing html
}
}
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}