From ab6b12b3912873de1a5a4d5e26ff022d87b74b2e Mon Sep 17 00:00:00 2001
From: Piotr Gawron <piotr.gawron@uni.lu>
Date: Tue, 21 Feb 2017 16:14:15 +0100
Subject: [PATCH] simple java parser for agenda (for import purpose)

---
 appointment-import/.classpath                 |  36 ++++
 appointment-import/.gitignore                 |   1 +
 appointment-import/.project                   |  23 +++
 .../org.eclipse.core.resources.prefs          |   6 +
 .../.settings/org.eclipse.jdt.core.prefs      |   5 +
 .../.settings/org.eclipse.m2e.core.prefs      |   4 +
 appointment-import/pom.xml                    |  67 ++++++++
 .../appointment/parse/AppointmentEntry.java   |  99 +++++++++++
 .../appointment/parse/AppointmentType.java    |  34 ++++
 .../smash/appointment/parse/CellParser.java   | 158 ++++++++++++++++++
 .../java/smash/appointment/parse/Main.java    |  27 +++
 .../appointment/parse/NameSurnameIndexer.java |   9 +
 .../appointment/parse/NdNumberIndexer.java    |   9 +
 .../java/smash/appointment/parse/Subject.java |  89 ++++++++++
 .../smash/appointment/parse/SubjectDao.java   |  43 +++++
 .../appointment/parse/SubjectIndexer.java     |  22 +++
 .../appointment/parse/SurnameIndexer.java     |   9 +
 .../appointment/parse/SurnameNameIndexer.java |   9 +
 .../java/smash/appointment/parse/Utils.java   |   7 +
 .../parse/XlsxCalendarProcessor.java          | 142 ++++++++++++++++
 .../src/main/resources/log4j.properties       |   8 +
 .../smash/appointment/parse/AllTests.java     |  14 ++
 .../appointment/parse/CellParseTestCase.java  |  15 ++
 .../appointment/parse/CellParserTest.java     |  77 +++++++++
 .../appointment/parse/SubjectDaoTest.java     |  32 ++++
 .../smash/appointment/parse/TestBase.java     |  26 +++
 .../parse/XlsxCalendarProcessorTest.java      |  42 +++++
 .../src/test/resources/log4j.properties       |   8 +
 .../testFiles/calendarExample.xlsx            | Bin 0 -> 30585 bytes
 appointment-import/testFiles/subjects.txt     |   2 +
 30 files changed, 1023 insertions(+)
 create mode 100644 appointment-import/.classpath
 create mode 100644 appointment-import/.gitignore
 create mode 100644 appointment-import/.project
 create mode 100644 appointment-import/.settings/org.eclipse.core.resources.prefs
 create mode 100644 appointment-import/.settings/org.eclipse.jdt.core.prefs
 create mode 100644 appointment-import/.settings/org.eclipse.m2e.core.prefs
 create mode 100644 appointment-import/pom.xml
 create mode 100644 appointment-import/src/main/java/smash/appointment/parse/AppointmentEntry.java
 create mode 100644 appointment-import/src/main/java/smash/appointment/parse/AppointmentType.java
 create mode 100644 appointment-import/src/main/java/smash/appointment/parse/CellParser.java
 create mode 100644 appointment-import/src/main/java/smash/appointment/parse/Main.java
 create mode 100644 appointment-import/src/main/java/smash/appointment/parse/NameSurnameIndexer.java
 create mode 100644 appointment-import/src/main/java/smash/appointment/parse/NdNumberIndexer.java
 create mode 100644 appointment-import/src/main/java/smash/appointment/parse/Subject.java
 create mode 100644 appointment-import/src/main/java/smash/appointment/parse/SubjectDao.java
 create mode 100644 appointment-import/src/main/java/smash/appointment/parse/SubjectIndexer.java
 create mode 100644 appointment-import/src/main/java/smash/appointment/parse/SurnameIndexer.java
 create mode 100644 appointment-import/src/main/java/smash/appointment/parse/SurnameNameIndexer.java
 create mode 100644 appointment-import/src/main/java/smash/appointment/parse/Utils.java
 create mode 100644 appointment-import/src/main/java/smash/appointment/parse/XlsxCalendarProcessor.java
 create mode 100644 appointment-import/src/main/resources/log4j.properties
 create mode 100644 appointment-import/src/test/java/smash/appointment/parse/AllTests.java
 create mode 100644 appointment-import/src/test/java/smash/appointment/parse/CellParseTestCase.java
 create mode 100644 appointment-import/src/test/java/smash/appointment/parse/CellParserTest.java
 create mode 100644 appointment-import/src/test/java/smash/appointment/parse/SubjectDaoTest.java
 create mode 100644 appointment-import/src/test/java/smash/appointment/parse/TestBase.java
 create mode 100644 appointment-import/src/test/java/smash/appointment/parse/XlsxCalendarProcessorTest.java
 create mode 100644 appointment-import/src/test/resources/log4j.properties
 create mode 100644 appointment-import/testFiles/calendarExample.xlsx
 create mode 100644 appointment-import/testFiles/subjects.txt

diff --git a/appointment-import/.classpath b/appointment-import/.classpath
new file mode 100644
index 00000000..f7b62f18
--- /dev/null
+++ b/appointment-import/.classpath
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/appointment-import/.gitignore b/appointment-import/.gitignore
new file mode 100644
index 00000000..b83d2226
--- /dev/null
+++ b/appointment-import/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appointment-import/.project b/appointment-import/.project
new file mode 100644
index 00000000..eee5e1c7
--- /dev/null
+++ b/appointment-import/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>appointment-import</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>
diff --git a/appointment-import/.settings/org.eclipse.core.resources.prefs b/appointment-import/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 00000000..04cfa2c1
--- /dev/null
+++ b/appointment-import/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,6 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/main/resources=UTF-8
+encoding//src/test/java=UTF-8
+encoding//src/test/resources=UTF-8
+encoding/<project>=UTF-8
diff --git a/appointment-import/.settings/org.eclipse.jdt.core.prefs b/appointment-import/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..bbcbc934
--- /dev/null
+++ b/appointment-import/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/appointment-import/.settings/org.eclipse.m2e.core.prefs b/appointment-import/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 00000000..14b697b7
--- /dev/null
+++ b/appointment-import/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/appointment-import/pom.xml b/appointment-import/pom.xml
new file mode 100644
index 00000000..d1022957
--- /dev/null
+++ b/appointment-import/pom.xml
@@ -0,0 +1,67 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>smash</groupId>
+  <artifactId>appointment-import</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <packaging>jar</packaging>
+
+  <name>appointment-import</name>
+  <url>http://maven.apache.org</url>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.12</version>
+      <scope>test</scope>
+    </dependency>
+<dependency>
+    <groupId>log4j</groupId>
+    <artifactId>log4j</artifactId>
+    <version>1.2.17</version>
+</dependency>
+<dependency>
+    <groupId>org.apache.poi</groupId>
+    <artifactId>poi-ooxml</artifactId>
+    <version>3.15</version>
+</dependency>    
+  </dependencies>
+  
+	<build>
+		<plugins>
+<plugin>
+    <groupId>org.apache.maven.plugins</groupId>
+    <artifactId>maven-compiler-plugin</artifactId>
+    <version>3.5.1</version>
+    <configuration>
+        <source>1.7</source>
+        <target>1.7</target>
+    </configuration>
+</plugin> 		
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-assembly-plugin</artifactId>
+				<configuration>
+        	<source>1.7</source>
+        	<target>1.7</target>
+        	<archive>
+						<manifest>
+             <addClasspath>true</addClasspath>
+          	 <mainClass>smash.appointment.parse.Main</mainClass>
+						</manifest>
+					</archive>
+					<descriptorRefs>
+          <descriptorRef>jar-with-dependencies</descriptorRef>
+        </descriptorRefs>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+	  
+</project>
diff --git a/appointment-import/src/main/java/smash/appointment/parse/AppointmentEntry.java b/appointment-import/src/main/java/smash/appointment/parse/AppointmentEntry.java
new file mode 100644
index 00000000..8db01548
--- /dev/null
+++ b/appointment-import/src/main/java/smash/appointment/parse/AppointmentEntry.java
@@ -0,0 +1,99 @@
+package smash.appointment.parse;
+
+public class AppointmentEntry {
+	private String					day;
+	private String					time;
+	private Subject					subject;
+	private AppointmentType	type;
+	private String					source;
+
+	/**
+	 * @return the time
+	 * @see #time
+	 */
+	public String getTime() {
+		return time;
+	}
+
+	/**
+	 * @param time
+	 *          the time to set
+	 * @see #time
+	 */
+	public void setTime(String time) {
+		this.time = time;
+	}
+
+	/**
+	 * @return the subject
+	 * @see #subject
+	 */
+	public Subject getSubject() {
+		return subject;
+	}
+
+	/**
+	 * @param subject
+	 *          the subject to set
+	 * @see #subject
+	 */
+	public void setSubject(Subject subject) {
+		this.subject = subject;
+	}
+
+	/**
+	 * @return the type
+	 * @see #type
+	 */
+	public AppointmentType getType() {
+		return type;
+	}
+
+	/**
+	 * @param type
+	 *          the type to set
+	 * @see #type
+	 */
+	public void setType(AppointmentType type) {
+		this.type = type;
+	}
+
+	/**
+	 * @return the day
+	 * @see #day
+	 */
+	public String getDay() {
+		return day;
+	}
+
+	/**
+	 * @param day
+	 *          the day to set
+	 * @see #day
+	 */
+	public void setDay(String day) {
+		this.day = day;
+	}
+
+	/**
+	 * @return the source
+	 * @see #source
+	 */
+	public String getSource() {
+		return source;
+	}
+
+	/**
+	 * @param source
+	 *          the source to set
+	 * @see #source
+	 */
+	public void setSource(String source) {
+		this.source = source;
+	}
+
+	@Override
+	public String toString() {
+		return day + " " + time + " " + subject + " " + type + "\t\t[source: " + source + "]";
+	}
+}
diff --git a/appointment-import/src/main/java/smash/appointment/parse/AppointmentType.java b/appointment-import/src/main/java/smash/appointment/parse/AppointmentType.java
new file mode 100644
index 00000000..bb60199f
--- /dev/null
+++ b/appointment-import/src/main/java/smash/appointment/parse/AppointmentType.java
@@ -0,0 +1,34 @@
+package smash.appointment.parse;
+
+public enum AppointmentType {
+	
+	//most complex should be first
+	LEVEL_BV_BG_SB(new String[] { "evel BV + BG + SB","BV + BG + SB" }), // 
+	LEVEL_BV_SB(new String[] { "evel BV + SB","BV + SB" }), //
+	LEVEL_BV_BG(new String[] { "evel BV + BG","BV + BG" }), //
+	LEVEL_BG_SB(new String[] { "evel BG + SB","BG + SB" }), //
+	LEVEL_BV(new String[] { "evel BV", "BV" }), //
+	LEVEL_BG(new String[] { "evel BG","BG" }), //
+	LEVEL_SB(new String[] { "evel SB", "SB" }), //
+	
+	LEVEL_A(new String[] { "level A" }), //
+	OTHER(new String[] {}), //
+	LEVEL_B(new String[] { "evel B" }), //
+	LEVEL_B_M_POWER(new String[] { "mPower" }), // 
+	;
+
+	private String[] queryStrings;
+
+	private AppointmentType(String[] queryStrings) {
+		this.queryStrings = queryStrings;
+
+	}
+
+	/**
+	 * @return the queryStrings
+	 * @see #queryStrings
+	 */
+	public String[] getQueryStrings() {
+		return queryStrings;
+	}
+}
diff --git a/appointment-import/src/main/java/smash/appointment/parse/CellParser.java b/appointment-import/src/main/java/smash/appointment/parse/CellParser.java
new file mode 100644
index 00000000..efc2e388
--- /dev/null
+++ b/appointment-import/src/main/java/smash/appointment/parse/CellParser.java
@@ -0,0 +1,158 @@
+package smash.appointment.parse;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.log4j.Logger;
+
+public class CellParser {
+	Logger						 logger			 = Logger.getLogger(CellParser.class);
+
+	private SubjectDao subjectDao;
+
+	Pattern						 timePattern = Pattern.compile("^[0-9][0-9]\\:[0-9][0-9]");
+
+	public String extractTime(String content) {
+		String result = null;
+		Matcher matcher = timePattern.matcher(content);
+		if (matcher.find()) {
+			result = matcher.group();
+		}
+		return result;
+	}
+
+	public String removeTime(String content) {
+		Matcher matcher = timePattern.matcher(content);
+		if (matcher.find()) {
+			content = matcher.replaceFirst("").trim();
+		}
+		return content;
+	}
+
+	public AppointmentEntry parseAppointment(String query, String defaultTime) {
+		AppointmentEntry result = new AppointmentEntry();
+
+		String time = extractTime(query);
+		if (time != null) {
+			query = removeTime(query);
+		} else {
+			time = defaultTime;
+		}
+		result.setTime(time);
+
+		Subject subject = extractSubject(query);
+		result.setSubject(subject);
+
+		AppointmentType type = extractType(query);
+		if (type == null) {
+			type = AppointmentType.OTHER;
+		}
+		result.setType(type);
+
+		result.setSource(query);
+		return result;
+	}
+
+	private AppointmentType extractType(String query) {
+		String simplifiedQuery = Utils.simplifyString(query);
+
+		AppointmentType result = null;
+
+		String usedString = null;
+		for (AppointmentType type : AppointmentType.values()) {
+			boolean matchFound = false;
+			for (String string : type.getQueryStrings()) {
+				if (!matchFound) {
+					String simplifiedString = Utils.simplifyString(string);
+
+					if (simplifiedQuery.contains(simplifiedString)) {
+						matchFound = true;
+						if (result == null) {
+							result = type;
+							usedString = string;
+						} else {
+							if (string.contains(usedString)) {
+								result = type;
+								usedString = string;
+							} else if (usedString.contains(string)) {
+								//new one is a substring of old
+							} else { //if there is no substring then we might have a problem
+								AppointmentType newType = result;
+								if (usedString.length() < string.length()) {
+									result = type;
+									usedString = string;
+								}
+								logger.warn("More than one type possible for query: " + query + ". Type 1: " + result + ". Type 2: " + type + ". Choosing: " + newType);
+							}
+						}
+
+					}
+				}
+			}
+		}
+		return result;
+	}
+
+	private Subject extractSubject(String query) {
+		Subject result = null;
+		String simplifiedQuery = Utils.simplifyString(query);
+
+		SubjectIndexer[] mainIndices = new SubjectIndexer[] { //
+				new NameSurnameIndexer(), //
+				new SurnameNameIndexer(), //
+				new NdNumberIndexer(),//
+		};
+
+		result = getByIndices(query, simplifiedQuery, mainIndices);
+		if (result == null) {
+			SubjectIndexer[] secondaryIndices = new SubjectIndexer[] { //
+					new SurnameIndexer(), //
+			};
+			result = getByIndices(query, simplifiedQuery, secondaryIndices);
+		}
+		return result;
+	}
+
+	private Subject getByIndices(String query, String simplifiedQuery, SubjectIndexer[] mainIndices) {
+		Subject result = null;
+		for (Subject subject : subjectDao.getSubjects()) {
+			boolean matchFound = false;
+			for (SubjectIndexer indexer : mainIndices) {
+				if (!matchFound) {
+					if (indexer.match(subject, simplifiedQuery)) {
+						matchFound = true;
+						if (result == null) {
+							result = subject;
+						} else {
+							Subject newResult = result;
+							if (indexer.isBetter(subject, result)) {
+								newResult = subject;
+							}
+							logger.warn(
+									"More than one subject possible for query: " + query + ". Subject 1: " + result + ". Subject 2: " + subject + ". Choosing: " + newResult);
+							result = newResult;
+						}
+					}
+				}
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * @return the subjectDao
+	 * @see #subjectDao
+	 */
+	public SubjectDao getSubjectDao() {
+		return subjectDao;
+	}
+
+	/**
+	 * @param subjectDao
+	 *          the subjectDao to set
+	 * @see #subjectDao
+	 */
+	public void setSubjectDao(SubjectDao subjectDao) {
+		this.subjectDao = subjectDao;
+	}
+}
diff --git a/appointment-import/src/main/java/smash/appointment/parse/Main.java b/appointment-import/src/main/java/smash/appointment/parse/Main.java
new file mode 100644
index 00000000..051de5b0
--- /dev/null
+++ b/appointment-import/src/main/java/smash/appointment/parse/Main.java
@@ -0,0 +1,27 @@
+package smash.appointment.parse;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+public class Main {
+	private static Logger logger = Logger.getLogger(Main.class);
+
+	public static void main(String[] args) throws Exception {
+		if (args.length < 2) {
+			System.out.println("Usage: command <agenda.xlsx> <subjects.txt>");
+		} else {
+			SubjectDao subjectDao = new SubjectDao();
+			subjectDao.readFile(args[1]);
+
+			XlsxCalendarProcessor processor = new XlsxCalendarProcessor();
+			processor.setSubjectDao(subjectDao);
+
+			List<AppointmentEntry> entries = processor.processExcel(args[0]);
+			for (AppointmentEntry appointmentEntry : entries) {
+				logger.debug(appointmentEntry);
+			}
+		}
+	}
+
+}
diff --git a/appointment-import/src/main/java/smash/appointment/parse/NameSurnameIndexer.java b/appointment-import/src/main/java/smash/appointment/parse/NameSurnameIndexer.java
new file mode 100644
index 00000000..2ed820ad
--- /dev/null
+++ b/appointment-import/src/main/java/smash/appointment/parse/NameSurnameIndexer.java
@@ -0,0 +1,9 @@
+package smash.appointment.parse;
+
+public class NameSurnameIndexer extends SubjectIndexer {
+
+	public String getIndexedString(Subject subject) {
+		return Utils.simplifyString(subject.getName() + subject.getSurname());
+	}
+
+}
diff --git a/appointment-import/src/main/java/smash/appointment/parse/NdNumberIndexer.java b/appointment-import/src/main/java/smash/appointment/parse/NdNumberIndexer.java
new file mode 100644
index 00000000..cd96a4a1
--- /dev/null
+++ b/appointment-import/src/main/java/smash/appointment/parse/NdNumberIndexer.java
@@ -0,0 +1,9 @@
+package smash.appointment.parse;
+
+public class NdNumberIndexer extends SubjectIndexer {
+
+	public String getIndexedString(Subject subject) {
+		return Utils.simplifyString(subject.getNdNumber());
+	}
+
+}
diff --git a/appointment-import/src/main/java/smash/appointment/parse/Subject.java b/appointment-import/src/main/java/smash/appointment/parse/Subject.java
new file mode 100644
index 00000000..ee5cc02d
--- /dev/null
+++ b/appointment-import/src/main/java/smash/appointment/parse/Subject.java
@@ -0,0 +1,89 @@
+package smash.appointment.parse;
+
+public class Subject {
+	private String name;
+	private String surname;
+	private String ndNumber;
+	private String screeningNumber;
+
+	public Subject(String name, String surname, String ndNumber, String screeningNumber) {
+		this.name = name;
+		this.surname = surname;
+		this.ndNumber = ndNumber;
+		this.screeningNumber = screeningNumber;
+	}
+
+	/**
+	 * @return the name
+	 * @see #name
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * @param name
+	 *          the name to set
+	 * @see #name
+	 */
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	/**
+	 * @return the surname
+	 * @see #surname
+	 */
+	public String getSurname() {
+		return surname;
+	}
+
+	/**
+	 * @param surname
+	 *          the surname to set
+	 * @see #surname
+	 */
+	public void setSurname(String surname) {
+		this.surname = surname;
+	}
+
+	/**
+	 * @return the ndNumber
+	 * @see #ndNumber
+	 */
+	public String getNdNumber() {
+		return ndNumber;
+	}
+
+	/**
+	 * @param ndNumber
+	 *          the ndNumber to set
+	 * @see #ndNumber
+	 */
+	public void setNdNumber(String ndNumber) {
+		this.ndNumber = ndNumber;
+	}
+
+	/**
+	 * @return the screeningNumber
+	 * @see #screeningNumber
+	 */
+	public String getScreeningNumber() {
+		return screeningNumber;
+	}
+
+	/**
+	 * @param screeningNumber
+	 *          the screeningNumber to set
+	 * @see #screeningNumber
+	 */
+	public void setScreeningNumber(String screeningNumber) {
+		this.screeningNumber = screeningNumber;
+	}
+
+	@Override
+	public String toString() {
+		return this.getName() + " " + this.getSurname() + " (" + this.getNdNumber() + "; " + this.getScreeningNumber() + ")";
+	}
+
+}
diff --git a/appointment-import/src/main/java/smash/appointment/parse/SubjectDao.java b/appointment-import/src/main/java/smash/appointment/parse/SubjectDao.java
new file mode 100644
index 00000000..c852c84c
--- /dev/null
+++ b/appointment-import/src/main/java/smash/appointment/parse/SubjectDao.java
@@ -0,0 +1,43 @@
+package smash.appointment.parse;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class SubjectDao {
+	private List<Subject> subjects = new ArrayList<Subject>();
+
+	public void addSubject(Subject subject) {
+		subjects.add(subject);
+	}
+
+	public void readFile(String filename) throws IOException {
+		try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
+			String line;
+			while ((line = br.readLine()) != null) {
+				String tmp[] = line.split("\t");
+				addSubject(new Subject(tmp[0], tmp[1], tmp[2], tmp[3]));
+			}
+		}
+	}
+
+	/**
+	 * @return the subjects
+	 * @see #subjects
+	 */
+	public List<Subject> getSubjects() {
+		return subjects;
+	}
+
+	/**
+	 * @param subjects
+	 *          the subjects to set
+	 * @see #subjects
+	 */
+	public void setSubjects(List<Subject> subjects) {
+		this.subjects = subjects;
+	}
+
+}
diff --git a/appointment-import/src/main/java/smash/appointment/parse/SubjectIndexer.java b/appointment-import/src/main/java/smash/appointment/parse/SubjectIndexer.java
new file mode 100644
index 00000000..ff89c24f
--- /dev/null
+++ b/appointment-import/src/main/java/smash/appointment/parse/SubjectIndexer.java
@@ -0,0 +1,22 @@
+package smash.appointment.parse;
+
+import org.apache.log4j.Logger;
+
+public abstract class SubjectIndexer {
+	Logger logger = Logger.getLogger(SubjectIndexer.class);
+
+	public abstract String getIndexedString(Subject subject);
+
+	public boolean match(Subject subject, String simplifiedQuery) {
+		String indexedString = getIndexedString(subject);
+//		logger.debug("Check: " + simplifiedQuery + " against: " + indexedString);
+		if (simplifiedQuery.startsWith(indexedString)) {
+			return true;
+		}
+		return false;
+	}
+
+	public boolean isBetter(Subject subject, Subject oldSubject) {
+		return getIndexedString(subject).length()>getIndexedString(oldSubject).length();
+	}
+}
diff --git a/appointment-import/src/main/java/smash/appointment/parse/SurnameIndexer.java b/appointment-import/src/main/java/smash/appointment/parse/SurnameIndexer.java
new file mode 100644
index 00000000..10c1a29f
--- /dev/null
+++ b/appointment-import/src/main/java/smash/appointment/parse/SurnameIndexer.java
@@ -0,0 +1,9 @@
+package smash.appointment.parse;
+
+public class SurnameIndexer extends SubjectIndexer {
+
+	public String getIndexedString(Subject subject) {
+		return Utils.simplifyString(subject.getSurname());
+	}
+
+}
diff --git a/appointment-import/src/main/java/smash/appointment/parse/SurnameNameIndexer.java b/appointment-import/src/main/java/smash/appointment/parse/SurnameNameIndexer.java
new file mode 100644
index 00000000..7de6d7c4
--- /dev/null
+++ b/appointment-import/src/main/java/smash/appointment/parse/SurnameNameIndexer.java
@@ -0,0 +1,9 @@
+package smash.appointment.parse;
+
+public class SurnameNameIndexer extends SubjectIndexer {
+
+	public String getIndexedString(Subject subject) {
+		return Utils.simplifyString(subject.getSurname() + subject.getName());
+	}
+
+}
diff --git a/appointment-import/src/main/java/smash/appointment/parse/Utils.java b/appointment-import/src/main/java/smash/appointment/parse/Utils.java
new file mode 100644
index 00000000..0667ea3e
--- /dev/null
+++ b/appointment-import/src/main/java/smash/appointment/parse/Utils.java
@@ -0,0 +1,7 @@
+package smash.appointment.parse;
+
+public class Utils {
+	public static String simplifyString(String query) {
+		return query.replaceAll("[\\s\\-©]", "").toLowerCase();
+	}
+}
diff --git a/appointment-import/src/main/java/smash/appointment/parse/XlsxCalendarProcessor.java b/appointment-import/src/main/java/smash/appointment/parse/XlsxCalendarProcessor.java
new file mode 100644
index 00000000..9066b957
--- /dev/null
+++ b/appointment-import/src/main/java/smash/appointment/parse/XlsxCalendarProcessor.java
@@ -0,0 +1,142 @@
+package smash.appointment.parse;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.log4j.Logger;
+import org.apache.poi.EncryptedDocumentException;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellType;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
+
+public class XlsxCalendarProcessor {
+	Logger						 logger	= Logger.getLogger(XlsxCalendarProcessor.class);
+
+	private SubjectDao subjectDao;
+
+	public List<AppointmentEntry> processExcel(String filename) throws EncryptedDocumentException, InvalidFormatException, IOException, ParseException {
+		List<AppointmentEntry> result = new ArrayList<AppointmentEntry>();
+		InputStream inp = new FileInputStream(filename);
+		Workbook workbook = WorkbookFactory.create(inp);
+		Iterator<Sheet> sheetIter = workbook.sheetIterator();
+		while (sheetIter.hasNext()) {
+			Sheet sheet = sheetIter.next();
+			String name = sheet.getSheetName().trim();
+			if (name.contains("2017")) {
+				String monthName = name.split(" ")[0];
+				String monthNumber = parseMonth(monthName);
+				result.addAll(processSheet(sheet, "2017-" + monthNumber));
+			} else {
+				logger.debug("Skipping sheet: " + name);
+			}
+		}
+		return result;
+	}
+
+	int[]	dayColumns						 = new int[] { 3, 4, 5, 6, 7 };
+
+	int[]	weekStartRows					 = new int[] { 5, 23, 41, 60, 78, 96 };
+
+	int		hourColum							 = 0;
+	int		dayOfMonthRowOffset		 = 0;
+	int		calendarRowStartOffset = 3;
+	int		calendarRowEndOffset	 = 18;
+
+	private List<AppointmentEntry> processSheet(Sheet sheet, String string) {
+		List<AppointmentEntry> result = new ArrayList<AppointmentEntry>();
+
+		CellParser parser = new CellParser();
+		parser.setSubjectDao(subjectDao);
+		
+		for (int weekOffset : weekStartRows) {
+			Row weekRow = sheet.getRow(weekOffset + dayOfMonthRowOffset);
+			for (int dayColumnOffset : dayColumns) {
+				Cell dayCell = weekRow.getCell(dayColumnOffset);
+				String dayOfMonth = ((int) dayCell.getNumericCellValue()) + "";
+				if (dayOfMonth.length() == 1) {
+					dayOfMonth = "0" + dayOfMonth;
+				}
+				if (!dayOfMonth.equals("00")) {
+					String day = string + "-" + dayOfMonth;
+
+					String hour = "08:00";
+					for (int hourOffset = calendarRowStartOffset; hourOffset < calendarRowEndOffset; hourOffset++) {
+						Row hourRow = sheet.getRow(weekOffset + hourOffset);
+
+						Cell hourCell = hourRow.getCell(hourColum);
+						if (hourCell.getCellTypeEnum().equals(CellType.NUMERIC)) {
+
+							SimpleDateFormat formatTime = new SimpleDateFormat("HH:mm");
+							String hourString = formatTime.format(hourCell.getDateCellValue());
+
+							if (isHour(hourString)) {
+								hour = hourString;
+							}
+						}
+
+						String query = hourRow.getCell(dayColumnOffset).getStringCellValue();
+
+						if (query != null && !query.isEmpty()) {
+							AppointmentEntry entry = parser.parseAppointment(query, hour);
+							entry.setDay(day);
+							
+							result.add(entry);
+						}
+					}
+				}
+			}
+
+		}
+		return result;
+	}
+
+	Pattern timePattern = Pattern.compile("^[0-9][0-9]\\:[0-9][0-9]");
+
+	private boolean isHour(String hourString) {
+		Matcher matcher = timePattern.matcher(hourString);
+		return matcher.find();
+	}
+
+	private String parseMonth(String monthName) throws ParseException {
+		Date date = new SimpleDateFormat("MMMM", Locale.ENGLISH).parse(monthName);
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(date);
+		String result = (cal.get(Calendar.MONTH) + 1) + "";
+		if (result.length() == 1) {
+			result = "0" + result;
+		}
+		return result;
+	}
+
+	/**
+	 * @return the subjectDao
+	 * @see #subjectDao
+	 */
+	public SubjectDao getSubjectDao() {
+		return subjectDao;
+	}
+
+	/**
+	 * @param subjectDao
+	 *          the subjectDao to set
+	 * @see #subjectDao
+	 */
+	public void setSubjectDao(SubjectDao subjectDao) {
+		this.subjectDao = subjectDao;
+	}
+}
diff --git a/appointment-import/src/main/resources/log4j.properties b/appointment-import/src/main/resources/log4j.properties
new file mode 100644
index 00000000..e108a78c
--- /dev/null
+++ b/appointment-import/src/main/resources/log4j.properties
@@ -0,0 +1,8 @@
+#Set root logger 's level and its appender to an appender called CONSOLE which is defined below.
+log4j.rootLogger=debug, CONSOLE
+
+#Set the behavior of the CONSOLE appender 
+log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern=%d %5p [%t] (%F:%L) - %m%n
+#log4j.appender.CONSOLE.layout.ConversionPattern=%m%n
diff --git a/appointment-import/src/test/java/smash/appointment/parse/AllTests.java b/appointment-import/src/test/java/smash/appointment/parse/AllTests.java
new file mode 100644
index 00000000..80dc2e92
--- /dev/null
+++ b/appointment-import/src/test/java/smash/appointment/parse/AllTests.java
@@ -0,0 +1,14 @@
+package smash.appointment.parse;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({ CellParserTest.class, //
+		SubjectDaoTest.class, //
+		XlsxCalendarProcessorTest.class, //
+})
+public class AllTests {
+
+}
diff --git a/appointment-import/src/test/java/smash/appointment/parse/CellParseTestCase.java b/appointment-import/src/test/java/smash/appointment/parse/CellParseTestCase.java
new file mode 100644
index 00000000..5bc51566
--- /dev/null
+++ b/appointment-import/src/test/java/smash/appointment/parse/CellParseTestCase.java
@@ -0,0 +1,15 @@
+package smash.appointment.parse;
+
+class CellParseTestCase {
+	String					query;
+	Subject					subject;
+	String					time;
+	AppointmentType	type;
+
+	public CellParseTestCase(String query, Subject subject, String time, AppointmentType type) {
+		this.query = query;
+		this.subject = subject;
+		this.time = time;
+		this.type = type;
+	}
+};
diff --git a/appointment-import/src/test/java/smash/appointment/parse/CellParserTest.java b/appointment-import/src/test/java/smash/appointment/parse/CellParserTest.java
new file mode 100644
index 00000000..40311eba
--- /dev/null
+++ b/appointment-import/src/test/java/smash/appointment/parse/CellParserTest.java
@@ -0,0 +1,77 @@
+package smash.appointment.parse;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class CellParserTest extends TestBase {
+	List<CellParseTestCase>	testCases;
+	CellParser parser;
+
+	@Before
+	public void setUp() {
+		super.setUp();
+		
+		parser = new CellParser();
+		parser.setSubjectDao(subjectDao);
+		
+		testCases = new ArrayList<CellParseTestCase>();
+
+		testCases.add(new CellParseTestCase("Piotr Gawron level A FU V3", piotrGawron, null, AppointmentType.LEVEL_A));
+		testCases.add(new CellParseTestCase("09:00 Jan Kowalski-Nowak level A", janKowalskiNowak, "09:00", AppointmentType.LEVEL_A));
+		testCases.add(new CellParseTestCase("ND0002 l664574645 (sms)evel BV ©  + SB ©", janKowalskiNowak, null, AppointmentType.LEVEL_BV_SB));
+		testCases.add(new CellParseTestCase("ND0001 654654631 level B ©", piotrGawron, null, AppointmentType.LEVEL_B));
+		testCases.add(new CellParseTestCase("John Doe BV + BG + SB", johnDoe, null, AppointmentType.LEVEL_BV_BG_SB));
+		testCases.add(new CellParseTestCase("Kowalski-Nowak m-Power", janKowalskiNowak, null, AppointmentType.LEVEL_B_M_POWER));
+		testCases.add(new CellParseTestCase("ND0004 Name BV ©", cateKowalsky, null, AppointmentType.LEVEL_BV));
+		
+	}
+
+
+	@Test
+	public void testExtractTime() {
+		for (CellParseTestCase testCase : testCases) {
+			String result = parser.extractTime(testCase.query);
+			assertEquals("Invalid time parsed from query: " + testCase.query, testCase.time, result);
+		}
+	}
+
+	@Test
+	public void testRemoveTime() {
+		for (CellParseTestCase testCase : testCases) {
+			String result = parser.removeTime(testCase.query);
+			if (testCase.time == null) {
+				assertEquals("query after removing time should be the same for query: " + testCase.query, testCase.query, result);
+			} else {
+				assertFalse(testCase.query.equals(result));
+			}
+		}
+	}
+
+	@Test
+	public void testRemoveTime2() {
+		String result = parser.removeTime("09:00 John Doe level B");
+		assertEquals("John Doe level B", result);
+	}
+
+	@Test
+	public void testExtractAppointment() {
+		String defaultTime = "23:55";
+		for (CellParseTestCase testCase : testCases) {
+			AppointmentEntry appointment = parser.parseAppointment(testCase.query, defaultTime);
+			if (testCase.time != null) {
+				assertEquals("Invalid time parsed from query: " + testCase.query, testCase.time, appointment.getTime());
+			} else {
+				assertEquals("Invalid time parsed from query (default value expected): " + testCase.query, defaultTime, appointment.getTime());
+			}
+			assertEquals("Invalid subject parsed from query: " + testCase.query, testCase.subject, appointment.getSubject());
+			assertEquals("Invalid type parsed from query: " + testCase.query, testCase.type, appointment.getType());
+		}
+	}
+
+}
diff --git a/appointment-import/src/test/java/smash/appointment/parse/SubjectDaoTest.java b/appointment-import/src/test/java/smash/appointment/parse/SubjectDaoTest.java
new file mode 100644
index 00000000..66fc18c5
--- /dev/null
+++ b/appointment-import/src/test/java/smash/appointment/parse/SubjectDaoTest.java
@@ -0,0 +1,32 @@
+package smash.appointment.parse;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SubjectDaoTest {
+
+	@AfterClass
+	public static void tearDownAfterClass() throws Exception {
+	}
+
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testReadFile() throws Exception {
+		SubjectDao subjectDao = new SubjectDao();
+		subjectDao.readFile("testFiles/subjects.txt");
+		assertEquals(2, subjectDao.getSubjects().size());
+		assertEquals("Piotr", subjectDao.getSubjects().get(0).getName());
+	}
+
+}
diff --git a/appointment-import/src/test/java/smash/appointment/parse/TestBase.java b/appointment-import/src/test/java/smash/appointment/parse/TestBase.java
new file mode 100644
index 00000000..e3b909e9
--- /dev/null
+++ b/appointment-import/src/test/java/smash/appointment/parse/TestBase.java
@@ -0,0 +1,26 @@
+package smash.appointment.parse;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+
+public class TestBase {
+	SubjectDao subjectDao;
+
+	Subject		 piotrGawron			= new Subject("Piotr", "Gawron", "ND0001", "1");
+	Subject		 janKowalskiNowak	= new Subject("Jan", "Kowalski-Nowak", "ND0002", "2");
+	Subject		 johnDoe					= new Subject("John", "Doe", "ND0003", "3");
+	Subject		 cateKowalsky					= new Subject("Cate", "Kowalsky", "ND0004", "4");
+
+	public void setUp() {
+		subjectDao = new SubjectDao();
+
+		subjectDao.addSubject(piotrGawron);
+		subjectDao.addSubject(janKowalskiNowak);
+		subjectDao.addSubject(johnDoe);
+		subjectDao.addSubject(cateKowalsky);
+	}
+
+
+}
diff --git a/appointment-import/src/test/java/smash/appointment/parse/XlsxCalendarProcessorTest.java b/appointment-import/src/test/java/smash/appointment/parse/XlsxCalendarProcessorTest.java
new file mode 100644
index 00000000..8c07b601
--- /dev/null
+++ b/appointment-import/src/test/java/smash/appointment/parse/XlsxCalendarProcessorTest.java
@@ -0,0 +1,42 @@
+package smash.appointment.parse;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.FileNotFoundException;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+public class XlsxCalendarProcessorTest extends TestBase{
+	Logger logger = Logger.getLogger(XlsxCalendarProcessorTest .class);
+	
+	XlsxCalendarProcessor processor = new XlsxCalendarProcessor();
+
+	@AfterClass
+	public static void tearDownAfterClass() throws Exception {
+	}
+
+	@Before
+	public void setUp()  {
+		super.setUp();
+		processor.setSubjectDao(subjectDao);
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testReadExcel() throws Exception {
+		List<AppointmentEntry> entries = processor.processExcel("testFiles/calendarExample.xlsx");
+		assertTrue(entries.size() > 0);
+//		for (AppointmentEntry appointmentEntry : entries) {
+//			logger.debug(appointmentEntry);
+//		}
+	}
+
+}
diff --git a/appointment-import/src/test/resources/log4j.properties b/appointment-import/src/test/resources/log4j.properties
new file mode 100644
index 00000000..e108a78c
--- /dev/null
+++ b/appointment-import/src/test/resources/log4j.properties
@@ -0,0 +1,8 @@
+#Set root logger 's level and its appender to an appender called CONSOLE which is defined below.
+log4j.rootLogger=debug, CONSOLE
+
+#Set the behavior of the CONSOLE appender 
+log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern=%d %5p [%t] (%F:%L) - %m%n
+#log4j.appender.CONSOLE.layout.ConversionPattern=%m%n
diff --git a/appointment-import/testFiles/calendarExample.xlsx b/appointment-import/testFiles/calendarExample.xlsx
new file mode 100644
index 0000000000000000000000000000000000000000..516d8e548c74f5a7b2e1050b80918e0acfe80fc8
GIT binary patch
literal 30585
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
a*8RJ!|Irli2=_YJzz;nz=;3y}kNrQr;+^^c

literal 0
HcmV?d00001

diff --git a/appointment-import/testFiles/subjects.txt b/appointment-import/testFiles/subjects.txt
new file mode 100644
index 00000000..c55594f7
--- /dev/null
+++ b/appointment-import/testFiles/subjects.txt
@@ -0,0 +1,2 @@
+Piotr	Gawron	ND0001	1
+John	Doe	ND0002	2
-- 
GitLab