Package de.timefinder.core.io.winqd

Source Code of de.timefinder.core.io.winqd.ImportWinQD

/*
*  Copyright 2009 Peter Karich, peat_hal 'at' users 'dot' sourceforge 'dot' net.
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*  under the License.
*/
package de.timefinder.core.io.winqd;

import de.timefinder.data.algo.DataPoolSettings;
import de.timefinder.algo.constraint.DifferentDayConstraint;
import de.timefinder.algo.constraint.MinGapsConstraint;
import de.timefinder.core.io.text.ImportText;
import de.timefinder.data.DataPool;
import de.timefinder.data.Event;
import de.timefinder.data.Location;
import de.timefinder.data.Person;
import de.timefinder.data.Role;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* @author Peter Karich, peat_hal 'at' users 'dot' sourceforge 'dot' net
*/
public class ImportWinQD extends ImportText {

    private Log logger = LogFactory.getLog(getClass());
    private String courseInstancesFile = "Kurse.txt";
    private BufferedReader courseInstancesReader;
    private String eventAssignmentFile = "Belegung.txt";
    private BufferedReader eventAssignmentReader;
    private Map<String, WinQDCourse> courses = new TreeMap();
    private Map<String, Person> students = new TreeMap<String, Person>();
    private Map<String, Person> teachers = new TreeMap<String, Person>();
    private int semester = 11;

    public ImportWinQD(DataPool dataPool, DataPoolSettings settings, File folder) {
        super(dataPool, settings, folder);
    }

    @Override
    protected void initReaders() {
        try {
            eventAssignmentReader = new BufferedReader(
                    new InputStreamReader(new FileInputStream(new File(getFolder(), eventAssignmentFile)), "cp1252"));
        } catch (Exception ex) {
            logger.fatal("Konnte Datei nicht öffnen " + eventAssignmentFile, ex);
        }

        try {
            courseInstancesReader = new BufferedReader(
                    new InputStreamReader(new FileInputStream(new File(getFolder(), courseInstancesFile)), "cp1252"));
        } catch (Exception ex) {
            logger.fatal("Konnte Datei nicht öffnen " + courseInstancesFile, ex);
        }
    }

    public void setSemester(int semester) {
        this.semester = semester;
    }

    @Override
    protected void readData() {
        String line = null;
        int lineCounter = 0;
        int dataCounter = -1;

        Person currentPerson = null;
        int indexKind = -1;
        int indexShortName = -1;
        int indexHoursCourse = -1;
        int indexHours11 = -1;
        int indexHours12 = -1;

        try {
            while ((line = eventAssignmentReader.readLine()) != null) {
                lineCounter++;

                if (dataCounter >= 0)
                    dataCounter++;

                if (line.contains("Schuljahr")) {
                    dataCounter = 0;
                } else if (dataCounter == 3) {
                    currentPerson = new Person();
                    currentPerson.setName(line.trim());
                    addStudent(currentPerson);
                } else if (dataCounter == 4) {
                    currentPerson.setDescription(line.trim());
                } else if (dataCounter == 6 || line.contains("Angebot*")) {
                    dataCounter = 6;
                    indexKind = line.indexOf("Angebot*");

                    indexHoursCourse = line.indexOf("Std");
                    indexHours11 = line.indexOf("11/1");
                    indexHours12 = line.indexOf("12/1");
                    indexShortName = line.indexOf("Wahl");
                } else if (dataCounter > 6 && dataCounter < 54) {
                    if (currentPerson == null)
                        logger.fatal("Person ist null!? " + lineCounter);

                    String courseLongName = null;
                    String shortName = null;
                    Integer courseHours = null;
                    Integer hours11 = null;
                    Integer hours12 = null;

                    if (indexKind >= 0 && indexKind < line.length()) {
                        courseLongName = line.substring(0, indexKind).trim();

                        if (courseLongName.startsWith("PRO"))
                            courseLongName = courseLongName.split(" ")[1];

                        if (courseLongName.length() < 1)
                            continue;
                    }

                    // TODO every seminar is different!
                    if (line.contains("Wissenschaftspropädeutisches")) {
                        indexHoursCourse += 4;
                        indexHours11 += 4;
                    }

                    if (indexHoursCourse >= 0 && indexHours11 >= 0
                            && indexHours11 < line.length() && indexHoursCourse < indexHours11) {
                        String subStr = line.substring(indexHoursCourse, indexHours11).trim();
                        if (subStr.length() > 0)
                            courseHours = Integer.parseInt(subStr.split(" ")[0].trim());
                    }

                    if (indexHours11 >= 0 && indexHours12 >= 0
                            && indexHours12 < line.length() && indexHours11 < indexHours12) {
                        String subStr = line.substring(indexHours11, indexHours12).trim();
                        if (subStr.length() > 0)
                            hours11 = Integer.parseInt(subStr.split(" ")[0].trim());
                    }

                    if (indexHours12 >= 0 && indexShortName >= 0
                            && indexShortName < line.length() && indexHours12 < indexShortName) {
                        String subStr = line.substring(indexHours12, indexShortName).trim();
                        if (subStr.length() > 0)
                            hours12 = Integer.parseInt(subStr.split(" ")[0].trim());
                    }

                    if (indexShortName >= 0 && indexShortName < line.length()) {
                        String subStr = line.substring(indexShortName).trim();
                        if (subStr.length() > 0)
                            shortName = subStr.split(":")[0].trim();
                    }

                    if (shortName == null)
                        continue;

                    if ("Kunst PRO".equals(courseLongName)) {
                        // "Kunst PRO" und Kunst können als identisch angesehen werden
                        // wer Kunst PRO wählt, geht in den normalen Kunstunterricht
                        shortName = "KU";
                    } else if (courseLongName.startsWith("Projekt-Seminar")) {
                        // jeder Schüler hat zur gleichen Zeit ein Seminar
                        shortName = "P" + shortName;
                    } else if (courseLongName.startsWith("Wissenschaftspropädeutisches Seminar")) {
                        shortName = "W" + shortName;
                    }

                    WinQDCourse course = courses.get(shortName);
                    if (course == null) {
                        course = new WinQDCourse();
                        course.setShortName(shortName);
                        course.setName(courseLongName);
                        if (courseHours != null)
                            course.setHours(getHours(courseHours));
                        addCourse(course);
                    }

                    Integer hours = null;
                    if (semester == 11 && hours11 != null)
                        hours = hours11;

                    if (semester == 12 && hours12 != null)
                        hours = hours12;

                    if (hours != null)
                        course.getStudents().add(currentPerson);
                }
            } // while all lines of eventAssignmentFile

            logger.info(courses.size() + " Kurse gefunden!");
        } catch (Exception ex) {
            throw new RuntimeException(eventAssignmentFile + " - Fehler in Zeile " + lineCounter
                    + " (Datensatzzeile:" + dataCounter + ") : " + line, ex);
        }

        lineCounter = 0;
        dataCounter = - 1;

        try {
            while ((line = courseInstancesReader.readLine()) != null) {
                lineCounter++;

                if (dataCounter >= 0)
                    dataCounter++;

                if (line.contains("Kursleiter")) {
                    dataCounter = 0;
                    continue;
                }

                if (dataCounter < 2)
                    continue;

                // TNZ = Teilnehmerzahl

                //0  1      2     3                              4       5       6   7   8
                //Nr|Kurs  |Art  |Kursleiter                    |Fach 11|Fach 12|TNZ|TZ1|TZ2|..
                String[] columns = line.split("\\|");
                if (columns.length != 10)
                    continue;

                int no = Integer.parseInt(columns[0].trim());
                if (no == 0)
                    continue;

                String instanceName = columns[1].trim();
                String courseShortName = columns[4].trim();

                if (instanceName.startsWith("1W") || instanceName.startsWith("1P")) {
                    int fromIndex = indexOfLower(1, instanceName);
                    int index = indexOfNumber(1, instanceName);
                    courseShortName = instanceName.substring(fromIndex, index).toUpperCase();
                    // geografie
                    if ("EK".equals(courseShortName))
                        courseShortName = "GEO";
                    // chemie
                    if ("CH".equals(courseShortName))
                        courseShortName = "C";
                    // sport
                    if ("SP".equals(courseShortName))
                        courseShortName = "SPO";

                    if (fromIndex > 1)
                        courseShortName = instanceName.charAt(fromIndex - 1) + courseShortName;
                }

                WinQDCourse course = courses.get(courseShortName);
                if (course == null) {
                    logger.fatal("Missing course:" + courseShortName);
                    continue;
                }

                String name = columns[3].trim();
                currentPerson = teachers.get(name);
                if (currentPerson == null) {
                    currentPerson = new Person();
                    currentPerson.setName(name);
                    addTeacher(currentPerson);
                }


                course.addInstance(instanceName, currentPerson);
            }
        } catch (Exception ex) {
            throw new RuntimeException(courseInstancesFile + " - Fehler in Zeile " + lineCounter
                    + " (Datensatzzeile:" + dataCounter + ") : " + line, ex);
        }
        logger.info(courses.values());

        fillSimpleDataPool();
    }

    public void fillSimpleDataPool() {
        Map<Long, Object> lDao = simpleDaos.get(Location.class);
        Map<Long, Object> eDao = simpleDaos.get(Event.class);
        Map pDao = simpleDaos.get(Person.class);
        long pCounter = 0;
        long eCounter = 0;
        for (Person p : students.values()) {
            pDao.put(pCounter++, p);
        }
        for (Person p : teachers.values()) {
            pDao.put(pCounter++, p);
        }
        for (long i = 0; i < 20; i++) {
            Location loc = new Location("Raum " + i, 40);
            lDao.put(i, loc);
        }

        // courses
        for (WinQDCourse course : courses.values()) {
            if (course.getInstances().size() == 0) {
                logger.fatal("No instances found for:" + course);
                continue;
            }

            if (course.getStudents().size() == 0) {
                logger.warn("No students found for:" + course);
                continue;
            }

            splitPersons(course.getStudents(), course.getInstances());

            // instances
            for (WinQDCourseInstance cInstance : course.getInstances()) {

                // appointments
                List<Event> eventsForDiffDay = new ArrayList<Event>();
                DifferentDayConstraint diffDayConstr = new DifferentDayConstraint(settings, eventsForDiffDay);
                diffDayConstr.setWeight(1000.0f);
                int appointmentCounter = 0;
                for (Integer integ : course.getHours()) {
                    Event ev = newEvent();
                    ev.setStart(0);
                    ev.setDuration(integ);
                    ev.setName(course.getName() + " (" + cInstance.getName()
                            + "/" + course.getInstances().size() + ")\n"
                            + ++appointmentCounter + "/" + course.getHours().size());

                    eDao.put(eCounter++, ev);
                    eventsForDiffDay.add(ev);
                    cInstance.getTeacher().addEvent(ev, Role.TEACHER, true);

                    for (Person p : cInstance.getStudents()) {
                        p.addEvent(ev, Role.STUDENT, true);
                    }
                }

                for (Person p : cInstance.getStudents()) {
                    MinGapsConstraint minGapConstr = new MinGapsConstraint(settings, p.getEvents());
                    minGapConstr.setWeight(1.0f);
                    p.putConstraint(minGapConstr);
                }

                // bind the constraint only if it makes sense
                if (eventsForDiffDay.size() > 1) {
                    for (Event ev : eventsForDiffDay) {
                        ev.putConstraint(diffDayConstr);
                    }
                }
            }
        }
    }

    public int getTeacherNumber() {
        return teachers.size();
    }

    public int getStudentsNumber() {
        return students.size();
    }

    WinQDCourse getCourse(String string) {
        return courses.get(string);
    }

    Collection<WinQDCourse> getCourses() {
        return courses.values();
    }

    void addCourse(WinQDCourse course) {
        courses.put(course.getShortName(), course);
    }

    void addStudent(Person currentPerson) {
        students.put(currentPerson.getName(), currentPerson);
    }

    void addTeacher(Person currentPerson) {
        teachers.put(currentPerson.getName(), currentPerson);
    }

    public static List<Integer> getHours(int hours) {
        int no = hours / 2;
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < no; i++) {
            list.add(2);
        }

        int rest = hours % 2;
        if (rest != 0)
            list.add(rest);

        return list;
    }

    /**
     * Spreads the list of persons specified with students into the instances
     */
    static void splitPersons(Collection<Person> students,
            Collection<WinQDCourseInstance> instances) {
        int instancesSize = instances.size();
        if (instancesSize == 0)
            return;

        int personsPerInstance = students.size() / instancesSize;
        if (students.size() % instancesSize != 0)
            personsPerInstance++;

        WinQDCourseInstance current = null;
        Iterator<WinQDCourseInstance> iter = instances.iterator();
        int i = 0;
        for (Person person : students) {
            if (i++ % personsPerInstance == 0) {
                current = iter.next();
            }
            current.getStudents().add(person);
        }

        if (iter.hasNext())
            throw new IllegalStateException("Instance-Iterator has additional entries:" + iter.next()
                    + ", instances:" + instancesSize + ", students:" + students.size());
    }

    static int indexOfNumber(int from, String instanceName) {
        for (int ii = from; ii < instanceName.length(); ii++) {
            if (Character.isDigit(instanceName.charAt(ii)))
                return ii;
        }

        return -1;
    }

    static int indexOfLower(int from, String instanceName) {
        for (int ii = from; ii < instanceName.length(); ii++) {
            if (Character.isLowerCase(instanceName.charAt(ii)))
                return ii;
        }

        return -1;
    }
}
TOP

Related Classes of de.timefinder.core.io.winqd.ImportWinQD

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.