/* * This file is part of NucleusFramework for Bukkit, licensed under the MIT License (MIT). * * Copyright (c) JCThePants (www.jcwhatever.com) * * 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 com.jcwhatever.nucleus.internal.managed.language; import com.jcwhatever.nucleus.utils.text.TextUtils; import java.io.IOException; import java.io.InputStream; import java.util.ArrayDeque; import java.util.Deque; import java.util.HashSet; import java.util.Scanner; import java.util.Set; import javax.annotation.Nullable; /* * Parse NucleusFramework language file from stream. */ class LanguageParser { private final InputStream _stream; private final Set<String> _versions = new HashSet<>(10); private final Deque<LocalizedText> _localizedText = new ArrayDeque<>(25); /** * Constructor. * * @param stream The stream to parse. */ public LanguageParser(InputStream stream) { _stream = stream; } /** * Get valid language versions parsed from stream. */ public Set<String> getVersions() { return _versions; } /** * Get all parsed localized text. */ public Deque<LocalizedText> getLocalizedText() { return _localizedText; } /** * Begin parsing the stream provided in the constructor. * * @throws InvalidLocalizedTextException If the stream contains invalid lines. */ public void parseStream() throws InvalidLocalizedTextException { Scanner scanner = new Scanner(_stream, "UTF-16"); int lineNumber = 1; while (scanner.hasNextLine()) { parseLine(lineNumber, scanner.nextLine()); lineNumber++; } try { _stream.close(); } catch (IOException e) { e.printStackTrace(); } } /* * Parse a single line from the stream. */ private void parseLine(int lineNumber, String line) throws InvalidLocalizedTextException { // check for version if (line.startsWith("version> ")) { parseVersion(line); } // excluding comments and empty lines, parse localized text. else if (!line.startsWith("#") && !line.trim().isEmpty()) { LocalizedText text = parseLocalizedLine(line); if (text == null) { throw new InvalidLocalizedTextException("Invalid entry on line " + lineNumber + '.'); } _localizedText.add(text); } } /* * Parse the language version from a line. */ private void parseVersion(String versionLine) { String rawVersion = versionLine.substring(9, versionLine.length()); String[] versions = TextUtils.PATTERN_COMMA.split(rawVersion); for (String version : versions) { _versions.add(version.trim()); } } /* * Parse a localized line. Returns null if the line is invalid. */ @Nullable private LocalizedText parseLocalizedLine(String line) { int angleIndex = line.indexOf("> "); String rawNumber = line.substring(0, angleIndex); int index; try { index = Integer.parseInt(rawNumber); } catch (NumberFormatException e) { return null; } String text = line.substring(angleIndex + 2, line.length()); return new LocalizedText(index, text); } }