eu.morfeoproject.fast.catalogue.planner.ScreenPlanner.java Source code

Java tutorial

Introduction

Here is the source code for eu.morfeoproject.fast.catalogue.planner.ScreenPlanner.java

Source

/**
 * Copyright (c) 2008-2011, FAST Consortium
 * 
 * This file is part of FAST Platform.
 * 
 * FAST Platform 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.
 * 
 * FAST Platform 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 FAST Platform. If not, see <http://www.gnu.org/licenses/>.
 * 
 * Info about members and contributors of the FAST Consortium
 * is available at http://fast.morfeo-project.eu
 *
 **/
package eu.morfeoproject.fast.catalogue.planner;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.ontoware.rdf2go.model.node.URI;
import org.ontoware.rdf2go.model.node.impl.URIImpl;

import eu.morfeoproject.fast.catalogue.Catalogue;
import eu.morfeoproject.fast.catalogue.model.Condition;
import eu.morfeoproject.fast.catalogue.model.Screen;

public class ScreenPlanner {
    protected final transient Log log = LogFactory.getLog(this.getClass());

    private final URI ROOT_NODE = new URIImpl("urn:root");

    protected Planner planner;
    protected Catalogue catalogue;

    public ScreenPlanner(Catalogue catalogue) {
        this.catalogue = catalogue;
        this.planner = new CataloguePlanner(catalogue);
        //      this.planner = new Neo4jPlanner(catalogue.getStoragePath()+"/planner");
    }

    /**
     * Creates a list of plans
     * @param goal
     * @param screens
     * @return list of plans
     */
    public List<Plan> searchPlans(URI goal, List<Screen> screens) {
        LinkedList<URI> uriList = new LinkedList<URI>();
        for (Screen screen : screens) {
            uriList.add(screen.getUri());
        }

        LinkedList<Plan> planList = new LinkedList<Plan>();
        List<Plan> searchList = searchPlans(goal);
        planList.addAll(rankList(searchList, uriList));

        return reverse(removeDuplicates(planList, uriList));
    }

    protected List<Plan> reverse(List<Plan> planList) {
        for (Plan plan : planList) {
            Collections.reverse(plan.getUriList());
        }
        return planList;
    }

    protected List<Plan> removeDuplicates(List<Plan> planList, List<URI> uriList) {
        LinkedList<Plan> newList = new LinkedList<Plan>();
        for (Plan plan : planList) {
            Plan p = new Plan();
            p.setUriList(plan.getUriList(uriList));
            newList.add(p);
        }
        return newList;
    }

    protected List<Plan> rankList(List<Plan> planList, List<URI> uriList) {
        List<Plan> newList = new LinkedList<Plan>();
        int[] count = new int[planList.size()];
        for (int idx = 0; idx < planList.size(); idx++)
            count[idx] = countItems(planList.get(idx).getUriList(), uriList);

        for (int idx = 0; idx < planList.size(); idx++) {
            Plan plan = planList.get(idx);

            if (newList.isEmpty()) {
                newList.add(plan);
            } else {
                boolean added = false;
                for (int i = 0; i < newList.size(); i++) {
                    if (newList.get(i).getUriList(uriList).size() > plan.getUriList(uriList).size()) {
                        newList.add(i, plan);
                        added = true;
                        break;
                    }
                }
                if (!added)
                    newList.add(plan);
            }
        }

        return newList;
    }

    public List<Plan> searchPlans(List<URI> goalList, List<Screen> screens) {
        HashMap<URI, List<Plan>> plansByGoal = new HashMap<URI, List<Plan>>();
        List<Plan> combinedPlans;

        for (URI goal : goalList)
            plansByGoal.put(goal, searchPlans(goal, screens));
        combinedPlans = new LinkedList<Plan>();
        for (URI goal : goalList) {
            combinedPlans = combine(combinedPlans, plansByGoal.get(goal));
        }

        return combinedPlans;
    }

    /**
     * Creates a list of plans as a result of the combination of two lists.
     * Given a list of plans A: [[1, 2], [3, 4]] and a list of plans B: [[5, 6], [7, 8]]
     * it returns a list contaning 4 plans: [[1, 2, 5, 6], [1, 2, 7, 8], [3, 4, 5, 6], [3, 4, 7, 8]]
     * @param listA
     * @param listB
     * @return list combining listA and listB
     */
    public List<Plan> combine(List<Plan> listA, List<Plan> listB) {
        LinkedList<Plan> planList = new LinkedList<Plan>();

        if (listA.isEmpty() && listB.isEmpty())
            return planList;

        if (listA.isEmpty()) {
            for (Plan pB : listB) {
                Plan plan = new Plan();
                plan.getUriList().addAll(pB.getUriList());
                planList.add(plan);
            }
        } else if (listB.isEmpty()) {
            for (Plan pA : listA) {
                Plan plan = new Plan();
                plan.getUriList().addAll(pA.getUriList());
                planList.add(plan);
            }

        } else {
            for (Plan pA : listA) {
                for (Plan pB : listB) {
                    Plan plan = new Plan();
                    plan.getUriList().addAll(pA.getUriList());
                    plan.merge(pB);
                    planList.add(plan);
                }
            }
        }

        return planList;
    }

    /**
     * Calculates how many items of listB are also in listA
     * @param listA
     * @param listB
     * @return number of items repeated
     */
    private int countItems(List<URI> listA, List<URI> listB) {
        int count = 0;
        for (URI uri : listB) {
            if (listA.contains(uri))
                count++;
        }
        return count;
    }

    private List<Plan> searchPlans(URI uri) {
        List<Plan> planList = planner.searchPlans(uri, ROOT_NODE);
        for (Plan plan : planList)
            plan.getUriList().remove(ROOT_NODE);
        return planList;
    }

    public void add(Screen screen) {
        calculateForwards(screen);
        calculateBackwards(screen);
    }

    public void update(Screen newScreen, Screen oldScreen) {
        if (!equalListCondition(newScreen.getPreconditions(), oldScreen.getPreconditions())
                || !equalListCondition(newScreen.getPostconditions(), oldScreen.getPostconditions())) {
            planner.remove(newScreen.getUri());
            calculateForwards(newScreen);
            calculateBackwards(newScreen);
        }
    }

    public void remove(URI screenUri) {
        planner.remove(screenUri);
    }

    public void clear() {
        planner.clear();
    }

    private void calculateForwards(Screen screen) {
        if (screen.getPostconditions().size() > 0) {
            ArrayList<Screen> screens = new ArrayList<Screen>();
            screens.add(screen);
            ArrayList<URI> results = new ArrayList<URI>();
            results.addAll(catalogue.findScreensForwards(screens, new ArrayList<Condition>(),
                    new ArrayList<Condition>(), true, true, 0, -1, null));
            for (URI result : results) {
                planner.add(screen.getUri(), result);
                if (log.isInfoEnabled())
                    log.info("added transition " + screen.getUri() + " -> " + result);
            }
        }
    }

    private void calculateBackwards(Screen screen) {
        if (screen.getPreconditions().size() == 0) {
            planner.add(ROOT_NODE, screen.getUri());
        } else {
            ArrayList<Screen> screens = new ArrayList<Screen>();
            screens.add(screen);
            ArrayList<URI> results = new ArrayList<URI>();
            results.addAll(catalogue.findScreensBackwards(screens, new ArrayList<Condition>(),
                    new ArrayList<Condition>(), true, true, 0, -1, null));
            for (URI result : results) {
                planner.add(result, screen.getUri());
                if (log.isInfoEnabled())
                    log.info("added transition " + result + " -> " + screen.getUri());
            }
        }
    }

    private boolean equalListCondition(List<Condition> lcA, List<Condition> lcB) {
        if (lcA.size() != lcB.size())
            return false;
        for (int cIdx = 0; cIdx < lcA.size(); cIdx++) {
            if (!catalogue.isConditionCompatible(lcA.get(cIdx), lcB.get(cIdx))) {
                return false;
            }
        }
        return true;
    }

    /**
     * Generates all the plans from a given list of screens, already stored in the catalogue
     */
    protected void seed() {
        for (Screen screen : catalogue.getAllScreens()) {
            if (screen.getPreconditions().size() > 0) {
                ArrayList<Screen> screens = new ArrayList<Screen>();
                screens.add(screen);
                ArrayList<URI> results = new ArrayList<URI>();
                results.addAll(catalogue.findScreensBackwards(screens, new ArrayList<Condition>(),
                        new ArrayList<Condition>(), true, true, 0, -1, null));
                for (URI result : results) {
                    planner.add(result, screen.getUri());
                }
            }
        }
    }

}