/** * Writes all updates into files taking into account weather they should be appended to the file * or not. Existing files are overwritten without any further warnings. * * @throws UnmodifiableFunctionException */ private void writePrintInToFileUpdates() throws UnmodifiableFunctionException { FunctionElement fileOutputFunction = capi.getStorage().getFunction(IOPlugin.FILE_OUTPUT_FUNC_NAME); for (Update u : capi.getScheduler().getUpdateSet()) { if (APPEND_ACTION.equals(u.action) || WRITE_ACTION.equals(u.action)) { ListElement outputList = (ListElement) u.value; if (outputList != Element.UNDEF) { // set location to undef to prevent unnecessary output to file fileOutputFunction.setValue(u.loc.args, Element.UNDEF); List<? extends Element> lines = outputList.getList(); // if the path is relative to the MAIN specification file, make it absolute. String path2spec = ""; String fileName = u.loc.args.get(0).toString(); if (!new File(fileName).isAbsolute()) path2spec = capi.getSpec().getFileDir(); String outputFile = Tools.concatFileName(path2spec, fileName); FileWriter fw = null; try { fw = new FileWriter(outputFile, APPEND_ACTION.equals(u.action)); for (Element line : lines) fw.append(line + System.lineSeparator()); } catch (IOException e) { throw new CoreASMError("File " + outputFile + " could not be created."); } finally { if (fw != null) try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } } } } }
/** * Compose write and append print updates. The type write or append as well as the order of the * updates are taken into account. * * @param compAPI */ private void composeAppend(PluginCompositionAPI compAPI) { for (Location l : compAPI.getAffectedLocations()) { if (!FILE_OUTPUT_FUNC_NAME.equals(l.name)) continue; LinkedList<Element> elems1 = new LinkedList<>(); LinkedList<Element> elems2 = new LinkedList<>(); Set<Element> contributingAgents = new HashSet<Element>(); Set<ScannerInfo> contributingNodes = new HashSet<ScannerInfo>(); String action = APPEND_ACTION; // if the second set does not have a basic update, // add all the updates from the first set as well if (!compAPI.isLocUpdatedWithActions(2, l, Update.UPDATE_ACTION)) { for (Update update : compAPI.getLocUpdates(1, l)) { if (APPEND_ACTION.equals(update.action) || WRITE_ACTION.equals(update.action)) { Element value = update.value; if (!(update.value instanceof ListElement)) value = new ListElement(Arrays.asList(new Element[] {value})); ListElement list = (ListElement) value; elems1.addAll(list.getList()); contributingAgents.addAll(update.agents); contributingNodes.addAll(update.sources); } if (WRITE_ACTION.equals(update.action)) action = WRITE_ACTION; } } for (Update update : compAPI.getLocUpdates(2, l)) { if (APPEND_ACTION.equals(update.action) || WRITE_ACTION.equals(update.action)) { Element value = update.value; if (!(update.value instanceof ListElement)) value = new ListElement(Arrays.asList(new Element[] {value})); ListElement list = (ListElement) value; elems2.addAll(list.getList()); contributingAgents.addAll(update.agents); contributingNodes.addAll(update.sources); } if (WRITE_ACTION.equals(update.action)) { action = WRITE_ACTION; elems1.clear(); } } if (!elems1.isEmpty() || !elems2.isEmpty()) { LinkedList<Element> outputResult = elems1; if (outputResult.isEmpty()) outputResult = elems2; else if (!elems2.isEmpty()) { outputResult = new LinkedList<>(); outputResult.addAll(elems1); outputResult.addAll(elems2); } compAPI.addComposedUpdate( new Update( l, new ListElement(new ArrayList<Element>(outputResult)), action, contributingAgents, contributingNodes), this); } } }