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

it.uniroma2.art.coda.pearl.parser.validate.ValidatePRModel Maven / Gradle / Ivy

There is a newer version: 2.0.2
Show newest version
package it.uniroma2.art.coda.pearl.parser.validate;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import it.uniroma2.art.coda.pearl.model.BindingStruct;
import it.uniroma2.art.coda.pearl.model.GraphElement;
import it.uniroma2.art.coda.pearl.model.GraphStruct;
import it.uniroma2.art.coda.pearl.model.OptionalGraphStruct;
import it.uniroma2.art.coda.pearl.model.PlaceholderStruct;
import it.uniroma2.art.coda.pearl.model.ProjectionRule;
import it.uniroma2.art.coda.pearl.model.ProjectionRulesModel;
import it.uniroma2.art.coda.pearl.model.graph.GraphSingleElemPlaceholder;
import it.uniroma2.art.coda.pearl.model.graph.GraphSingleElemVar;
import it.uniroma2.art.coda.pearl.model.graph.GraphSingleElement;
import it.uniroma2.art.coda.structures.DependsOnInfo;

public class ValidatePRModel {
	
	public static String PLCHLD_USE = "plchldUse";
	public static String VAR_USE = "varUse";
	public static String DEP_USE = "depUse";
	public static String BIND_USE = "bindUse";
	

	private ProjectionRulesModel prModel;
	private Map validateInfoMap;
	
	
	public ValidatePRModel(ProjectionRulesModel prModel) {
		this.prModel = prModel;
		validateInfoMap = new HashMap();
		
		initializeInfoTable();
	}
	
	
	private void initializeInfoTable() {
		validateInfoMap.put(PLCHLD_USE, new ValidateInfo());
		validateInfoMap.put(VAR_USE, new ValidateInfo());
		validateInfoMap.put(DEP_USE, new ValidateInfo());
		validateInfoMap.put(BIND_USE, new ValidateInfo());
		
	}


	public Map startValidation(boolean useTabInResponse){
		return startValidation(useTabInResponse, true, true, true, true);
	}
	
	public Map startValidation(boolean useTabInResponse, boolean valPlchdlUse, 
			boolean valVarUse, boolean valDepUSe, boolean valBindingUse){
		
		if(valPlchdlUse){
			validatePlchldUse(useTabInResponse);
		}
		if(valVarUse){
			validateVarUse(useTabInResponse);
		}
		if(valDepUSe){
			validateDepUse(useTabInResponse);
		}
		if(valBindingUse){
			validateBindingUse(useTabInResponse);
		}
		
		return validateInfoMap;
		
	}
	
	public Map getValidationTable(){
		return validateInfoMap;
	}
	
	/**
	 * Check if each placeholder defined in a rule it is used at least once inside the rule itself
	 * (in the graph or in the where section) and if each used placeholder is defined.
	 * This method do not consider the case in which 
	 * a variable uses the same name as a placeholder, so in that case it produces a not_used info
	 */
	private void validatePlchldUse(boolean useTabInResponse){
		String tab = "\n";
		if(useTabInResponse){
			tab = "\n\t";
		}
		ValidateInfo validateInfo = validateInfoMap.get(PLCHLD_USE);
		Map projRuleMap = prModel.getProjRule();
		for(String ruleId : projRuleMap.keySet()){
			boolean hasWarning = false;
			StringBuilder infoAboutAPR = new StringBuilder();
			ProjectionRule pr = projRuleMap.get(ruleId);
			if(pr.isLazy()){
				//if it is a lazy rule, do not analyze it, since it has no graph nor where section
				continue;
			}
			//get the list of placeholder used in this rule
			Set placeholderSet = pr.getPlaceholderMap().keySet();
			List usedPlchldList = new ArrayList();
			//get the list of placeholder in the Graph section
			Collection graphGEList = pr.getInsertGraphList();
			for(GraphElement ge : graphGEList){
				usedPlchldList.addAll(getPlaceholderUsedInGraphElement(ge, true, false, false, false));
			}
			//get the list of placeholder in the where section
			Collection whereGEList = pr.getWhereList();
			for(GraphElement ge : whereGEList){
				usedPlchldList.addAll(getPlaceholderUsedInGraphElement(ge, true, false, false, false));
			}
			//see if all the defined placeholder are used in the rule
			List defPlchldNotUsedList = new ArrayList();
			for(String key : placeholderSet){
				if(!usedPlchldList.contains(key)){
					//the placeholder key was defined, but not used
					defPlchldNotUsedList.add(key);
				}
			}
			//see if all the used placeholder are defined (do not consider the placeholder derived from 
			// a binding or from a dependency)
			List usedPlchldNotDefinedList = new ArrayList();
			for(String key : usedPlchldList){
				if(!placeholderSet.contains(key)){
					//the placeholde key was used, but not defined
					usedPlchldNotDefinedList.add(key);
				}
			}
			
			//construct the report using the two lists: defPlchldNotUsedList and usedPlchldNotDefinedList
			for(String key : defPlchldNotUsedList){
				infoAboutAPR.append(tab + "the placeholder " + key + " was defined, but not used");
				hasWarning = true;
			}
			for(String key : usedPlchldNotDefinedList){
				infoAboutAPR.append(tab + "the placeholder " + key + " was used, but not defined");
				hasWarning = true;
			}
			
			if(infoAboutAPR.length() == 0){
				infoAboutAPR.append(tab + "All placeholder are used and defined inside this rule");
			}
			//Add the info regarding the use of placeholder in this rule
			validateInfo.addRuleIdAndInfo(ruleId, new SingleInfo(infoAboutAPR.toString(), hasWarning));	
			
		}
	}


	/**
	 * Check if all the variable defined in the where section are used in the graph section and if
	 * all variable used in the graph section are defined in the where section
	 * @param useTabInResponse
	 */
	private void validateVarUse(boolean useTabInResponse){
		String tab = "\n";
		if(useTabInResponse){
			tab = "\n\t";
		}
		ValidateInfo validateInfo = validateInfoMap.get(VAR_USE);
		Map projRuleMap = prModel.getProjRule();
		for(String ruleId : projRuleMap.keySet()){
			boolean hasWarning = false;
			StringBuilder infoAboutAPR = new StringBuilder();
			ProjectionRule pr = projRuleMap.get(ruleId);
			if(pr.isLazy()){
				//if it is a lazy rule, do not analyze it, since it has no graph nor where section
				continue;
			}
			//get all the variable used in the where section, so the variable defined inside this rule
			List varDefinedList = new ArrayList();
			Collection whereGEList = pr.getWhereList();
			for(GraphElement ge : whereGEList){
				varDefinedList.addAll(getPlaceholderUsedInGraphElement(ge, false, false,false, true));
			}
			
			//get all the variable used in the graph section, 
			List varUSedInGraphSectionList = new ArrayList();
			Collection graphGEList = pr.getInsertGraphList();
			for(GraphElement ge : graphGEList){
				varUSedInGraphSectionList.addAll(getPlaceholderUsedInGraphElement(ge, false, false,false, true));
			}
			
			//see if all the defined variable in the where section are used in the graph section
			List defVarNotUsedList = new ArrayList();
			for(String key : varDefinedList){
				if(!varUSedInGraphSectionList.contains(key)){
					//the variable key was defined, but not used
					defVarNotUsedList.add(key);
				}
			}
			//see if all the used variable in the graph section are defined in the where section
			List usedVarNotDefinedList = new ArrayList();
			for(String key : varUSedInGraphSectionList){
				if(!varDefinedList.contains(key)){
					//the variable key was defined, but not used
					usedVarNotDefinedList.add(key);
				}
			}
			
			//construct the report using the two lists: defVarNotUsedList and usedVarNotDefinedList
			for(String key : defVarNotUsedList){
				infoAboutAPR.append(tab + "the variable " + key + " was defined, but not used");
				hasWarning = true;
			}
			for(String key : usedVarNotDefinedList){
				infoAboutAPR.append(tab + "the variable " + key + " was used, but not defined");
				hasWarning = true;
			}
			
			if(infoAboutAPR.length() == 0){
				infoAboutAPR.append(tab + "All variable are used and defined inside this rule");
			}
			//Add the info regarding the use of placeholder in this rule
			validateInfo.addRuleIdAndInfo(ruleId, new SingleInfo(infoAboutAPR.toString(), hasWarning));	
		}
	}
	
	private void validateDepUse(boolean useTabInResponse){
		String tab = "\n";
		if(useTabInResponse){
			tab = "\n\t";
		}
		ValidateInfo validateInfo = validateInfoMap.get(DEP_USE);
		Map projRuleMap = prModel.getProjRule();
		
		for(String ruleId : projRuleMap.keySet()){
			boolean hasWarning = false;
			StringBuilder infoAboutAPR = new StringBuilder();
			ProjectionRule pr = projRuleMap.get(ruleId);
			if(pr.isLazy()){
				//if it is a lazy rule, do not analyze it, since it has no graph nor where section
				continue;
			}
			//get the dependency defined for this rule (get the used alias and the real id)
			Map> aliasToRuleIdMap = new HashMap>();
			Map> dependOnMap = pr.getDependOnMap();
			List usedMoreTimeAliasRuleId = new ArrayList();
			for(String depType : dependOnMap.keySet()){
				Map depInnerMap = dependOnMap.get(depType);
				for(String key : depInnerMap.keySet()){
					DependsOnInfo dependsOnInfo = depInnerMap.get(key);
					String aliasRuleId = dependsOnInfo.getAliasRuleId();
					//String depRuleId = dependsOnInfo.getDependsOnRuleId();
					List depRuleIdList = dependsOnInfo.getDependsOnRuleIdList();
					if(aliasToRuleIdMap.containsKey(aliasRuleId)){
						usedMoreTimeAliasRuleId.add(aliasRuleId);
					}
					aliasToRuleIdMap.put(aliasRuleId, depRuleIdList);
				}
			}
			
			//for every dependency, check if a rule with that id exists 
			List definedDepWithoutRuleDefinition = new ArrayList();
			for(String aliasRuleId : aliasToRuleIdMap.keySet()){
				List depRuleIdList = aliasToRuleIdMap.get(aliasRuleId);
				for(String depRuleId : depRuleIdList) {
					if(projRuleMap.get(depRuleId) == null){
						definedDepWithoutRuleDefinition.add(depRuleId);
					}
				}
			}
			
			//get the list of dependency placeholder in the Graph section 
			Collection graphGEList = pr.getInsertGraphList();
			List usedPlchldList = new ArrayList();
			for(GraphElement ge : graphGEList){
				usedPlchldList.addAll(getPlaceholderUsedInGraphElement(ge, false, false, true, false));
			}
			//get the list of dependency placeholder in the where section
			Collection whereGEList = pr.getWhereList();
			for(GraphElement ge : whereGEList){
				usedPlchldList.addAll(getPlaceholderUsedInGraphElement(ge, false, false, true, false));
			}
			
			//check if these placeholder are defined in their relative dependency rule
			List usedDepWithoutRuleDefinition = new ArrayList();
			List usedDepWithoutDefinition = new ArrayList();
			for(String depPlchld : usedPlchldList){
				String aliasDepRule = depPlchld.split("\\..")[0];
				String plchldName = depPlchld.split("\\..")[1];
				//String realDepRuleId = aliasToRuleIdMap.get(aliasDepRule);
				List realDepRuleIdList = aliasToRuleIdMap.get(aliasDepRule);
				for(String realDepRuleId : realDepRuleIdList){
					if(realDepRuleId == null){ // I think this can never happen
						//the alias used in a triple, does not match any defined dependency
						usedDepWithoutRuleDefinition.add(depPlchld);
						continue;
					}
					ProjectionRule depPR = projRuleMap.get(realDepRuleId);
					if(depPR == null){
						//the alias used in a triple, does not match any defined dependency
						usedDepWithoutRuleDefinition.add(depPlchld);
						continue;
					}
					if(!depPR.getPlaceholderMap().containsKey(plchldName)){
						usedDepWithoutDefinition.add(depPlchld);
					}
				}
			}
			
			for(String key :definedDepWithoutRuleDefinition){
				infoAboutAPR.append(tab+"the defined dependency "+key+" is stated in the dependsOn of the " +
						"rule, but no rule with that id exists");
				hasWarning = true;
			}
			
			for(String key : usedDepWithoutRuleDefinition){
				infoAboutAPR.append(tab+"the dependency placeholder "+key+" is used, but its dependency " +
						"rule is not defined");
				hasWarning = true;
			}
			for(String key : usedDepWithoutDefinition){
				infoAboutAPR.append(tab+"the dependency placeholder "+key+" is used, but in its " +
						"dependency rule the placeholder is not defined");
				hasWarning = true;
			}
			for(String key : usedMoreTimeAliasRuleId){
				infoAboutAPR.append(tab+"the dependency alias "+key+" is defined more than once");
				hasWarning = true;
			}
			if(infoAboutAPR.length() == 0){
				infoAboutAPR.append(tab + "All dependency placeholder are defined in their relative " +
						"dependency rule");
			}
			validateInfo.addRuleIdAndInfo(ruleId, new SingleInfo(infoAboutAPR.toString(), hasWarning));
		}
		
	}
	
	private void validateBindingUse(boolean useTabInResponse){
		String tab = "\n";
		if(useTabInResponse){
			tab = "\n\t";
		}
		ValidateInfo validateInfo = validateInfoMap.get(BIND_USE);
		Map projRuleMap = prModel.getProjRule();
		
		for(String ruleId : projRuleMap.keySet()){
			boolean hasWarning = false;
			StringBuilder infoAboutAPR = new StringBuilder();
			ProjectionRule pr = projRuleMap.get(ruleId);
			if(pr.isLazy()){
				//if it is a lazy rule, do not analyze it, since it has no graph nor where section
				continue;
			}
			//get the binding defined in this rule
			Map bindingsMap = pr.getBindingsMap();
			for(String bindName : bindingsMap.keySet()){
				BindingStruct bindingStruct = bindingsMap.get(bindName);
				String boundRuleId = bindingStruct.getBoundRuleId();
				//check if a lazy rule with that id exists
				ProjectionRule lazyRule = prModel.getProjRuleFromId(boundRuleId);
				if(lazyRule == null){
					//no rule with that id exists
					infoAboutAPR.append(tab + "The bind "+bindName+" refers to a non existing rule with id "
							+boundRuleId);
					hasWarning = true;
					continue;
				}
				//check if lazyRule is really a lazy rule
				if(!lazyRule.isLazy()){
					infoAboutAPR.append(tab + "The bind "+bindName+" refers to a non lazy rule with id "
							+boundRuleId);
					hasWarning = true;
					continue;
				}
			}
			//get all the binding used in the graph section
			Collection graphGEList = pr.getInsertGraphList();
			List usedBindingList = new ArrayList();
			for(GraphElement ge : graphGEList){
				usedBindingList.addAll(getPlaceholderUsedInGraphElement(ge, false, true, false, false));
			}
			//get all the binding used in the where section
			Collection whereGEList = pr.getWhereList();
			for(GraphElement ge : whereGEList){
				usedBindingList.addAll(getPlaceholderUsedInGraphElement(ge, false, true, false, false));
			}
			//check if each used binding refers to a placeholder in the corresponding lazy rule
			List bindWithNoDwfinwsPlchld = new ArrayList();
			List bindingWithNoBindingDef = new ArrayList();
			for(String usedBinding : usedBindingList){
				String bindName = usedBinding.split("\\.")[0];
				BindingStruct boundRule = bindingsMap.get(bindName);
				if(boundRule ==  null){
					//the used binding has no associated ruleId, so no definition in the binding section
					bindingWithNoBindingDef.add(usedBinding);
					continue;
				}
				String boundRuleId = boundRule.getBoundRuleId();
				String bindPlchldPart = usedBinding.split("\\.")[1];
				ProjectionRule lazyRule = prModel.getProjRuleFromId(boundRuleId);
				if(lazyRule == null){
					infoAboutAPR.append(tab + "The binding "+usedBinding+" refers to a non existing rule " +
							"with id " + boundRuleId);
					hasWarning = true;
					continue;
				}
				//check if lazyRule is really a lazy rule
				if(!lazyRule.isLazy()){
					infoAboutAPR.append(tab + "The binding "+usedBinding+" refers to a non lazy rule with id "
							+boundRuleId);
					hasWarning = true;
					continue;
				}
				Map placeholderMap = lazyRule.getPlaceholderMap();
				if(!placeholderMap.containsKey(bindPlchldPart)){
					bindWithNoDwfinwsPlchld.add(usedBinding);
				}
			}
			for(String key : bindingWithNoBindingDef){
				infoAboutAPR.append(tab + "The binding "+key+" does not have the corresponding binding " +
						"definition");
				hasWarning = true;
			}
			for(String key : bindWithNoDwfinwsPlchld){
				infoAboutAPR.append(tab + "The binding "+key+" does not have the corresponding placeholder " +
						"in the bound lazy rule");
				hasWarning = true;
			}
			
			if(infoAboutAPR.length() == 0){
				infoAboutAPR.append(tab + "All the binding are used in the correct way");
			}
			validateInfo.addRuleIdAndInfo(ruleId, new SingleInfo(infoAboutAPR.toString(), hasWarning));
		}
		
	}
	
	
	private List getPlaceholderUsedInGraphElement(GraphElement ge, boolean localPlchld, 
			boolean fromBinding, boolean fromDependency, boolean variables) {
		List usedPlchldOrVarInGraphElemList = new ArrayList();
		if(ge instanceof GraphStruct){
			GraphStruct gs = (GraphStruct) ge;
			GraphSingleElement subject = gs.getSubject();
			GraphSingleElement predicate = gs.getPredicate();
			GraphSingleElement object = gs.getObject();
			if(subject instanceof GraphSingleElemPlaceholder){
				GraphSingleElemPlaceholder subjPlchld = (GraphSingleElemPlaceholder) subject;
				if(localPlchld && !subjPlchld.getName().contains(".")){
					usedPlchldOrVarInGraphElemList.add(subjPlchld.getName().substring(1));
				} else if(fromBinding && !subjPlchld.isFromDependsOnRule() && 
						subjPlchld.getName().contains(".")){
					usedPlchldOrVarInGraphElemList.add(subjPlchld.getName().substring(1));
				} else if(fromDependency && subjPlchld.isFromDependsOnRule()){
					usedPlchldOrVarInGraphElemList.add(subjPlchld.getName().substring(1));
				}
			} else if(variables && (subject instanceof GraphSingleElemVar)){
				GraphSingleElemVar subjVar = (GraphSingleElemVar)subject;
				usedPlchldOrVarInGraphElemList.add(subjVar.getVarId().substring(1));
			}
			if(predicate instanceof GraphSingleElemPlaceholder){
				GraphSingleElemPlaceholder predPlchld = (GraphSingleElemPlaceholder) predicate;
				if(localPlchld && !predPlchld.getName().contains(".")){
					usedPlchldOrVarInGraphElemList.add(predPlchld.getName().substring(1));
				} else if(fromBinding && !predPlchld.isFromDependsOnRule() && 
						predPlchld.getName().contains(".")){
					usedPlchldOrVarInGraphElemList.add(predPlchld.getName().substring(1));
				} else if(fromDependency && predPlchld.isFromDependsOnRule()){
					usedPlchldOrVarInGraphElemList.add(predPlchld.getName().substring(1));
				}
			} else if(variables && (predicate instanceof GraphSingleElemVar)){
				GraphSingleElemVar predVar = (GraphSingleElemVar)predicate;
				usedPlchldOrVarInGraphElemList.add(predVar.getVarId().substring(1));
			}
			if(object instanceof GraphSingleElemPlaceholder){
				GraphSingleElemPlaceholder objPlchld = (GraphSingleElemPlaceholder) object;
				if(localPlchld && !objPlchld.getName().contains(".")){
					usedPlchldOrVarInGraphElemList.add(objPlchld.getName().substring(1));
				} else if(fromBinding && !objPlchld.isFromDependsOnRule() && 
						objPlchld.getName().contains(".")){
					usedPlchldOrVarInGraphElemList.add(objPlchld.getName().substring(1));
				} else if(fromDependency && objPlchld.isFromDependsOnRule()){
					usedPlchldOrVarInGraphElemList.add(objPlchld.getName().substring(1));
				}
			} else if(variables && (object instanceof GraphSingleElemVar)){
				GraphSingleElemVar objVar = (GraphSingleElemVar)object;
				usedPlchldOrVarInGraphElemList.add(objVar.getVarId().substring(1));
			}
			
		} else if(ge instanceof OptionalGraphStruct) {
			OptionalGraphStruct ogs = (OptionalGraphStruct) ge;
			Collection optionalTriples = ogs.getOptionalTriples();
			for(GraphElement geFromOgs : optionalTriples){
				usedPlchldOrVarInGraphElemList.addAll(getPlaceholderUsedInGraphElement(geFromOgs, localPlchld,
						fromBinding, fromDependency, variables));
			}
		} else{
			//this should never happen
		}
		return usedPlchldOrVarInGraphElemList;
	}


	public String getValidationInfoAsString(boolean justWarning){
		StringBuilder sb = new StringBuilder();
		for(String infoType : validateInfoMap.keySet()){
			sb.append("\n\nInfoType = "+infoType);
			ValidateInfo validateInfo = validateInfoMap.get(infoType);
			for(String ruleId : validateInfo.getRuleIdInfoMap().keySet()){
				SingleInfo info = validateInfo.getInfoFromRuleId(ruleId);
				if(justWarning && !info.hasWarning()){
					//the caller want just the warning and the current SingleInfo is not a warning, so
					// skip this and go to the next one
					continue;
				}
				sb.append("\n- ruleID : "+ruleId);
				sb.append(info.getInfo());
			}
			
		}
		
		return sb.toString();
	}
	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy