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

net.yetamine.pet4bnd.model.format.PetFormat Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2016 Yetamine
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.yetamine.pet4bnd.model.format;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.stream.Stream;

import net.yetamine.pet4bnd.feedback.Feedback;
import net.yetamine.pet4bnd.model.Bundle;
import net.yetamine.pet4bnd.model.BundleVersion;
import net.yetamine.pet4bnd.model.PackageExport;
import net.yetamine.pet4bnd.model.Persistable;

/**
 * Encapsulates a bundle description.
 */
public final class PetFormat implements Bundle, Persistable {

    /** Packages that the bundle exports. */
    private final Map exports;
    /** Bundle version description. */
    private final BundleVersion version;
    /** Representation of the parsed content. */
    private final List representation;

    /**
     * Creates a new instance.
     *
     * @param parser
     *            the parser of the data. It must not be {@code null}.
     */
    PetFormat(PetParser parser) {
        representation = parser.representation();
        exports = Collections.unmodifiableMap(parser.bundleExports());
        version = parser.bundleVersion();
    }

    /**
     * @see net.yetamine.pet4bnd.model.Bundle#version()
     */
    public BundleVersion version() {
        return version;
    }

    /**
     * @see net.yetamine.pet4bnd.model.Bundle#exports()
     */
    public Map exports() {
        return exports;
    }

    /**
     * Parses the specified definition file.
     *
     * 

* The implementation uses the given feedback to report the lines where an * error or warning occurs. * * @param path * the path to the file. It must not be {@code null}. * @param feedback * the parser feedback to use. It must not be {@code null}. * * @return the parser containing the result of parsing and error statistics * * @throws IOException * if an I/O operation failed */ public static PetParser parse(Path path, Feedback feedback) throws IOException { try (Stream lines = Files.lines(path, StandardCharsets.UTF_8)) { final ParsingFeedback logger = new ParsingFeedback(feedback); final PetParser parser = new PetParser().feedback(logger); lines.forEach(line -> { logger.record(line); parser.accept(line); }); // No line now logger.record(null, 0); return parser.finish(); } } /** * Formats the bundle description. * * @param sink * the sink to accept lines of the representation. It must not be * {@code null}. */ public void format(Consumer sink) { Objects.requireNonNull(sink); representation.forEach(line -> sink.accept(line.toString())); } /** * Stores the encapsulated object in the given sink. * * @param sink * the sink to store the data to. It must not be {@code null}. * * @throws IOException * if storing the object fails */ public void persist(BufferedWriter sink) throws IOException { for (TextLine line : representation) { sink.write(line.toString()); sink.newLine(); } } /** * @see net.yetamine.pet4bnd.model.Persistable#persist(java.io.OutputStream) */ public void persist(OutputStream sink) throws IOException { try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(sink, StandardCharsets.UTF_8))) { persist(writer); } } /** * Input tracking feedback. */ private static final class ParsingFeedback implements Feedback { /** Underlying feedback instance. */ private final Feedback feedback; /** Current input. */ private String input; /** Current line. */ private int position; /** * Creates a new instance. * * @param backing * the underlying feedback instance. It must not be * {@code null}. */ public ParsingFeedback(Feedback backing) { feedback = Objects.requireNonNull(backing); } /** * Stores the line for the next messages. * * @param line * the line to store * @param number * the line number */ public void record(String line, int number) { position = number; input = line; } /** * Stores the next line for the next messages, i.e., increments the line * number. * * @param line * the line to store */ public void record(String line) { input = line; if (input != null) { ++position; } } /** * @see net.yetamine.pet4bnd.feedback.Feedback#fail(java.lang.String, * java.lang.Throwable) */ public void fail(String message, Throwable t) { if (input == null) { feedback.fail(message, t); return; } feedback.fail(message); feedback.fail(reference(), t); } /** * @see net.yetamine.pet4bnd.feedback.Feedback#warn(java.lang.String, * java.lang.Throwable) */ public void warn(String message, Throwable t) { if (input == null) { feedback.warn(message, t); return; } feedback.warn(message); feedback.warn(reference(), t); } /** * @see net.yetamine.pet4bnd.feedback.Feedback#info(java.lang.String) */ public void info(String message) { feedback.info(message); } /** * Renders the reference for the current input, which must not be * {@code null}. * * @return the reference for the current input */ private String reference() { assert (input != null); return (position > 0) ? String.format("See line %d: %s", position, input) : "See: " + input; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy