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

fr.boreal.io.api.Parser Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) Inria Sophia Antipolis - Méditerranée / LIRMM
 * (Université de Montpellier & CNRS) (2014 - 2017)
 *
 * Contributors :
 *
 * Clément SIPIETER 
 * Mélanie KÖNIG
 * Swan ROCHER
 * Jean-François BAGET
 * Michel LECLÈRE
 * Marie-Laure MUGNIER 
 *
 *
 * This file is part of Graal .
 *
 * This software is governed by the CeCILL  license under French law and
 * abiding by the rules of distribution of free software.  You can  use,
 * modify and/ or redistribute the software under the terms of the CeCILL
 * license as circulated by CEA, CNRS and INRIA at the following URL
 * "http://www.cecill.info".
 *
 * As a counterpart to the access to the source code and  rights to copy,
 * modify and redistribute granted by the license, users are provided only
 * with a limited warranty  and the software's author,  the holder of the
 * economic rights,  and the successive licensors  have only  limited
 * liability.
 *
 * In this respect, the user's attention is drawn to the risks associated
 * with loading,  using,  modifying and/or developing or reproducing the
 * software by the user in light of its specific status of free software,
 * that may mean  that it is complicated to manipulate,  and  that  also
 * therefore means  that it is reserved for developers  and  experienced
 * professionals having in-depth computer knowledge. Users are therefore
 * encouraged to load and test the software's suitability as regards their
 * requirements in conditions enabling the security of their systems and/or
 * data to be ensured and,  more generally, to use and operate it in the
 * same conditions as regards security.
 *
 * The fact that you are presently reading this means that you have had
 * knowledge of the CeCILL license and that you accept its terms.
 */
package fr.boreal.io.api;

import fr.boreal.io.dlgp.Directive;
import fr.boreal.io.dlgp.ParserResult;
import fr.boreal.model.formula.api.FOFormula;
import fr.boreal.model.logicalElements.api.Atom;
import fr.boreal.model.query.api.FOQuery;
import fr.boreal.model.rule.api.FORule;
import fr.boreal.views.builder.ViewBuilder;
import fr.boreal.views.builder.ViewBuilder.MappingBuilderException;
import fr.boreal.views.datasource.AbstractViewWrapper;
import fr.lirmm.boreal.util.stream.CloseableIterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 * @author Clément Sipieter (INRIA) {@literal }
 * @param  the type of objects returned by the parser
 *
 */
public interface Parser extends CloseableIterator {

	boolean hasNext() throws ParseException;

	T next() throws ParseException;

	/**
	 * 
	 * @return the parsed objects split by type into different collections
	 * @throws ParseException iff a parsing error occur
	 * @throws MappingBuilderException iff a mapping parsing exception occur
	 * 
	 */
	default ParserResult parse() throws ParseException, MappingBuilderException {
		Collection atoms = new ArrayList<>();
		Collection rules = new ArrayList<>();
		Collection> queries = new ArrayList<>();
		Collection> views = new LinkedHashSet<>();

		while (this.hasNext()) {
			switch (this.next()) {
			case Atom a -> atoms.add(a);
			case FORule r -> rules.add(r);
			case FOQuery q -> queries.add(q);
			case Directive d when d.type().equals(Directive.Type.VIEW) -> views.addAll(ViewBuilder.createFactBases(d.value().toString()));
			default -> {}
			};
		}
		return new ParserResult(atoms, rules, queries, views);
	}

	/**
	 * Streams parsed objects of a specific type.
	 * 
	 * @param    The type of objects to stream (e.g., Atom or Rule).
	 * @param clazz The class object representing the type T.
	 * @return A stream of objects of type T.
	 */
	default  Stream streamParsedObjects(Class clazz) {

		Logger LOG = LoggerFactory.getLogger(getClass());

		Iterable iterable = () -> new Iterator<>() {
			@Override
			public boolean hasNext() {
				try {
					return Parser.this.hasNext();
				} catch (ParseException e) {
					LOG.error("", e);
					return false;
				}
			}

			@Override
			public Object next() {
				try {
					return Parser.this.next();
				} catch (ParseException e) {
					e.printStackTrace();
					return null; // Handling null is important in the stream below
				}
			}
		};

		Spliterator spliterator = Spliterators.spliteratorUnknownSize(iterable.iterator(), Spliterator.NONNULL);

		// Convert the Iterable into a Stream, then filter and map to Stream
		return StreamSupport.stream(spliterator, false).filter(clazz::isInstance) // Keep only instances of T
				.map(clazz::cast); // Safely cast to T since filter ensures type
	}
}