<commit_before>/*******************************************************************************
 * (C) Copyright 2016 <NAME> and <NAME>
 *  
 * This file is part of STEP
 *  
 * STEP is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *  
 * STEP is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *  
 * You should have received a copy of the GNU Affero General Public License
 * along with STEP.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
package step.core.artefacts.reports;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.bson.Document;
import org.bson.types.ObjectId;
import org.jongo.MongoCollection;
import org.jongo.ResultHandler;

import com.mongodb.DBObject;
import com.mongodb.MongoClient;

import step.commons.datatable.DataTable;
import step.commons.datatable.TableRow;
import step.core.accessors.AbstractAccessor;
import step.core.accessors.MongoClientSession;
import step.core.accessors.MongoDBAccessorHelper;


public class ReportNodeAccessor extends AbstractAccessor {
		
	MongoCollection reports;
	
	com.mongodb.client.MongoCollection<Document> reports_;
	
	public ReportNodeAccessor() {
		super();
	}

	@Deprecated
	public ReportNodeAccessor(MongoClient client) {
		super();
		reports = MongoDBAccessorHelper.getCollection(client, "reports");
		reports_ = MongoDBAccessorHelper.getMongoCollection_(client, "reports");
	}
	
	public ReportNodeAccessor(MongoClientSession clientSession) {
		super(clientSession);
		reports = getJongoCollection("reports");
		reports_ = getMongoCollection("reports");
	}
	
	public void createIndexesIfNeeded(Long ttl) {
		createOrUpdateIndex(reports_, "parentID");
		createOrUpdateCompoundIndex(reports_, "executionID", "status", "executionTime");
		createOrUpdateCompoundIndex(reports_, "executionID", "executionTime");
		createOrUpdateCompoundIndex(reports_, "executionID", "_class");
	}

	public void save(ReportNode node) {
		reports.save(node);
	}
	
	public ReportNode get(ObjectId nodeId) {
		return reports.findOne(nodeId).as(ReportNode.class);
	}
	
	public List<ReportNode> getReportNodePath(ObjectId id) {
		LinkedList<ReportNode> result = new LinkedList<>();
		appendParentNodeToPath(result, get(id));
		return result;
	}
	
	private void appendParentNodeToPath(LinkedList<ReportNode> path, ReportNode node) {
		path.addFirst(node);
		ReportNode parentNode;
		if(node.getParentID()!=null) {
			parentNode = get(node.getParentID());
			if (parentNode != null) {
				appendParentNodeToPath(path, parentNode);
			}
		}
	}

    public Iterator<ReportNode> getChildren(ObjectId parentID) {    	
    	return reports.find("{parentID: #}",parentID).sort("{executionTime: 1}").as(ReportNode.class).iterator();
    }
    
	public Iterator<ReportNode> getReportNodesByExecutionID(String executionID) {
		assert executionID != null;
		return reports.find("{executionID: #}", executionID).sort("{executionTime: 1}").as(ReportNode.class).iterator();
	}
	
	public long countReportNodesByExecutionID(String executionID) {
		assert executionID != null;
		return reports.count("{executionID: #}");
	}

	public Iterator<ReportNode> getReportNodesByExecutionIDAndClass(String executionID, String class_) {
		assert executionID != null;
		return reports.find(
				"{executionID: #, _class: #}", executionID, class_).as(ReportNode.class).iterator();
	}
    
	public Iterator<ReportNode> getLeafReportNodesByExecutionID(String executionID) {
		assert executionID != null;
		return reports.find(
				"{executionID: #, $or: [ { _class: 'step.commons.model.report.CallFunctionReportNode' }, { status: 'TECHNICAL_ERROR'} ]}", executionID)
				.sort("{executionTime: 1}").as(ReportNode.class).iterator();
	}
	
//	public Iterator<ReportNode> getLeafReportNodesByExecutionIDAndArtefactID(String executionID, String artefactID) {
//		assert executionID != null; assert artefactID!=null;
//		Iterator<ReportNode> it = getReportNodesByExecutionIDAndArtefactID(executionID, artefactID);
//		Iterator<ReportNode> treeIt = new TreeIterator<ReportNode>(it, new TreeIteratorFactory<ReportNode>() {
//			@Override
//			public Iterator<ReportNode> getChildrenIterator(ReportNode parent) {
//				return getChildren(parent._id);
//			}});
//		Iterator<ReportNode> filterIt = new FilterIterator<ReportNode>(treeIt, new ObjectFilter<ReportNode>() {
//			@Override
//			public boolean matches(ReportNode o) {
//				return ((o instanceof CallFunctionReportNode) || o.getStatus() == ReportNodeStatus.TECHNICAL_ERROR); 
//			}
//		});
//		return filterIt;
//	}
	
	public Iterator<ReportNode> getLeafReportNodesByExecutionIDAndCustomAttribute(String executionID, List<Map<String, String>> customAttributes) {
		assert executionID != null;
		
		StringBuilder query = new StringBuilder();
		query.append("{$and:[{executionID: #},");
		
		if(customAttributes!=null&&customAttributes.size()>0) {
			query.append("{$or: [");
			Iterator<Map<String, String>> it = customAttributes.iterator();
			while(it.hasNext()) {
				Map<String, String> customAttributeMap = it.next();
				Iterator<String> keyIt = customAttributeMap.keySet().iterator();
				while(keyIt.hasNext()) {
					String key = keyIt.next();
					query.append("{'customAttributes.").append(key).append("': '").append(customAttributeMap.get(key)).append("'}");
					if(keyIt.hasNext()) {
						query.append(",");
					}
				}
				if(it.hasNext()) {
					query.append(",");
				}
			}
			query.append("]},");
		}
		query.append("{$or: [ { _class: 'step.artefacts.reports.CallFunctionReportNode' }, { status: 'TECHNICAL_ERROR'} ]}]}");
		
		return reports.find(query.toString(), executionID).sort("{executionTime: 1}").as(ReportNode.class).iterator();
	}<commit_msg>Implementing method getReportNodesByExecutionIDAndCustomAttribute in ReportNodeAccessor<commit_after>/*******************************************************************************
 * (C) Copyright 2016 <NAME> and <NAME>
 *  
 * This file is part of STEP
 *  
 * STEP is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *  
 * STEP is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *  
 * You should have received a copy of the GNU Affero General Public License
 * along with STEP.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
package step.core.artefacts.reports;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.bson.Document;
import org.bson.types.ObjectId;
import org.jongo.MongoCollection;
import org.jongo.ResultHandler;

import com.mongodb.DBObject;
import com.mongodb.MongoClient;

import step.commons.datatable.DataTable;
import step.commons.datatable.TableRow;
import step.core.accessors.AbstractAccessor;
import step.core.accessors.MongoClientSession;
import step.core.accessors.MongoDBAccessorHelper;


public class ReportNodeAccessor extends AbstractAccessor {
		
	MongoCollection reports;
	
	com.mongodb.client.MongoCollection<Document> reports_;
	
	public ReportNodeAccessor() {
		super();
	}

	@Deprecated
	public ReportNodeAccessor(MongoClient client) {
		super();
		reports = MongoDBAccessorHelper.getCollection(client, "reports");
		reports_ = MongoDBAccessorHelper.getMongoCollection_(client, "reports");
	}
	
	public ReportNodeAccessor(MongoClientSession clientSession) {
		super(clientSession);
		reports = getJongoCollection("reports");
		reports_ = getMongoCollection("reports");
	}
	
	public void createIndexesIfNeeded(Long ttl) {
		createOrUpdateIndex(reports_, "parentID");
		createOrUpdateCompoundIndex(reports_, "executionID", "status", "executionTime");
		createOrUpdateCompoundIndex(reports_, "executionID", "executionTime");
		createOrUpdateCompoundIndex(reports_, "executionID", "_class");
	}

	public void save(ReportNode node) {
		reports.save(node);
	}
	
	public ReportNode get(ObjectId nodeId) {
		return reports.findOne(nodeId).as(ReportNode.class);
	}
	
	public List<ReportNode> getReportNodePath(ObjectId id) {
		LinkedList<ReportNode> result = new LinkedList<>();
		appendParentNodeToPath(result, get(id));
		return result;
	}
	
	private void appendParentNodeToPath(LinkedList<ReportNode> path, ReportNode node) {
		path.addFirst(node);
		ReportNode parentNode;
		if(node.getParentID()!=null) {
			parentNode = get(node.getParentID());
			if (parentNode != null) {
				appendParentNodeToPath(path, parentNode);
			}
		}
	}

    public Iterator<ReportNode> getChildren(ObjectId parentID) {    	
    	return reports.find("{parentID: #}",parentID).sort("{executionTime: 1}").as(ReportNode.class).iterator();
    }
    
	public Iterator<ReportNode> getReportNodesByExecutionID(String executionID) {
		assert executionID != null;
		return reports.find("{executionID: #}", executionID).sort("{executionTime: 1}").as(ReportNode.class).iterator();
	}
	
	public long countReportNodesByExecutionID(String executionID) {
		assert executionID != null;
		return reports.count("{executionID: #}");
	}

	public Iterator<ReportNode> getReportNodesByExecutionIDAndClass(String executionID, String class_) {
		assert executionID != null;
		return reports.find(
				"{executionID: #, _class: #}", executionID, class_).as(ReportNode.class).iterator();
	}
    
	public Iterator<ReportNode> getLeafReportNodesByExecutionID(String executionID) {
		assert executionID != null;
		return reports.find(
				"{executionID: #, $or: [ { _class: 'step.commons.model.report.CallFunctionReportNode' }, { status: 'TECHNICAL_ERROR'} ]}", executionID)
				.sort("{executionTime: 1}").as(ReportNode.class).iterator();
	}
	
//	public Iterator<ReportNode> getLeafReportNodesByExecutionIDAndArtefactID(String executionID, String artefactID) {
//		assert executionID != null; assert artefactID!=null;
//		Iterator<ReportNode> it = getReportNodesByExecutionIDAndArtefactID(executionID, artefactID);
//		Iterator<ReportNode> treeIt = new TreeIterator<ReportNode>(it, new TreeIteratorFactory<ReportNode>() {
//			@Override
//			public Iterator<ReportNode> getChildrenIterator(ReportNode parent) {
//				return getChildren(parent._id);
//			}});
//		Iterator<ReportNode> filterIt = new FilterIterator<ReportNode>(treeIt, new ObjectFilter<ReportNode>() {
//			@Override
//			public boolean matches(ReportNode o) {
//				return ((o instanceof CallFunctionReportNode) || o.getStatus() == ReportNodeStatus.TECHNICAL_ERROR); 
//			}
//		});
//		return filterIt;
//	}
	
	public Iterator<ReportNode> getReportNodesByExecutionIDAndCustomAttribute(String executionID, List<Map<String, String>> customAttributes) {
		assert executionID != null;
		
		StringBuilder query = new StringBuilder();
		query.append("{$and:[{executionID: #},");
		
		if(customAttributes!=null&&customAttributes.size()>0) {
			query.append("{$or: [");
			Iterator<Map<String, String>> it = customAttributes.iterator();
			while(it.hasNext()) {
				Map<String, String> customAttributeMap = it.next();
				Iterator<String> keyIt = customAttributeMap.keySet().iterator();
				while(keyIt.hasNext()) {
					String key = keyIt.next();
					query.append("{'customAttributes.").append(key).append("': '").append(customAttributeMap.get(key)).append("'}");
					if(keyIt.hasNext()) {
						query.append(",");
					}
				}
				if(it.hasNext()) {
					query.append(",");
				}
			}
			query.append("]}]}");
		}
		//query.append("{$or: [ { _class: 'step.artefacts.reports.CallFunctionReportNode' }, { status: 'TECHNICAL_ERROR'} ]}]}");
		
		return reports.find(query.toString(), executionID).sort("{executionTime: 1}").as(ReportNode.class).iterator();
	}
{'fraction_non_alphanumeric': 0.1529279820555956, 'fraction_numerical': 0.0016021789633902106, 'mean_word_length': 5.27021597187343, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6721642', 'n_tokens_mistral': 4057, 'n_tokens_neox': 3667, 'n_words': 788}