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)); }