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

fr.boreal.io.dlgp.InternalObjectFactory 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.dlgp;

import java.util.ArrayList;

import fr.boreal.model.functions.IntegraalInvokers;
import fr.boreal.model.functions.Invoker;
import fr.boreal.model.functions.JavaMethodInvoker;
import fr.boreal.model.logicalElements.api.Term;
import fr.boreal.model.logicalElements.factory.api.TermFactory;
import fr.boreal.model.logicalElements.impl.FunctionalTermImpl;
import fr.lirmm.graphik.dlgp3.parser.ADlgpItemFactory;
import fr.lirmm.graphik.dlgp3.parser.BuildException;
import fr.lirmm.graphik.dlgp3.parser.InvokeManager;

class InternalObjectFactory extends ADlgpItemFactory {

	private final TermFactory termFactory;

	private final Object boolIRI = createIRI(XSD + "boolean");
	private final Object decimalIRI = createIRI(XSD + "decimal");
	private final Object doubleIRI = createIRI(XSD + "double");
	private final Object integerIRI = createIRI(XSD + "integer");
	private final Object stringLangIRI = createIRI(RDF + "langString");
	private final Object stringIRI = createIRI(XSD + "string");

	public InternalObjectFactory(TermFactory termfactory) {
		this.termFactory = termfactory;
	}

	@Override
	public  Object createIRI(String s) {
		return decode(s);
	}

	@Override
	public Object createLiteral(Object datatype, String stringValue, String langTag) {
		if (datatype.equals(boolIRI)) {
			return this.termFactory.createOrGetLiteral(Boolean.valueOf(stringValue));
		} else if (datatype.equals(decimalIRI)) {
			return this.termFactory.createOrGetLiteral(Float.valueOf(stringValue));
		} else if (datatype.equals(doubleIRI)) {
			return this.termFactory.createOrGetLiteral(Double.valueOf(stringValue));
		} else if (datatype.equals(integerIRI)) {
			return this.termFactory.createOrGetLiteral(Integer.valueOf(stringValue));
		} else if (datatype.equals(stringLangIRI)) {
			return this.termFactory.createOrGetLiteral(stringValue);
		} else if (datatype.equals(stringIRI)) {
			return this.termFactory.createOrGetLiteral(stringValue);
		}
		return this.termFactory.createOrGetConstant(stringValue);
	}

	@Override
	public Object createVariable(String stringValue) {
		return termFactory.createOrGetVariable(stringValue);
	}

	public void buildImportDecl(String url) {
		throw new UnsupportedOperationException("DLGP file import is not yet possible");
	}

	public void buildPrefixDecl(String prefix,Object ns) {
		String s = ns.toString();
		if (s.startsWith("<")) 
			s = s.substring(1, s.length() - 1);
		this.getPrefixManager().setPrefix(prefix, s);
		this.fireParseEvent(new DeclarePrefixEvent(prefix, s));

	}

	public void buildComputedDecl(String prefix,Object ns) {
		String s = ns.toString();
		if (s.startsWith("<")) 
			s = s.substring(1, s.length() - 1);
		this.getComputedManager().setPrefix(prefix, s);
		this.fireParseEvent(new DeclareComputedEvent(prefix, s));
	}

	@Override
	public void buildViewDecl(String prefix, Object viewDefinitionFileObj) {
		String viewDefinitionFile = viewDefinitionFileObj.toString();
		if (viewDefinitionFile.startsWith("<")) {
			viewDefinitionFile = viewDefinitionFile.substring(1, viewDefinitionFile.length() - 1);
		}	
		this.fireParseEvent(new DeclareViewEvent(viewDefinitionFile));
	}	

	public void buildBaseDecl(String base) throws BuildException {
		base = base.substring(1, base.length() - 1);

		if (isBaseDeclared)
			throw new BuildException("Base already declared.");


		isBaseDeclared = true;
		this.getPrefixManager().setDefault(base);
		fireParseEvent(new DeclareBaseEvent(base));
	}

	public void buildTopDecl(String top,String flag) throws BuildException{
		if(flag.equals(IRI)) {
			top = top.substring(1, top.length() - 1);
        }
		else {
			top = this.getPrefixManager().getDefault() + top;
        }
        if (isTopDeclared)
            throw new BuildException("Base already declared.");
        isTopDeclared = true;
        fireParseEvent(new DeclareTopEvent(top));
    }

	public void buildUnaDecl() {
		una = true;
		this.fireParseEvent(new DeclareUNAEvent());
	}

	public Object buildPredicate(String token) {
		return this.createIRI(this.getPrefixManager().getDefault() + token);
	}

	public ParseEvent buildAtom(Object predicate,ArrayList listTerm) {
		return new FindsAtomEvent(predicate, listTerm.toArray(new Object[0]));
	}

	public ParseEvent buildAtomInBody(Object predicate,ArrayList listTerm) {
		return new FindsAtomEvent(predicate, listTerm.toArray(new Object[0]));
	}

	/* Computed */

	public ParseEvent buildComputedAtom(Object predicate,ArrayList listTerm) {
		return new FindsComputedAtomEvent(predicate, listTerm.toArray(new Object[0]));
	}

	public ParseEvent buildSpecialAtom(String binaryPred,ArrayList listTerm) {
		return new FindsSpecialAtomEvent(listTerm.get(0),binaryPred,listTerm.get(1));
	}

	@Override
	public ParseEvent buildEquality(Object term0, Object term1) {
		return new FindsEqualityEvent(term0, term1);
	}


	/* Functions */

	public Object buildFunctionalOrIriTerm(Object nameFunction, ArrayList listTermFunction, String prefix) {
		if(this.isComputed(prefix)) {
			ArrayList sub_terms = new ArrayList<>(listTermFunction.size());
			listTermFunction.forEach(o -> sub_terms.add((Term)o));

			try {
				String fname = nameFunction.toString().split("#")[0];
				String method_name = prefix.split(":")[1];
				Class invokerClass = ((Class)invokeManager.getInvokerObject(fname + "#"));

				if(invokerClass == null) {
					// standard functions
					IntegraalInvokers stdfct = new IntegraalInvokers(termFactory);
					Invoker invoker = stdfct.getInvoker(method_name);
					return new FunctionalTermImpl(prefix, invoker, sub_terms);
				} else {
					String class_name = invokerClass.getName();
					Invoker invoker = new JavaMethodInvoker(
							this.termFactory,
							InvokeManager.classToPath.get(class_name),
							class_name,
							method_name);
					return new FunctionalTermImpl(prefix, invoker, sub_terms);
				}
			} catch (Exception e) {
				e.printStackTrace();
				return nameFunction;
			}
		} else {
			return nameFunction;
		}
	}

	public Object buildSpecialFunctionalTerm(Object leftOperand,ArrayList ops,ArrayList rightOperands) {
		throw new UnsupportedOperationException("DLGP short functional notation is not yet possible");
	}

	public void buildNegativeConjunction(ArrayList> listNegConjunction) {
		if(!listNegConjunction.isEmpty()) {
			fireParseEvent(new FindsNegativeConjunction(listNegConjunction));
		}
	}


	public void buildVarList(ArrayList listTerm) { 
		fireParseEvent(new FindsVarListEvent(listTerm.toArray(new Object[0])));
	}

	public Object buildBool(String token) {
		return this.createLiteral(boolIRI, token, null);
	}

	public Object buildDecimal(String token) {
		return this.createLiteral(decimalIRI, token, null);
	}

	public Object buildDouble(String token) {
		return this.createLiteral(doubleIRI, token, null);
	}

	public Object buildInteger(String token) {
		return this.createLiteral(integerIRI, token, null);
	}


	public Object buildLang(String qs,String lang) {
		return this.createLiteral(stringLangIRI, qs, lang.substring(1));
	}

	public Object buildString(String qs) {
		return this.createLiteral(stringIRI, qs, null);	
	}

	public void buildQuery(String name) {
		current_object = OBJECT_TYPE.QUERY;
		fireParseEvent(new StartsObjectEvent(OBJECT_TYPE.QUERY, name));
	}

	public void buildNegativeConst(String name) {
		current_object = OBJECT_TYPE.NEG_CONSTRAINT;
		fireParseEvent(new StartsObjectEvent(OBJECT_TYPE.NEG_CONSTRAINT, name));
	}

	public void buildFact(ArrayList < ParseEvent > pending_events,String name) {
		current_object = OBJECT_TYPE.FACT;
		if (pending_events != null)
		{
			// call listeners for all pending atoms
			fireParseEvent(new StartsObjectEvent(OBJECT_TYPE.FACT, name));
			for (ParseEvent pending_event : pending_events) fireParseEvent(pending_event);
		}
	}

	public void buildRule(ArrayList < ParseEvent > pending_events,String name) {
		current_object = OBJECT_TYPE.RULE;
		if (pending_events != null)
		{
			// call listeners for all pending atoms
			fireParseEvent(new StartsObjectEvent(OBJECT_TYPE.RULE, name));
			for (ParseEvent pending_event : pending_events) {
				fireParseEvent(pending_event);
			}
		}
	}

	/*for the end conjunction event*/
	public void EndConjunctionEvent(OBJECT_TYPE object_type) {
		switch (object_type) {
		case QUERY, NEG_CONSTRAINT, FACT, RULE:
			fireParseEvent(new ConjunctionEndsEvent(object_type));
			break;
            case UNKNOWN:
			break;
		}
	}	

	/**
	 * Unescapes a string that contains unicode escape sequences \\uXXXX and \\UXXXXXXXX.
	 * 
	 * @param st A string optionally containing unicode escape sequences.
	 * @return The translated string.
	 */
	private static String decode(String st) {

		StringBuilder sb = new StringBuilder(st.length());

		for (int i = 0; i < st.length(); i++) {
			char ch = st.charAt(i);
			if (ch == '\\') {
				char nextChar = (i == st.length() - 1) ? '\\' : st
						.charAt(i + 1);

				switch (nextChar) {
				// Hex Unicode: u????
				case 'u':
					if (i >= st.length() - 5) {
						ch = 'u';
						break;
					}
					int code1 = Integer.parseInt(st.substring(i + 2, i + 6), 16);
					sb.append(Character.toChars(code1));
					i += 5;
					continue;
				case 'U':
					if (i >= st.length() - 9) {
						ch = 'U';
						break;
					}
					int code2 = Integer.parseInt(st.substring(i + 2, i + 10), 16);
					sb.append(Character.toChars(code2));
					i += 9;
					continue;
				}
				i++;
			}
			sb.append(ch);
		}
		return sb.toString();
	}

}