package de.ovgu.cide.mining.database.recommendationengine; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Observable; import java.util.Observer; import java.util.Set; import java.util.Map.Entry; import de.ovgu.cide.features.IFeature; import de.ovgu.cide.mining.database.ApplicationController; import de.ovgu.cide.mining.database.model.AElement; import de.ovgu.cide.mining.database.recommendationengine.graphrelation.GraphRelationElementRecommender; import de.ovgu.cide.mining.database.recommendationengine.substrings.SubStringFeatureRecommender; import de.ovgu.cide.mining.database.recommendationengine.typechecking.TypeCheckElementRecommender; import de.ovgu.cide.mining.events.AGenerateRecommendationsEvent; //TODO: CACHE! RESULTS! public class AElementRecommendationManager implements Observer { private ApplicationController AC; private Map<IFeature, Map<AElement, ARecommendationContextCollection>> element2Recommendation; public static boolean USE_TYPESYSTEM = true; public static boolean USE_TOPOLOGYANALYSIS =true; public static boolean USE_SUBSTRINGCOMP = true; public static boolean USE_FOCUS_TS_09 = true; private Set<AAbstractElementRecommender> elementRecommenders; private Set<AAbstractFeatureRecommender> featureRecommenders; public AElementRecommendationManager(ApplicationController AC, AElementColorManager elementColorManager) { this.AC = AC; element2Recommendation = new HashMap<IFeature, Map<AElement, ARecommendationContextCollection>>(); elementRecommenders = new HashSet<AAbstractElementRecommender>(); if (USE_TYPESYSTEM) elementRecommenders.add(new TypeCheckElementRecommender()); if (USE_TOPOLOGYANALYSIS) elementRecommenders.add(new GraphRelationElementRecommender()); // recommenders.add(new SubStringElementRecommender()); featureRecommenders = new HashSet<AAbstractFeatureRecommender>(); if (USE_SUBSTRINGCOMP) featureRecommenders.add(new SubStringFeatureRecommender()); AC.addObserver(this); } public Map<IFeature, ARecommendationContextCollection> getAllRecommendations( AElement element) { Map<IFeature, ARecommendationContextCollection> result = new HashMap<IFeature, ARecommendationContextCollection>(); for (IFeature color : element2Recommendation.keySet()) { Map<AElement, ARecommendationContextCollection> recommendations = element2Recommendation .get(color); if (recommendations == null || recommendations.size() == 0) continue; if (!recommendations.containsKey(element)) continue; result.put(color, recommendations.get(element)); } return result; } public Map<AElement, ARecommendationContextCollection> getRecommendations( IFeature color, AElement element) { Map<AElement, ARecommendationContextCollection> colorRecommendations = element2Recommendation .get(color); if (colorRecommendations == null) return new HashMap<AElement, ARecommendationContextCollection>(); colorRecommendations = new HashMap<AElement, ARecommendationContextCollection>( colorRecommendations); Map<AElement, ARecommendationContextCollection> resultRecommendations = new HashMap<AElement, ARecommendationContextCollection>(); for (Entry<AElement, ARecommendationContextCollection> entry : colorRecommendations .entrySet()) { AElement recElement = entry.getKey(); ARecommendationContextCollection collection = entry.getValue(); for (ARecommendationContext context : collection.getContexts()) { if (!element.equals(context.getSupporter())) continue; resultRecommendations.put(recElement, collection); break; } } return resultRecommendations; } public int getRecommendationsCount(IFeature color, AElement element) { return getRecommendations(color, element).size(); } public Map<AElement, ARecommendationContextCollection> getRecommendations( IFeature color) { return getRecommendations(color, -1, -1, -1); } public Map<AElement, ARecommendationContextCollection> getRecommendations( IFeature color, int start, int end, int cuhash) { Map<AElement, ARecommendationContextCollection> recommendations = new HashMap<AElement, ARecommendationContextCollection>(); if (ApplicationController.CHECK_COLOR_RELATIONS) { Map<AElement, ARecommendationContextCollection> colorRecommendations = element2Recommendation .get(color); if (colorRecommendations != null && colorRecommendations.size() > 0) { recommendations = colorRecommendations; } } Set<AElement> elements = AC.getElementsOfColor(color); for (AElement tmpElement : new ArrayList<AElement>(elements)) { if (cuhash != -1 && tmpElement.getCompelationUnitHash() != cuhash) continue; if (start > -1 && tmpElement.getStartPosition() < start) continue; if (end > -1 && (tmpElement.getStartPosition() + tmpElement.getLength()) > end) continue; Map<AElement, ARecommendationContextCollection> tmpRecommendations = getRecommendations( color, tmpElement); if (tmpRecommendations == null) continue; mergeRecommendations(tmpRecommendations, recommendations); } return recommendations; } public int getRecommendationsCount(IFeature color, int start, int end, int cuhash) { return getRecommendations(color, start, end, cuhash).size(); } private void generateRecommendations() { element2Recommendation = new HashMap<IFeature, Map<AElement, ARecommendationContextCollection>>(); for (IFeature color : AC.getProjectFeatures()) { // RESET RECOMMENDATIONS Map<AElement, ARecommendationContextCollection> recommendations = new HashMap<AElement, ARecommendationContextCollection>(); element2Recommendation.put(color, recommendations); // RECOMMENDATION BASED ON LOCAL ELEMENT DATA Set<AElement> elements = AC.getElementsOfColor(color); if (ApplicationController.CHECK_COLOR_RELATIONS) { Set<AElement> tmpElements = new HashSet<AElement>(); tmpElements.addAll(elements); // ADD ELEMENTS OF RELATED COLORS for (IFeature relatedColor : AC.getRelatedColors(color)) { tmpElements.addAll(AC.getElementsOfColor(relatedColor)); } elements = tmpElements; } // generate recommendations for all elements for (AElement element : elements) { // recommend elements according to recommendation type for (AAbstractElementRecommender recommender : elementRecommenders) { Map<AElement, ARecommendationContext> tmpRecommendations = recommender .getRecommendations(element, color); addRecommendations(tmpRecommendations, recommendations); } } // RECOMMENDATION BASED ON GLOBAL FEATURE DATA // recommend elements according to recommendation type for (AAbstractFeatureRecommender recommender : featureRecommenders) { Map<AElement, ARecommendationContext> tmpRecommendations = recommender .getRecommendations(color); addRecommendations(tmpRecommendations, recommendations); } } } private void mergeRecommendations( Map<AElement, ARecommendationContextCollection> newRecommendations, Map<AElement, ARecommendationContextCollection> oldRecommendations) { for (AElement tmpRecElement : newRecommendations.keySet()) { ARecommendationContextCollection oldCollection = oldRecommendations .get(tmpRecElement); if (oldCollection == null) { oldRecommendations.put(tmpRecElement, newRecommendations .get(tmpRecElement)); } } } private void addRecommendations( Map<AElement, ARecommendationContext> newRecommendations, Map<AElement, ARecommendationContextCollection> oldRecommendations) { for (AElement tmpRecElement : newRecommendations.keySet()) { ARecommendationContextCollection collection = oldRecommendations .get(tmpRecElement); if (collection == null) { collection = new ARecommendationContextCollection(); oldRecommendations.put(tmpRecElement, collection); } // add the new context collection.addContext(newRecommendations.get(tmpRecElement)); } } public void update(Observable o, Object arg) { if (o.equals(AC)) { if (arg instanceof AGenerateRecommendationsEvent) { generateRecommendations(); } } } public void __script_updateRecommendations() { generateRecommendations(); } }