Skip to content
Snippets Groups Projects
ApplicationLookup.java 3.6 KiB
Newer Older
package de.unipotsdam.cs.toolup.model;


import de.unipotsdam.cs.toolup.database.DatabaseController;
import de.unipotsdam.cs.toolup.exceptions.InvalidIdException;
import de.unipotsdam.cs.toolup.util.SubsetUtil;

import java.io.IOException;
import java.sql.SQLException;

public class ApplicationLookup {


    public static final String LIST_DELIMITER = ",";
    private final List<String> features;

    public ApplicationLookup(String features) {
        this.features = Arrays.asList(features.split(LIST_DELIMITER));
    }

    public Set<Application> getApplications() throws IOException, SQLException, InvalidIdException {
        throwExceptionIfNoFeaturesAreSpecified();
        Set<String> resultSetOfApps = getApplicationsWithLargestSubSetOfFeatures();
        return loadApplicationsByIds(resultSetOfApps);
    }

    /**
     * This method gets all Applications that match the whole feature list;
     * if there are none, it gets the Applications that match the feature subsets with one feature missing;
     * if the are none, with two features missing and so on.
     */
    private Set<String> getApplicationsWithLargestSubSetOfFeatures() throws SQLException, InvalidIdException, IOException {
        Set<String> resultSetOfApps = new HashSet<>();
        int sizeOfFeatureList = features.size();

        while (resultSetOfApps.isEmpty() && sizeOfFeatureList > 0) {
            addAllApplicationsThatMatchFeatureSubsetsOfGivenSize(resultSetOfApps, sizeOfFeatureList);
            sizeOfFeatureList--;
        }
        return resultSetOfApps;
    }

    private void addAllApplicationsThatMatchFeatureSubsetsOfGivenSize(Set<String> resultSetOfApps, int sizeOfFeatureList) throws SQLException, InvalidIdException, IOException {
        Set<Set<String>> allSubSetsOfFeatures = SubsetUtil.getAllSubsetsOfSize(new HashSet<String>(features), sizeOfFeatureList);

        for (Set<String> subSetOfFeatures : allSubSetsOfFeatures) {
            Set<String> applicationsForFeatureSubSet = buildIntersectionOfRelatedApplications(new ArrayList<String>(subSetOfFeatures));
            resultSetOfApps.addAll(applicationsForFeatureSubSet);
        }
    }

    private void throwExceptionIfNoFeaturesAreSpecified() {
        if (features.isEmpty()){
            throw new UnsupportedOperationException("Feature ID must be specified.");
        }
    }

    private Set<String> buildIntersectionOfRelatedApplications(List<String> featureList) throws SQLException, InvalidIdException, IOException {
        //load the related applications of the first feature
        String firstFeatureId = featureList.get(0).trim();
        Set<String> intersectionOfApps = DatabaseController.getInstance()
                .loadRelatedApplicationsForFeat(firstFeatureId);

        //if there is more than one feature, make the intersection of the result sets
        for (int i = 1; i < featureList.size(); i++) {
            String id = featureList.get(i).trim();
            Set<String> apps = DatabaseController.getInstance()
                    .loadRelatedApplicationsForFeat(id);
            intersectionOfApps.retainAll(apps);
        }
        return intersectionOfApps;
    }

    private Set<Application> loadApplicationsByIds(Set<String> intersectionOfApps) throws SQLException, InvalidIdException, IOException {
        Set<Application> resultSetOfApps = new HashSet<>();
        for (String id: intersectionOfApps){
            BusinessObject app = DatabaseController.getInstance().load(id);
            if (!(app instanceof NullBusinessObject)) {
                resultSetOfApps.add((Application) app);
            }
        }
        return resultSetOfApps;
    }
}