/******************************************************************************* * Copyright (c) 2014 Hussein Mhanna * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Hussein Mhanna - initial API and implementation ******************************************************************************/ package org.eclipse.rmf.reqif10.search.util; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.rmf.reqif10.AttributeDefinition; import org.eclipse.rmf.reqif10.AttributeValue; import org.eclipse.rmf.reqif10.SpecElementWithAttributes; import org.eclipse.rmf.reqif10.SpecHierarchy; import org.eclipse.rmf.reqif10.SpecObject; import org.eclipse.rmf.reqif10.Specification; import org.eclipse.rmf.reqif10.search.criteria.Criteria; import org.eclipse.rmf.reqif10.search.criteria.Operator; /** * @author Hussein MHANNA * */ public class ReqIFSearcher { /** * The constructor */ public ReqIFSearcher() { } public Map<Resource, Collection<EObject>> search(IProgressMonitor monitor, Collection<Resource> resources, Collection<Criteria> criterias, boolean replace) { Map<Resource, Collection<EObject>> result = new HashMap<Resource, Collection<EObject>>(); for (Resource resource : resources) { Collection<EObject> searchresult = search(monitor, resource, criterias, replace); result.put(resource, searchresult); if (monitor.isCanceled()) { break; } } monitor.done(); return result; } protected Collection<EObject> search(IProgressMonitor monitor, Resource resource, Collection<Criteria> criterias, boolean replace) { Set<EObject> result = new HashSet<EObject>(); // we create a set of specifications to add to add the SpecHierarchy // having reference to found SpecObject Set<Specification> specifications = new HashSet<Specification>(); for (TreeIterator<EObject> contents = resource.getAllContents(); contents .hasNext();) { EObject eObject = contents.next(); Entry entry = isCompatibleWithCriteria(eObject, criterias); if (entry != null) { result.add(eObject); if (replace) { setValue(entry); } } if (eObject instanceof Specification) { specifications.add((Specification) eObject); } } // For each Specification in the resource set, we add to the result the // SpecHierarchy // having reference to found SpecObject for (Specification specification : specifications) { addSpecHierarchies(result, specification.getChildren()); } return result; } private void addSpecHierarchies(Set<EObject> result, EList<SpecHierarchy> children) { for (SpecHierarchy specHierarchy : children) { SpecObject specObject = specHierarchy.getObject(); if ((specObject != null) && (result.contains(specObject))) { result.add(specHierarchy); addSpecHierarchies(result, specHierarchy.getChildren()); } } } protected Entry isCompatibleWithCriteria(EObject eObject, Collection<Criteria> criterias) { for (Criteria criteria : criterias) { Entry entry = getEntry(eObject, criteria); if (entry != null) { EStructuralFeature feature = entry.feature; if (feature instanceof EAttribute) { Object value = entry.getValue(); Operator operator = criteria.getOperator(); String textToSearch = criteria.getSerachedText(); if (value != null) { String stringValue = value.toString(); switch (operator) { case CONTAINS: if (stringValue.contains(textToSearch)) { return entry; } break; case NOT_CONTAINS: if (false == stringValue.contains(textToSearch)) { return entry; } break; case EQUALS: if (stringValue.contains(textToSearch)) { return entry; } break; case NOT_EQUALS: if (false == stringValue.equals(textToSearch)) { return entry; } break; default: break; } } else if (operator.equals(Operator.NOT_EQUALS)) { return entry; } } } } return null; } protected void setValue(Entry entry) { Criteria criteria = entry.criteria; EObject eObject = entry.eObject; EAttribute feature = entry.feature; String value = criteria.getReplacementText(); if (criteria.getOperator().equals(Operator.CONTAINS)) { value = entry .getValue() .toString() .replaceAll(criteria.getSerachedText(), criteria.getReplacementText()); } doSetValue(eObject, feature, EcoreUtil.createFromString(feature.getEAttributeType(), value)); } protected void doSetValue(EObject eObject, EStructuralFeature feature, Object value) { eObject.eSet(feature, value); } protected Entry getEntry(EObject eObject, Criteria criteria) { Entry entry = null; String featureName = criteria.getFeatureName(); EStructuralFeature eStructuralFeature = eObject.eClass() .getEStructuralFeature(featureName); if (eStructuralFeature instanceof EAttribute) { entry = new Entry(eObject, (EAttribute) eStructuralFeature, criteria); } else if (eObject instanceof SpecElementWithAttributes) { EList<AttributeValue> values = ((SpecElementWithAttributes) eObject) .getValues(); for (AttributeValue attributeValue : values) { eStructuralFeature = attributeValue.eClass() .getEStructuralFeature(featureName); if (eStructuralFeature == null) { EStructuralFeature definitionEStructuralFeature = attributeValue .eClass().getEStructuralFeature("definition"); if (definitionEStructuralFeature != null) { AttributeDefinition attributeDefinition = (AttributeDefinition) attributeValue .eGet(definitionEStructuralFeature); if (attributeDefinition != null && attributeDefinition.getLongName() != null && attributeDefinition.getLongName().equals( featureName)) { eStructuralFeature = attributeValue.eClass() .getEStructuralFeature("theValue"); } } } // null instance of anything is always null so we do not need to // check if eStructuralFeature is not null if (eStructuralFeature instanceof EAttribute) { entry = new Entry(attributeValue, (EAttribute) eStructuralFeature, criteria); break; } } } return entry; } protected class Entry { private EObject eObject; private EAttribute feature; private Criteria criteria; public Entry(EObject eObject, EAttribute feature, Criteria criteria) { super(); this.eObject = eObject; this.feature = feature; this.criteria = criteria; } public Criteria getCriteria() { return criteria; } public EObject getEObject() { return eObject; } public EAttribute getFeature() { return feature; } protected Object getValue() { return eObject.eGet(feature); } } }