All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nl.rrd.wool.parser.WoolProjectParser Maven / Gradle / Ivy

Go to download

WOOL is a simple, powerful dialogue framework for creating virtual agent conversations.

The newest version!
/*
 * Copyright 2019 Roessingh Research and Development.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

package nl.rrd.wool.parser;

import nl.rrd.wool.exception.ParseException;
import nl.rrd.wool.i18n.*;
import nl.rrd.wool.model.WoolDialogue;
import nl.rrd.wool.model.WoolDialogueDescription;
import nl.rrd.wool.model.WoolProject;

import java.io.IOException;
import java.io.Reader;
import java.util.*;

/**
 * This class can read an entire WOOL project consisting of ".wool" dialogue
 * files and ".json" translation files.
 *
 * @author Dennis Hofs (RRD)
 */
public class WoolProjectParser {

	private WoolFileLoader fileLoader;

	private Map dialogues =
			new LinkedHashMap<>();
	private Map> translations =
			new LinkedHashMap<>();

	private Map translatedDialogues =
			new LinkedHashMap<>();

	public WoolProjectParser(WoolFileLoader fileLoader) {
		this.fileLoader = fileLoader;
	}

	public WoolProjectParserResult parse() throws IOException {
		WoolProjectParserResult result = new WoolProjectParserResult();
		List files = fileLoader.listWoolFiles();
		parseFiles(files, result);
		if (!result.getParseErrors().isEmpty())
			return result;
		createTranslatedDialogues(result);
		if (!result.getParseErrors().isEmpty())
			return result;
		WoolProject project = new WoolProject();
		project.setDialogues(translatedDialogues);
		result.setProject(project);
		return result;
	}

	/**
	 * Tries to parse all project files (dialogue and translation files). This
	 * method fills variables "dialogues" and "translations". Any parse errors
	 * will be added to "readResult".
	 *
	 * 

It uses "dialogueFiles" and "translationFiles". They will be cleared * in the end.

* * @param files the project files * @param readResult the read result * @throws IOException if a reading error occurs */ private void parseFiles(List files, WoolProjectParserResult readResult) throws IOException { Set dlgDescrSet = new HashSet<>(); List dialogueFiles = new ArrayList<>(); List translationFiles = new ArrayList<>(); for (WoolFileDescription file : files) { if (file.getFileName().endsWith(".wool")) dialogueFiles.add(file); else if (file.getFileName().endsWith(".json")) translationFiles.add(file); } for (WoolFileDescription descr : dialogueFiles) { dlgDescrSet.add(fileDescriptionToDialogueDescription(descr)); WoolParserResult dlgReadResult = parseDialogueFile(descr); if (dlgReadResult.getParseErrors().isEmpty()) { dialogues.put(descr, dlgReadResult.getDialogue()); } else { getParseErrors(readResult, descr).addAll( dlgReadResult.getParseErrors()); } } for (WoolFileDescription descr : translationFiles) { WoolDialogueDescription dlgDescr = fileDescriptionToDialogueDescription(descr); if (dlgDescrSet.contains(dlgDescr)) { getParseErrors(readResult, descr).add(new ParseException( String.format("Found both translation file \"%s\" and dialogue file \"%s.wool\"", descr.getFileName(), dlgDescr.getDialogueName()) + ": " + descr)); continue; } WoolTranslationParserResult transParseResult = parseTranslationFile( descr); if (!transParseResult.getParseErrors().isEmpty()) { getParseErrors(readResult, descr).addAll( transParseResult.getParseErrors()); } if (!transParseResult.getWarnings().isEmpty()) { getWarnings(readResult, descr).addAll( transParseResult.getWarnings()); } if (transParseResult.getParseErrors().isEmpty()) translations.put(descr, transParseResult.getTranslations()); } } private List getParseErrors( WoolProjectParserResult readResult, WoolFileDescription descr) { String path = fileDescriptionToPath(descr); List errors = readResult.getParseErrors().get(path); if (errors != null) return errors; errors = new ArrayList<>(); readResult.getParseErrors().put(path, errors); return errors; } private List getWarnings(WoolProjectParserResult readResult, WoolFileDescription descr) { String path = fileDescriptionToPath(descr); List warnings = readResult.getWarnings().get(path); if (warnings != null) return warnings; warnings = new ArrayList<>(); readResult.getWarnings().put(path, warnings); return warnings; } /** * Tries to create translated dialogues for all translation files. This * method fills variable "translatedDialogues" with the dialogues from * "dialogues" plus translated dialogues from "translations". Any parse * errors will be added to "readResult". * *

It uses "dialogues" and "translations". They will be cleared in the * end.

* * @param readResult the read result */ private void createTranslatedDialogues(WoolProjectParserResult readResult) { try { doCreateTranslatedDialogues(readResult); } finally { dialogues.clear(); translations.clear(); } } private void doCreateTranslatedDialogues(WoolProjectParserResult readResult) { for (WoolFileDescription descr : dialogues.keySet()) { WoolDialogueDescription dlgDescr = fileDescriptionToDialogueDescription(descr); WoolDialogue dlg = dialogues.get(descr); translatedDialogues.put(dlgDescr, dlg); } for (WoolFileDescription descr : translations.keySet()) { WoolDialogueDescription dlgDescr = fileDescriptionToDialogueDescription(descr); WoolDialogue source = findSourceDialogue(dlgDescr.getMainSpeaker(), dlgDescr.getDialogueName()); if (source == null) { getParseErrors(readResult, descr).add(new ParseException( "No source dialogue found for translation: " + descr)); continue; } WoolTranslator translator = new WoolTranslator(translations.get( descr)); WoolDialogue translated = translator.translate(source); translatedDialogues.put(dlgDescr, translated); } } private WoolDialogue findSourceDialogue(String mainSpeaker, String dlgName) { List matches = new ArrayList<>(); for (WoolFileDescription descr : dialogues.keySet()) { String currDlgName = fileNameToDialogueName(descr.getFileName()); if (descr.getMainSpeaker().equals(mainSpeaker) && currDlgName.equals(dlgName)) { matches.add(descr); } } if (matches.isEmpty()) return null; if (matches.size() == 1) return dialogues.get(matches.get(0)); Map lngMap = new HashMap<>(); for (WoolFileDescription match : matches) { lngMap.put(match.getLanguage(), match); } I18nLanguageFinder finder = new I18nLanguageFinder(new ArrayList<>( lngMap.keySet())); finder.setUserLocale(Locale.ENGLISH); String language = finder.find(); if (language == null) return dialogues.get(matches.get(0)); else return dialogues.get(lngMap.get(language)); } private WoolParserResult parseDialogueFile(WoolFileDescription description) throws IOException { String dlgName = fileNameToDialogueName(description.getFileName()); try (WoolParser woolParser = new WoolParser(dlgName, fileLoader.openFile(description))) { return woolParser.readDialogue(); } } private WoolTranslationParserResult parseTranslationFile( WoolFileDescription description) throws IOException { try (Reader reader = fileLoader.openFile(description)) { return WoolTranslationParser.parse(reader); } } private WoolDialogueDescription fileDescriptionToDialogueDescription( WoolFileDescription descr) { WoolDialogueDescription result = new WoolDialogueDescription(); result.setMainSpeaker(descr.getMainSpeaker()); result.setLanguage(descr.getLanguage()); result.setDialogueName(fileNameToDialogueName(descr.getFileName())); return result; } private String fileNameToDialogueName(String fileName) { if (fileName.endsWith(".wool") || fileName.endsWith(".json")) return fileName.substring(0, fileName.length() - 5); else return fileName; } private String fileDescriptionToPath(WoolFileDescription descr) { return descr.getLanguage() + "/" + descr.getMainSpeaker() + "/" + descr.getFileName(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy