diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000000000000000000000000000000000000..07926923085123e3d7ff394a8777e16563073379
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,16 @@
+# Editor configuration, see https://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 4
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.ts]
+quote_type = single
+
+[*.md]
+max_line_length = off
+trim_trailing_whitespace = false
diff --git a/.gitignore b/.gitignore
index 8a4c59aef9c4142c7675b653db6b710a5d6503c3..795da40d5d07c33b3026ab24cf05fb514f446701 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,9 @@ env/
# Apple
.DS_Store
+# VSCode
+.vscode/
+
# NetBeans
**/nbproject/private/
**/nbproject/Makefile-*.mk
diff --git a/.versionrc b/.versionrc
new file mode 100644
index 0000000000000000000000000000000000000000..7428f00ed3d40104ab4e21ab38a3b5c767e2ad0b
--- /dev/null
+++ b/.versionrc
@@ -0,0 +1,3 @@
+{
+ "tagPrefix": ""
+}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000000000000000000000000000000000000..dcc23ec3be1745199c0f80c59cb8b377adc3f1ea
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,2 @@
+Information on how to contribute to this project, is written in the docs.
+See here: [docs/unified-ticketing/contributing.md](docs/unified-ticketing/contributing.md)
diff --git a/LICENSE.md b/LICENSE.md
index 1110e89874643ece9fc3efe3ba58f2b946535cb4..4564b291ddcb7eda26bf6d4fad7ca9edec7764a0 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -2,7 +2,7 @@ GNU General Public License
==========================
_Version 3, 29 June 2007_
-_Copyright © 2007 Free Software Foundation, Inc. <>_
+_Copyright © 2007 [Free Software Foundation, Inc.](https://fsf.org)_
Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.
diff --git a/README.md b/README.md
index a2df26aee3f42e0d2338d31175129ab68b0afcdd..bd0a2dfe520c13984dea60349813e83f3a837a41 100644
--- a/README.md
+++ b/README.md
@@ -4,3 +4,8 @@ This is the repository of the unified-ticketing library.
Documentation for this is done with GitLab Pages using MkDocs and is available here:
https://transfer.hft-stuttgart.de/pages/unified-ticketing/
+
+If you don't want to open the Webpage or it is not available for whatever reason,
+the documentation root is in [docs/index.md][docs-root]
+
+[docs-root]: docs/index.md
diff --git a/docs/api/core/logging.md b/docs/api/core/logging.md
new file mode 100644
index 0000000000000000000000000000000000000000..c11b3c49540f87815ef1629eb66e69923b7063ad
--- /dev/null
+++ b/docs/api/core/logging.md
@@ -0,0 +1,41 @@
+# Logging
+
+The library uses the built-in logger from `java.util.logging`.
+It configures to not use the parent logger and places a new ConsoleHandler
+on static initialization. This outputs the log in formatted lines like:
+```text
+[2020-11-27T14:40:26+0100] [WARNING] [de.hftstuttgart.unifiedticketing.core.Logging.test] calling from app
+```
+
+This will _not_ change visual presentation based on any localization.
+
+## change log-level
+
+Default is to use _INFO_-level.
+You can change the used level:
+```java
+Logging.setLevel(Level);
+```
+
+The parameter passed is of type `java.util.logging.Level`.
+
+## test logging output
+
+To test if the logging as such works,
+you can pass a test string:
+```java
+Logging.test("test message");
+```
+
+This message will be logged by the `Logging`-class own Logger,
+once per level.
+
+## set custom formatter
+
+If you need another format,
+you can replace the default formatter of this lib by calling:
+```java
+Logging.setFormatter(Formatter);
+```
+
+This formatter has to be of type `java.util.logging.Formatter`
diff --git a/docs/api/core/ticket-system.md b/docs/api/core/ticket-system.md
new file mode 100644
index 0000000000000000000000000000000000000000..17d4790e1925fda15c8957e9e3ce60adc151ce58
--- /dev/null
+++ b/docs/api/core/ticket-system.md
@@ -0,0 +1,159 @@
+# Ticketsystem
+
+A `TicketSystem` object represents a connection definition to a space in an external ticket system.
+Part of this is a base URL, and some system specific identifier for e.g. a project on that system.
+If the access needs some kind of authentication,
+this has to be configured in this object on creation.
+
+## create new instance
+
+The constructor of `TicketSystem` is not publicly callable.
+Acquiring an instance has to be done either by passing an URI or using the builder mechanism.
+
+### by URI
+
+This library has a global definition, for how an URI has to start.
+The end of it is defined by each system specific implementation.
+
+!!! info "global URI definition"
+ `unifiedticketing::`
+ _For system specific details look into the systems part of this docs_
+
+To instantiate a `TicketSystem` from an URI, call the static method `fromUri(String)`:
+
+```java
+TicketSystem ts = TicketSystem.fromUri();
+```
+
+!!! warning
+ If the given String does not match the criteria for a valid URI,
+ or the system identifier is unknown, it throws an `AssertionException`
+
+### by builder
+
+The library has a builder mechanism defined to instantiate a new `TicketSystem` object, using fluent-api.
+To start it, call the static method `fromBuilder()`.
+The returning object gives you all supported systems as choice,
+which then brings you to the system specific builder mechanism.
+
+At the end, you'll have to finish the building process with a call to `build()`.
+
+!!! warning
+ If not all mandatory information where given before calling `build()`,
+ it will throw an `AssertionException`
+
+## configuration options
+
+You can set configurations of two kinds:
+
+- simple boolean switches to enable/disable a behaviour/feature
+- string values
+
+To set a configuration, call the instance method `config`. It provides two signatures:
+
+- `config(TicketSystem.ConfigurationOption, boolean)`
+- `config(TicketSystem.ConfigurationOption, String)`
+
+??? abstract "currently available configuration options"
+ | ConfigurationOption | type | default | description |
+ | :------------------- | :------ | :------ | :------------------------------------------------------------------------------------------------ |
+ | RETURN_NULL_ON_ERROR | boolean | `false` | If true, don't throw exception on error, but return null or the calling object, if in fluent-api. |
+
+!!! warning
+ option `RETURN_NULL_ON_ERROR` is not fully implemented and tested yet.
+ Expect it still throws Exceptions sometimes, but returns null/self also sometimes.
+## list tickets
+
+Tickets are requested by using the filter mechanism.
+To get _all_ Tickets just don't define any filters before calling `get()`.
+They are returned as `List`.
+
+??? warning "default pagination"
+ many systems have an implicit default pagination enabled,
+ which could block you from simply getting _all_ tickets.
+
+ you can ask the `TicketSystem` object, to tell you if it uses a default pagination:
+
+ ```java
+ ts.hasDefaultPagination();
+ ```
+
+!!! info "assignees"
+ Tickets have a field of type `Assignee`.
+ These have final String fields,
+ where the system implementation puts values if supported.
+
+!!! example "requesting tickets"
+ ```java
+ ts.find()
+ .setPage(1)
+ .setPageSize(10)
+ .get();
+ ```
+
+You can add various filter options, before finally calling `get()`.
+Each supported systems implementation is free to define special filter options.
+These are only callable, if your variable has the dedicated child-type.
+
+The globally available ones are listed below.
+They are marked `single` or `multi` types.
+A `single` typed filter will override previous values,
+whereas `multi` typed ones will be added to the previous values.
+
+| filter option method definition | type | description |
+| :------------------------------- | :------- | :--------------------------------------------------------------------------------------------------------------- |
+| `isClosed()` | `single` | returns only tickets closed, or _considered_ closed by the system specific implementation |
+| `isOpen()` | `single` | returns only tickets open, or _considered_ open by the system specific implementation |
+| `setPage(int)` | `single` | page number of pagination to request |
+| `setPageSize(int)` | `single` | page size of request to paginate with |
+| `withAssigneeId(String)` | `multi` | tickets with given assigneeId as assignee.
On multiple calls ticket must have _ALL_ given ids as assignees |
+| `withAssigneeName(String)` | `multi` | same as assigneeId above |
+| `withDescriptionContain(String)` | `single` | substring the description has to contain |
+| `withDescriptionMatch(String)` | `single` | fully qualified regular expression, the whole description has to match |
+| `withId(String)` | `multi` | id a ticket must have.
multiple calls keeps tickets matching _any_ of the set ids |
+| `withLabel(String)` | `multi` | label a ticket must have.
Multiple calls a ticket must have _all_ given labels |
+| `withTitleContain(String)` | `single` | substring the title has to contain |
+| `withTitleMatch(String)` | `single` | fully qualified regular expression, the whole title has to match |
+
+## get single ticket
+
+To request a single ticket the method `getTicketById` is provided,
+available with two signatures:
+- `getTicketById(String)`
+- `getTicketById(int)`
+
+The integer variant is just for convenience, if you have the id as number.
+It calls the String one with your number transformed.
+
+!!! example
+ ```java
+ Ticket t = ts.getTicketById("5");
+ ```
+
+## create new ticket
+
+The creation of a new Ticket is started by calling `createTicket()`.
+This starts another fluid-api chain,
+in which you can set everything your new ticket should contain.
+The chain finishes calling `create()` at the end.
+
+!!! warning
+ if a mandatory information for ticket creation is not given,
+ prior calling `create()`,
+ an `AssertionException` is thrown.
+
+!!! example
+ ```java
+ Ticket t = ts.createTicket()
+ .title("some title")
+ .create();
+ ```
+
+Global available setters for ticket creation are:
+
+| method | additional information |
+| :--------------------------------------------- | :---------------------------------------------------------------------- |
+| `assignees(String[])` | array of assignee identifiers, check system specific part, what to pass |
+| `description(String)` | |
+| `labels(Set)`
`labels(String[])` | |
+| `title(String)` | |
diff --git a/docs/api/core/ticket.md b/docs/api/core/ticket.md
new file mode 100644
index 0000000000000000000000000000000000000000..38c58aa7a47536b4cce2f7dac469f22d8d737866
--- /dev/null
+++ b/docs/api/core/ticket.md
@@ -0,0 +1,57 @@
+# Ticket
+
+A ticket instance represents one ticket of the connected space.
+
+## get/create ticket
+
+The class is not publicly constructable,
+as it always belongs to a `TicketSystem` object.
+
+Getting an instance for a existing ticket,
+or creating a new one,
+is done from a `TicketSystem` instance.
+[->For details see here <-](./ticket-system.md)
+## reading data
+
+There are various getters available.
+Below the globally defined ones are listed,
+each system specific implementation is free to provide additional ones.
+
+!!! warning
+ systems are not guaranteed to support all data,
+ a global getter is defined for.
+ Therefore it can happen, you get an null value back
+ or exception thrown in this case.
+
+| method | return |
+| :----------------- | :-------------------- |
+| `getAssignees()` | `Set` |
+| `getDescription()` | `String` |
+| `getId()` | `String` |
+| `getLabels()` | `Set` |
+| `getParent()` | `TicketSystem` |
+| `getTitle()` | `String` |
+| `isOpen()` | `boolean` |
+
+## changing data
+
+You can change data of supported fields through dedicated setters.
+Every changed field is flagged as changed.
+To persist the changes to the connected space,
+you need to call `save()`.
+This forms an update request for all flagged fields
+and returns a new instance of `Ticket`,
+formed off the answer from the connected system.
+
+Below the globally defined setters are listed,
+each system implementation is free to offer more.
+
+| method | description |
+| :-------------------------------------------------- | :-------------------------------------------------------------- |
+| `addAssignee(String)`
`removeAssignee(String)` | adds/removes assignee, check system specific part, what to pass |
+| `addLabel(String)` | add label |
+| `clearAssignees()` | remove all assignees |
+| `open()`
`close()` | opens/closes the ticket |
+| `setDescription(String)` | |
+| `setLabels(Set)`
`setLabels(String[])` | replace all labels with the passed ones |
+| `setTitle(String)` | |
diff --git a/docs/api/exceptions.md b/docs/api/exceptions.md
new file mode 100644
index 0000000000000000000000000000000000000000..4b4cc724ae1e4ad5ebbb016769d6ff14a65aa33d
--- /dev/null
+++ b/docs/api/exceptions.md
@@ -0,0 +1,23 @@
+# Exceptions
+
+The library defines its own set of exceptions.
+Throughout the whole library, these are used.
+They are located in the package `de.hftstuttgart.unifiedticketing.exceptions`.
+
+Base for all others is `UnifiedticketingException`,
+which extends `RuntimeException`.
+Every other custom exception extends this exception.
+
+This provides you with the ability,
+to catch a specific or all library related problems.
+Both without catching exceptions of your own code,
+that happen to be in the same try block.
+
+## Possible Exceptions
+
+- `AssertionException`
+- `DeserializationException`
+- `HttpRequestException`
+- `HttpResponseException`
+- `SerializationException`
+- `UnsupportedFunctionException`
diff --git a/docs/api/index.md b/docs/api/index.md
new file mode 100644
index 0000000000000000000000000000000000000000..463afc33070d442393d3bad702ead024810076a6
--- /dev/null
+++ b/docs/api/index.md
@@ -0,0 +1,66 @@
+# Java-API
+
+This is the API-Documentation,
+holding detailed information for each publicly available action you can do with each class.
+Below the structure of the library is explained and some generic examples are shown.
+## library structure
+
+The library is structured into three packages:
+
+1. `de.hftstuttgart.unifiedticketing.core`
+1. `de.hftstuttgart.unifiedticketing.exceptions`
+1. `de.hftstuttgart.unifiedticketing.systems`
+
+The core package contains the classes defining the generic API,
+to be implemented by each supported system.
+The systems package contains a sub-package per supported system,
+which then holds the implementations of the core classes.
+The exceptions package has some own exception types,
+used throughout the lib.
+
+For each package, this documentation provides a chapter in the navigation on the left.
+
+## examples
+
+!!! info
+ These examples are not specific to a certain system.
+ Therefore they can contain placeholders for system specific parts.
+ To get these parts, you'll have to go to the dedicated API-docs part.
+
+??? example "create TicketSystem instance"
+ __from builder:__
+ ```java
+ TicketSystem ts = TicketSystem.fromBuilder()
+ .
+ .build();
+ ```
+
+ __from uri:__
+ ```java
+ TicketSystem ts = TicketSystem.fromUri();
+ ```
+
+??? example "searching tickets"
+ __without filters:__
+ ```java
+ ts.find().get();
+ ```
+
+ __only open tickets and explicit pagination:__
+ ```java
+ ts.find()
+ .isOpen()
+ .setPage(1)
+ .setPageSize(10)
+ .get();
+ ```
+
+??? warning "default pagination"
+ many systems have an implicit default pagination enabled,
+ which could block you from simply getting _all_ tickets.
+
+ !!! tip
+ you can ask the `TicketSystem` object, to tell you if it uses a default pagination:
+ ```java
+ ts.hasDefaultPagination();
+ ```
diff --git a/docs/api/systems/gitlab/ticket-system.md b/docs/api/systems/gitlab/ticket-system.md
new file mode 100644
index 0000000000000000000000000000000000000000..8ab3d36bb8d47929d4345a7e10c91827cac09614
--- /dev/null
+++ b/docs/api/systems/gitlab/ticket-system.md
@@ -0,0 +1,138 @@
+# GitLab-Ticketsystem
+
+This documents GitLab specific things for the integration to this library.
+For the global parts, see in the [core sections Ticketsystem site][core-ts].
+
+## create new instance
+
+A `GitlabTicketSystem` object is always referencing a specific GitLab project.
+Mandatory information to instantiate it, are the GitLab instances base url and the projects id.
+
+For public accessible actions, it can be used anonymously.
+Other operations have to be authenticated using an api-key.
+
+For all calls the GitLab api V4 is used (at the time of writing this, the only available one).
+If not configured otherwise, connections will use https.
+
+### by URI
+
+```java
+// recommended option
+GitlabTicketSystem ts = (GitlabTicketSystem) TicketSystem.fromUri("");
+
+// second possible declaration
+TicketSystem<
+ GitlabTicket,
+ GitlabTicketSystem,
+ GitlabTicketBuilder,
+ GitlabFilter
+ > gl = TicketSystem.fromUri("");
+```
+
+The first declaration option uses the child-class from the GitLab implementation directly.
+The second option uses the parent-class instead,
+defining the different implementations with Generics.
+
+Use the first option, if you're sure you want to use GitLab no matter what.
+This way you can see GitLab specific methods,
+whereas the second option keeps you limited on the global defined ones.
+If you may switch ticket systems in the future,
+the second option forces you to not use system specific stuff, making a transition easier.
+
+The URI to pass has to match this format:
+```
+unifiedticketing:gitlab:[http://|https://]:[:api key]
+```
+
+- protocol for http/https is optional. If not given, https is used
+- base url can contain also non-standard port hosted gitlab instances
+- api key if authentication needed, otherwise anonymous access is used
+
+??? example "URI examples"
+ - non-https anonymous, project 234, public gitlab
+ `unifiedticketing:gitlab:http://wwww.gitlab.com:234`
+ - implicit https authenticated, project 234, public gitlab
+ `unifiedticketing:gitlab:gitlab.com:234:1234896102765abcddbda324bb3a3`
+ - explicit https authenticated, project 42, fictional gitlab, non-standard port
+ `unifiedticketing:gitlab:https://gitlab.example.org:8080:42:1234896102765abcddbda324bb3a3`
+
+### by builder
+
+For instantiation from the builder,
+mostly the same like building by URI applies.
+
+!!! warning
+ Passing the base url ensure the protocol (http or https) is removed
+
+??? example "builder examples"
+ - non-https anonymous, project 234, public gitlab
+ ```java
+ GitlabTicketSystem ts = TicketSystem.fromBuilder()
+ .gitlab()
+ .withBaseUrl("www.gitlab.com")
+ .withHttp()
+ .withProjectId(234) // String and int variant available
+ .build();
+ ```
+ - implicit https authenticated, project 234, public gitlab
+ ```java
+ GitlabTicketSystem ts = TicketSystem.fromBuilder()
+ .gitlab()
+ .withBaseUrl("gitlab.com")
+ .withProjectId("234")
+ .withApiKey("1234896102765abcddbda324bb3a3")
+ .build();
+ ```
+ - explicit https authenticated, project 42, fictional gitlab, non-standard port
+ ```java
+ GitlabTicketSystem ts = TicketSystem.fromBuilder()
+ .gitlab()
+ .withBaseUrl("gitlab.example.org:8080")
+ .withHttps()
+ .withProjectId(42)
+ .withApiKey("1234896102765abcddbda324bb3a3")
+ .build();
+ ```
+
+## list tickets
+
+!!! warning "default pagination"
+ GitLab has a default pagination on _20_ elements per page.
+ Highest possible value is _100_ elements. [[Link]][gl-api-docs-pagination]
+
+!!! warning "mutual exclusive filters"
+ if you filter for assignees, you can only use either assignee-ids or their usernames. [[Link]][gl-api-docs-issues-list]
+
+!!! info "assignees"
+ GitLab implementation supports the fields `id`, `username` and `full name`.
+ If ticket has no assignee, assignee field stays `null`.
+
+From the filters shown on the global `TicketSystem` docs,
+the ones for regex-matching are not natively supported by the GitLab API.
+If such a filter is used,
+this get's done locally after receiving the response from GitLab,
+before handing it to the user.
+
+## get single ticket
+
+!!! info
+ This uses the list mechanism internally,
+ with the given issue-id as filter and just unwraps it from the received list.
+
+## create new ticket
+
+For a new GitLab ticket a title is mandatory.
+Everything else is optional.
+
+!!! example "minimal example"
+ ```java
+ GitlabTicket = ts.createTicket()
+ .title("my new ticket")
+ .create();
+ ```
+
+Setting an assignee, has to be by user-id. Setting by user name is not supported.
+
+[core-ts]: ../../core/ticket-system.md
+[gl-api-docs-issues-list]: https://docs.gitlab.com/ee/api/issues.html#list-issues
+[gl-api-docs-pagination]: https://docs.gitlab.com/ee/api/#pagination
diff --git a/docs/api/systems/gitlab/ticket.md b/docs/api/systems/gitlab/ticket.md
new file mode 100644
index 0000000000000000000000000000000000000000..c8a2b00405bed9110b28ab5784a6e436f70a2d51
--- /dev/null
+++ b/docs/api/systems/gitlab/ticket.md
@@ -0,0 +1,4 @@
+# Gitlab-Ticket
+
+!!! todo
+ write usage api docs
diff --git a/docs/developers-guide/machine-setup.md b/docs/developers-guide/machine-setup.md
new file mode 100644
index 0000000000000000000000000000000000000000..5d1bb2a1cdce9edf09af3df8ab9448878eb4c7fa
--- /dev/null
+++ b/docs/developers-guide/machine-setup.md
@@ -0,0 +1,255 @@
+# Machine Setup
+
+## General
+
+### Git
+
+The whole project is a Git repository,
+to do anything you'll need to have Git setup on your machine.
+
+!!! tip
+ We highly recommend you use Git directly typing commands to your terminal,
+ instead of relying on any GUI tools, IDE integration's whatsoever.
+ They make life easy, sure.
+ But do you know, what exact calls they do under the hood?
+
+#### Installation
+
+=== "*nix"
+ Should be part of all major systems default software distribution path.
+
+=== "Windows"
+ !!! warning "disclaimer"
+ This is for people having not much experience.
+ If you e.g. use Cygwin, you could just install Git from there and ignore this^^
+
+ - Download Git: [Git-SCM][gitscm-win]
+ - Installation recommendations:
+ - opt-out from `Enable Git Credential Manager`
+ _We had bad experiences with it, storing wrong passwords an no one knew where to remove them as none of the pros used this thing^^_
+
+#### Configuration
+
+After installing Git, you'll have to set a few information,
+in order to be able to work with it.
+Mandatory is your username and email.
+
+Globally set your most used username and email address you'll be using.
+
+```bash
+git config --global user.name ""
+git config --global user.email ""
+```
+
+!!! attention
+ If your global email is different from the one for this projects GitLab,
+ make sure to either add your main email address as committer email in your profile,
+ or change the git config for this project individually after cloning it.
+
+#### Clone project
+
+As of writing, the project can be accessed with HTTPS and SSH.
+If this is not working,
+check the repository from the link in the upper right corner of the page.
+(Maybe the path changed and someone forgot to update this part of the docs)
+
+=== "SSH"
+ ```bash
+ git clone git@transfer.hft-stuttgart.de:9Lukas5/unified-ticketing.git
+ ```
+
+=== "HTTPS"
+ ```bash
+ git clone https://transfer.hft-stuttgart.de/gitlab/9Lukas5/unified-ticketing.git
+ ```
+
+## Java Development
+
+The Java library is development with OpenJDK 8 and Maven 3.6
+
+### Requirements
+
+- Git setup
+- OpenJDK 1.8.0+
+- Maven 3.6.0+
+
+### Installation
+
+#### OpenJDK
+
+=== "*nix"
+ Check your specific systems package names.
+
+ __Ubuntu 20.04__:
+ ```bash
+ sudo apt install openjdk-11-jdk
+ ```
+
+=== "Windows"
+
+ - download OpenJDK: [jdk.java.net][java-net]
+ - extract archive to permanent place
+ - create/update system environment variable `JAVA_HOME`,
+ to the path you extracted OpenJDK to.
+ - update `PATH` variable including the `bin` folder of your newly placed OpenJDK
+ - check with a terminal that `java --version` works
+
+#### Maven
+
+=== "*nix"
+ Same as before, check your specific systems package names.
+
+ __Ubuntu:__
+ ```bash
+ sudo apt install maven
+ ```
+
+=== "Windows"
+
+ - download Maven binary: [maven.apache.org][maven-dl]
+ - extract archive to permanent place
+ - create/update system environment variable `MAVEN_HOME`,
+ to the path you extracted Maven to.
+ - update `PATH` including `bin` folder of maven home
+ - check that `mvn --version` works
+
+### Import project to IDE
+
+Following is described, how to import the maven project to your IDE.
+I really hope, you're familiar enough to know how to use your IDE,
+so this is a just-in-case service.
+
+Also, this does not claim to be up-to-date/correct/cover all available IDE's.
+You are invited to contribute to this list below
+if you're IDE of choice is not listed yet or has some faults.
+
+=== "IntelliJ IDEA"
+ - Select `Open or Import`
+ - Choose the folder you cloned the project into
+
+## MkDocs (Documentation)
+
+This project is documented using MkDocs Material.
+It means we write Markdown files, organize them in a configuration file
+and MkDocs generates a static Website out of it we host and you are reading right now.
+
+### Requirements
+
+- Python 3.5+
+- pip
+- Python virtual environment _(optional)_
+
+### Installation
+
+=== "*nix"
+ check system specific names and commands, below are some examples collected over time:
+
+ __Ubuntu:__
+ ```bash
+ sudo apt install python3 python3-pip python3-venv
+ ```
+
+=== "Windows"
+ - download & install Python: [python.org][python-win-dl] (use executable installer version)
+
+- open a terminal inside the project's root directory
+- _optional:_ create & activate new virtual environment:
+
+ === "*unix"
+ ```bash
+ python3 -m venv env
+ . ./env/bin/activate
+ ```
+
+ === "Windows"
+ === "CMD"
+ ```cmd
+ python -m venv env
+ env\scripts\activate.bat
+ ```
+ === "Power Shell"
+ !!! attention "execution policy"
+ You may have to first set the correct execution policy,
+ before able to run the activation script.
+
+ ```powershell
+ Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
+ ```
+
+ ```powershell
+ python -m venv env
+ env\scripts\Activate.ps1
+ ```
+
+- install all required packages:
+ ```
+ pip install -Ur requirements.txt
+ ```
+
+### Usage
+
+To work on the documentation, the mkdocs development server has to run.
+On start it tells you on which port it runs (default is `8000`).
+
+Open the Browser on the shown URL and edit the Markdown files.
+On saving changes your Browser should automatically reload the page.
+
+- _optional:_ enter python virtual environment
+
+ === "*unix"
+ ```bash
+ . ./env/bin/activate
+ ```
+
+ === "Windows"
+ === "CMD"
+ ```cmd
+ env\scripts\activate.bat
+ ```
+ === "Power Shell"
+ !!! attention "execution policy"
+ You may have to first set the correct execution policy,
+ before able to run the activation script.
+
+ ```powershell
+ Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
+ ```
+
+ ```powershell
+ env\scripts\Activate.ps1
+ ```
+
+- start MkDocs development server:
+ ```bash
+ mkdocs serve
+ ```
+- work
+- kill dev server by pressing `ctrl+c`
+- _optional:_ exit python virtual environment:
+ ```bash
+ deactivate
+ ```
+
+### Editor/IDE
+
+You don't need any special IDE, as a bare minimum a text editor would work (even vim is possible).
+__But don't you dare to use this crappy Microsoft built in editor!__
+
+Practically it's very supportive of course,
+to use a IDE that has good markdown support in terms of code-highlighting,
+table formatting, etc.
+Below are collected tips for different IDE's.
+
+=== "VSCode"
+ recommended extensions:
+ _these are the extension id's searchable from vscode_
+
+ - `editorconfig.editorconfig`
+ - `waderyan.gitblame`
+ - `yzhang.markdown-all-in-one`
+ - `jebbs.plantuml`
+
+[gitscm-win]: https://git-scm.com/download/win
+[java-net]: https://jdk.java.net/
+[maven-dl]: https://maven.apache.org/download.cgi
+[python-win-dl]: https://www.python.org/downloads/windows/
diff --git a/docs/developers-guide/styleguide.md b/docs/developers-guide/styleguide.md
new file mode 100644
index 0000000000000000000000000000000000000000..85c4e4db3db39d31f9b47400669a8be30f998418
--- /dev/null
+++ b/docs/developers-guide/styleguide.md
@@ -0,0 +1,99 @@
+# Styleguide
+
+If not explicitly stated otherwise,
+the following takes effect for all files:
+
+- character encoding __utf-8__
+- line endings with __lf__
+- indentation with __4 spaces__
+- final new line
+
+In general,
+it's a good idea to have a look into the yet existing code,
+to check how certain things were done up to now.
+
+## Java
+
+The most important thing to say here is: opening braces are written into the next line.
+_(more to come if s.o. does s.th. differently I didn't think of)_
+
+## Markdown
+
+most important bullet points:
+
+- leave always an empty line above and beneath of lists.
+ It may render fine in normal markdown viewers,
+ but not in the MkDocs Pages docs (like this)
+
+ ??? example inline end
+ __bad:__
+ ```markdown
+ some text
+ - bullet point
+ - another item
+ more normal text
+ ```
+ __good:__
+ ```markdown
+ some text
+
+ - bullet point
+ - another item
+
+ more normal text
+ ```
+
+- if you insert a link,
+ __always__ write the link to the bottom of the file with an alias,
+ ordered alphabetically.
+
+ ??? example
+ __bad:__
+ ```markdown
+ Look [here](https://www.coolsite.not/with/ultra/long/url) to read more about this.
+ ```
+ __good:__
+ ```markdown
+ Look [here][coolsite] to read more about this.
+
+ [coolsite]: https://www.coolsite.not/with/ultra/long/url
+ ```
+
+- split long sentences on punctuation and connection words like `and` & `or`.
+ It will have the same appearance in viewers,
+ but be much easier to maintain on code side.
+
+ ??? example
+ __bad__:
+ ```markdown
+ Some sentence that is very long, therefore it has punctuation and has absolutely no sense at all.
+ ```
+ > Some sentence that is very long, therefore it has punctuation and has absolutely no sense at all.
+
+ __good:__
+ ```markdown
+ Some sentence that is very long,
+ therefore it has punctuation
+ and has absolutely no sense at all.
+ ```
+
+ > Some sentence that is very long,
+ > therefore it has punctuation
+ > and has absolutely no sense at all.
+
+- tables have to be formatted in code
+
+ ??? example
+ __bad:__
+ ```markdown
+ ||column 1|
+ |:-|:-|
+ |__row 1__|cell 1|
+ ```
+
+ __good:__
+ ```markdown
+ | | column 1 |
+ | :-------- | :------- |
+ | __row 1__ | cell 1 |
+ ```
diff --git a/docs/developers-guide/uml.md b/docs/developers-guide/uml.md
new file mode 100644
index 0000000000000000000000000000000000000000..c3666ae1af6d479a067cea973f12e996739251ce
--- /dev/null
+++ b/docs/developers-guide/uml.md
@@ -0,0 +1,411 @@
+# Library UML-Diagram
+
+This is the full UML-diagram for the Unified-Ticketing library.
+
+!!! tip
+ You most likely can't read anything embedded to the site,
+ please open the graphics-URL in an extra tab and zoom in.
+
+```plantuml
+
+abstract Filter {
+ __ generics definition __
+ T extends Ticket
+ F extends Filter
+ ==
+ - {static} logger: Logger
+
+ # {static} addToSet(\n\tfilterName: FilterNames,\n\tmap: Map,\n\tnewValue: String\n)
+
+ __ instance definition __
+ # setFilters: Map
+
+ + constructor()
+
+ + withAssigneeId(id: String): F
+ + withAssigneeName(name: String): F
+ + withDescriptionContain(substring: String): F
+ + withDescriptionMatch(regex: String): F
+ + withId(id: string): F
+ + isOpen(): F
+ + isClosed(): F
+ + withLabel(label: String): F
+ + setPage(page: int): F
+ + setPageSize(size: int): F
+ + withTitleContain(substring: String): F
+ + withTitleMatch(regex: String): F
+
+ + {abstract} get(): List
+}
+
+enum FilterNames {
+ + ASSIGNEEID
+ + ASSIGNEENAME
+ + DESCRIPTION_CONTAIN
+ + DESCRIPTION_MATCH
+ + IDS
+ + LABELS
+ + OPEN
+ + PAGE
+ + PAGINATION
+ + TITLE_CONTAINS
+ + TITLE_MATCH
+}
+
+class Logging {
+ - {static} handler: Handler
+ - {static} mainLogger: Logger
+ - {static} logger: Logger
+
+ + {static} getLogger(name: String): Logger
+ + {static} setFormatter(formatter: Formatter): void
+ + {static} setLevel(level: Level): void
+ + {static} test(message: String): void
+}
+
+class RegisteredSystems <<(S, orange)>> {
+ - {static} logger: Logger
+ - {static} instance: RegisteredSystems
+
+ # {static} getInstance(): RegisteredSystems
+
+ __ instance definition __
+ + constructor()
+
+ + gitlab(): GitlabTicketSystemBuilder
+}
+
+abstract Ticket {
+ __ generics definition __
+ T \t extends Ticket
+ TS \t extends TicketSystem
+ ==
+ - {static} logger: Logger
+
+ __ instance definition __
+ # assignees: Set
+ # description: String
+ # id: String
+ # labels: Set
+ # open: boolean
+ # title: String
+
+ # updatedFields: Set
+ # parent: TS
+
+ # constructor(parent: TS)
+
+ + getAssignees(): Set extends TicketAssignee>
+ + {abstract} addAssignee(identifier: String): T
+ + clearAssignees(): T
+ + {asbtract} removeAssignee(identifier: String): T
+ + getDescription(): String
+ + setDescription(description: String): T
+ + getId(): String
+ + addLabel(label: String): T
+ + getLabels(): Set
+ + setLabels(labels: Set): T
+ + setLabels(labels: String[]): T
+ + isOpen(): boolean
+ + open(): T
+ + close(): T
+ + getParent(): TS
+ + getTitle(): String
+ + setTitle(title: String): T
+
+ + {abstract} save(): T
+
+ + equals(o: Object): boolean
+ + hashCode(): int
+ + toString(): String
+}
+
+enum FieldNames {
+ + ASSIGNEES
+ + DESCRIPTION
+ + ID
+ + LABELS
+ + OPEN
+ + TITLE
+}
+
+abstract TicketAssignee {
+ + email: String
+ + id: String
+ + fullName: String
+ + username: String
+
+ # constructor(\n\temail: String,\n\tid: String,\n\tusername: String,\n\tfullName: String\n)
+
+ + equals(o: Object): boolean
+ + hashCode(): int
+ + toString(): String
+}
+
+abstract TicketBuilder {
+ __ generics definition __
+ B \t extends TicketBuilder
+ T \t extends Ticket
+ TS \t extends TicketSystem
+ ==
+ - {static} logger: Logger
+
+ __ instance definition __
+ # assignees: Set
+ # description: String
+ # labels: Set
+ # title: String
+
+ # constructor(parent: TS)
+
+ + assignees(identifiers: String...): B
+ + description(description: String): B
+ + labels(labels: Set): B
+ + labels(labels: String[]): B
+ + title(title: String): B
+
+ + {abstract} create(): T
+}
+
+abstract TicketSystem {
+ __ generics definition __
+ B \t extends TicketBuilder
+ F \t extends Filter
+ T \t extends Ticket
+ TS \t extends TicketSystem
+ ==
+ - {static} logger: Logger
+
+ + {static} fromBuilder(): RegisteredSystems
+ + {static} fromUri(uri: String): TicketSystem
+
+ __ instance definition __
+ + apiKey: String
+ + baseUrl: String
+ + password: String
+ + username: String
+
+ # configuration: Map
+
+ + constructor()
+
+ + config(option: ConfigurationOptions, value: String): TS
+ + config(option: ConfigurationOptions, value: boolean): TS
+ + getConfigTrue(option: ConfigurationOptions): boolean
+ + getConfigValue(option: ConfigurationOptions): Object
+ + {abstract} createTicket(): TB
+ + {abstract} find(): F
+ + {abstract} getTicketById(id: String): T
+ + {abstract} getTicketById(id: int): T
+
+ + {abstract} hasAssigneeSupport(): boolean
+ + {abstract} hasDefaultPagination(): boolean
+ + {abstract} hasLabelSupport(): boolean
+ + {abstract} hasPaginationSupport(): boolean
+ + {abstract} hasReturnNullOnErrorSupport(): boolean
+}
+
+enum ConfigurationOptions {
+ + RETURN_NULL_ON_ERROR
+}
+
+abstract TicketSystemBuilder {
+ __ generics definition __
+ B \t extends TicketBuilder
+ TS \t extends TicketSystem
+ ==
+ - {static} logger: Logger
+
+ __ instance definition __
+ + baseUrl: String
+
+ + withBaseUrl(url: String): B
+
+ + {abstract} build(): TS
+}
+
+' package connections
+Filter *-- FilterNames: "inner class"
+TicketSystem --> RegisteredSystems: "fromBuilder()"
+TicketSystem *-- ConfigurationOptions: "inner class"
+Ticket *-- FieldNames: "inner class"
+Ticket --> Ticket: "save()"
+Ticket o-- TicketSystem: "parent"
+Ticket o-- TicketAssignee
+TicketSystem --> TicketBuilder: "createTicket()"
+TicketBuilder --> Ticket: "create()"
+
+class AssertionException {
+ + constructor()
+ + constructor(msg: String)
+ + constructor(msg: String, cause: Throwable)
+ + constructor(suppressed: Throwable)
+}
+
+class DeserializationException {
+ + constructor()
+ + constructor(msg: String)
+ + constructor(msg: String, cause: Throwable)
+ + constructor(suppressed: Throwable)
+}
+
+class HttpRequestException {
+ + constructor()
+ + constructor(msg: String)
+ + constructor(msg: String, cause: Throwable)
+ + constructor(suppressed: Throwable)
+}
+
+class HttpResponseException {
+ + constructor()
+ + constructor(msg: String)
+ + constructor(msg: String, cause: Throwable)
+ + constructor(suppressed: Throwable)
+}
+
+class SerializationException {
+ + constructor()
+ + constructor(msg: String)
+ + constructor(msg: String, cause: Throwable)
+ + constructor(suppressed: Throwable)
+}
+
+class UnifiedticketingException {
+ + constructor()
+ + constructor(msg: String)
+ + constructor(msg: String, cause: Throwable)
+ + constructor(suppressed: Throwable)
+}
+
+class UnsupportedFunctionException {
+ + constructor()
+ + constructor(msg: String)
+ + constructor(msg: String, cause: Throwable)
+ + constructor(suppressed: Throwable)
+}
+
+AssertionException -[hidden]down- DeserializationException
+DeserializationException -[hidden]down- HttpRequestException
+HttpRequestException -[hidden]down- HttpResponseException
+HttpResponseException -[hidden]down- SerializationException
+SerializationException -[hidden]down- UnifiedticketingException
+UnifiedticketingException -[hidden]down- UnsupportedFunctionException
+
+class GitlabFilter {
+ - {static} logger: Logger
+
+ __ instance definition __
+ # parent: GitlabTicketSystem
+
+ # getHttpClient(): OkHttpClient
+ + get(): List
+}
+
+class GitlabTicket {
+ - {static} logger: Logger
+
+ # {static} fromTicketResponse(\n\tparent: GitlabTicketSystem,\n\tresponse: GitlabTicketResponse\n): GitlabTicket
+
+ __ instance definition __
+ # constructor(parent: GitLabTicketSystem)
+
+ + addAssignee(userId: String): GitlabTicket
+ + addAssignee(userId: int): GitlabTicket
+ + removeAssignee(userId: String): GitlabTicket
+ + removeAssignee(userId: int): GitlabTicket
+ + save(): GitlabTicket
+
+ + deepEquals(o: Object): boolean
+}
+
+class GitlabTicketAssignee {
+ # constructor(id: int, fullName: String, username: String)
+}
+
+class GitlabTicketBuilder {
+ - {static} logger: Logger
+
+ __ instant definition __
+ # constructor(parent: GitlabTicketSystem)
+
+ + assignees(identifiers: String...): GitlabTicketBuilder
+ + assignees(identifiers: int...): GitlabTicketBuilder
+
+ # getHttpClient(): OkHttpClient
+ + create(): GitlabTicket
+}
+
+class GitlabTicketResponse {
+ + assignees: List
+ + description: String
+ + iid: int
+ + labels: Set
+ + state: String
+ + title: String
+
+ # constructor()
+}
+
+class Assignee {
+ + id: int
+ + name: String
+ + username: String
+}
+
+class GitlabTicketSystem {
+ - {static} logger: Logger
+
+ + {static} fromUri(uri: String): GitlabTicketSystem
+
+ __ instance definition __
+ # constructor()
+ + createTicket(): GitlabTicketBuilder
+ + find(): GitlabFilter
+ + getTicketById(id: String): GitlabTicket
+
+ + hasAssigneeSupport(): boolean
+ + hasDefaultPagination(): boolean
+ + hasLabelSupport(): boolean
+ + hasPaginationSupport(): boolean
+ + hasReturnNullOnErrorSupport(): boolean
+}
+
+class GitlabTicketSystemBuilder {
+ - {static} logger: Logger
+
+ __ instance definition __
+ # apiKey: String
+ # apiVersion: String
+ # projectId: int
+ # https: boolean
+
+ + constructor()
+
+ + withApiKey(apiKey: String): GitlabTicketSystemBuilder
+ + withHttp(): GitlabTicketSystemBuilder
+ + withHttps(): GitlabTicketSystemBuilder
+ + withProjectId(projectId: int): GitlabTicketSystemBuilder
+ + withProjectId(projectId: String): GitlabTicketSystemBuilder
+
+ + build(): GitlabTicketSystem
+}
+
+' package connections
+GitlabFilter o-- GitlabTicketSystem: "parent"
+GitlabTicketResponse o- Assignee: "inner class"
+GitlabTicketSystemBuilder --> GitlabTicketSystem: "build()"
+GitlabTicketSystem --> GitlabTicketBuilder: "createTicket()"
+GitlabTicketBuilder --> GitlabTicket: "create()"
+GitlabTicketSystem *-- GitlabTicketResponse
+
+' core package connections
+GitlabFilter --|> Filter
+GitlabTicket --|> Ticket
+GitlabTicketAssignee --|> TicketAssignee
+GitlabTicketBuilder --|> TicketBuilder
+GitlabTicketSystem --|> TicketSystem
+GitlabTicketSystemBuilder --|> TicketSystemBuilder
+
+RegisteredSystems --> GitlabTicketSystemBuilder: "gitlab()"
+
+```
diff --git a/docs/developers-guide/workflow.md b/docs/developers-guide/workflow.md
new file mode 100644
index 0000000000000000000000000000000000000000..7373caafcc6363df474f20631b6bc47c304507f5
--- /dev/null
+++ b/docs/developers-guide/workflow.md
@@ -0,0 +1,397 @@
+# Workflow
+
+This project is maintained in a GitLab repository,
+hosted on the [M4Lab's][m4lab] [Transfer-Portal][tr-portal] [GitLab instance][tr-gitlab].
+Source code for the maven Java library and the markdown docs are managed together in a [single repository][lib-repo-home].
+
+This page tells you for the different parts of this project,
+how to do it.
+The following applies project wide:
+
+- language is english: code, comments, documentation, tickets, discussion, ...
+
+## Git/GitLab
+
+!!! danger "disclaimer"
+ There are a few rules any developer HAS TO follow,
+ in order to get any chance his merge-requests will be accepted.
+
+This project is managed using Git, hosted on the universities GitLab instance.
+
+### Issues/Merge Requests handling
+
+Project management happens in the GitLab repositories issue board.
+
+First of all, make sure for everything you do a ticket exists.
+Extending this, also check regularly your tickets are:
+
+- assigned to you
+- are in the correct column
+
+There are three columns as of writing this documentation: `To Do`, `Doing` and `review`.
+Planning something, a new ticket get's created and placed into the `To Do` column.
+
+If you start to work on this ticket
+
+- move it to `Doing`
+- create a new feature branch from the master
+ - named like: `-`
+- push the new branch
+- create a new merge request
+ - title starting with `wip: `
+ - description containing `closes #`
+ - assign it to you (even if you're not able to merge)
+- start working
+
+After implementing your change
+
+- move your ticket to `review` column
+- change your merge requests labels: remove `Doing` and add `review`
+- change assignee to someone to review your work
+
+### Branch Names
+
+Branches should always start with the number of the related ticket, followed by a dash.
+This way the branch get's automatically shown in the ticket.
+
+### Committing
+
+!!! tip "golden rules"
+ - __many small__ > ~~few big~~ commits
+ - unrelated changes in separate commit
+
+We encourage everyone to make heavy use of `git status` and `git diff`.
+Please always check before committing, what exactly you have changed.
+What we won't accept:
+
+- whole file content removed and added back
+ This most likely happens if you make great use of auto format,
+ messing everything up.
+ Another one error source is something changed line endings.
+- empty lines containing spaces, or trailing spaces on line end (without technical reason)
+ No big deal to fix, but time waste if we have to block your MR because of this.
+- multiple changes in one commit, that have nothing to do with each other
+ Great you have fixed a typo in a comment at the other end of the file.
+ What do you think happens, if five people fix the same typo in their commits?
+ We would have four merge conflicts, needing manual work to fix this mess.
+ So create a new ticket for what you found,
+ instead of just doing it as it doesn't hurt.
+ It hurts, trust me.
+- commit messages not following conventional commits specification
+
+!!! tip "view diff of not yet tracked files"
+ If you want to check a new file for flaws, sure `git diff` doesn't show anything.
+ But you can add the file and before committing check with `git diff --cached`.
+
+!!! tip "add only parts of changes in a file"
+ As we want to have more small commits, than one single big one,
+ it can be useful to split your changes into multiple commits,
+ even inside the same file.
+ You can use `git add -p [path|file]`.
+ This allows you to exactly decide which lines of your changes should be staged
+ , before committing.
+
+#### Commit Messages
+
+We use the [conventional commits][conv-comm] specification in this repository,
+to auto generate a changelog with [conventional-changelog][conv-change].
+
+### Protected Branches/Tags
+
+The repository has the master branch and release tags (format `^[0-9]+\.[0-9]+\.[0-9]+$`)
+protected to project maintainers.
+
+### Branching-Model
+
+We use a branch per feature based branching model.
+Base and target to merge is always latest `master`.
+
+## Java Development
+
+First step before changing the source code,
+would be to check if there's something going on yet,
+or this topic possibly was discussed yet and abandoned for some reason.
+For this, check the [defined GitLab workflow](#gitgitlab).
+
+This library is a maven project.
+In order to contribute to it,
+make sure your machine is setup according to the [setup guide][setup-guide].
+
+### Change an existing functionality
+
+- check with the [source structure below](#source-code-structure),
+ where to find the part you want to change.
+- make your changes
+- make sure all unittests still pass
+- commit your changes following the Git/GitLab workflow defined.
+
+### Add integration for new system
+
+- familiarize with the [code structure](#source-code-structure)
+- create a new package under `de.hftstuttgart.unifiedticketing.systems`,
+ identifying the new system
+- prepare to implement all abstract classes from the `core` package
+ - class names have to be the same as the `core` ones,
+ prefixed with the identifier you named your package after
+- create unittests for the planned integration,
+ either by putting a `fail();` into each testmethod,
+ or really writing tests first for TDD
+- commit & push this skeleton-like state
+- create WIP merge-request
+- implement
+
+### Source code structure
+
+After cloning the repository,
+you'll have to open/import an existing maven project in your IDE of choice.
+There WILL NOT be any configuration files for a specific IDE committed into the code.
+In regards to the maven project parts,
+only the `pom.xml` and the contents under `/src` are committed.
+
+The main package for everything of this library is `de.hftstuttgart.unifiedticketing`.
+Beneath it is split into three sub-packages:
+
+| subpackage | content |
+| :----------- | :------------------------------------------------------------------------- |
+| `core` | root classes defining lib core, generic public interface |
+| `exceptions` | library own exceptions |
+| `systems` | subpackage per system integration, implementation of abstract core-classes |
+
+__core:__
+The majority of the classes are abstract ones.
+They define the generic interface available to the user of this lib.
+Logic identical for all system integrations are found in these classes.
+Only few methods are really declared abstract,
+in most cases it's the part calling the external system.
+
+__exceptions:__
+The library defines its own exceptions, based on `RuntimeException`.
+If you throw any exception,
+__only__ use exceptions from this package,
+never anything else.
+
+If you miss an exception you'd like to throw,
+add a new one that extends `UnifiedTicketingException`.
+
+__systems:__
+Each system that's integrated into this lib,
+will have a sub-package under `de.hftstuttgart.unifiedticketing.systems`.
+In this very own package every abstract class from the `core`-package has to be implemented.
+Apart from that,
+every system can define as many helper classes
+or additional sub-packages.
+
+### Unittests
+
+The logical code is structured under `/src/main/java`.
+For unittests the same package structure is created under `/src/test/java`.
+Tests are written using the `jupiter-engine` from JUnit5,
+combined with `Mockito3`.
+
+- test-classes are named identical to the class under test,
+ suffixed with `Test`
+- test-classes have to be in the same package than the class under test
+
+What has to be tested:
+
+- constructors
+- getters/setters
+- calculations/transformations/...
+- fluent-api to return the same instance
+- serializing request data before request
+- failing web-request
+- successful web-request & deserializing of received data
+
+!!! warning "testing external resources"
+ All tests _have to_ run offline.
+ To test external resources,
+ e.g. a web-request,
+ use Mockito to block the code under test to really access the external resource
+ and transparently return your mock answer expected for the assertions following.
+
+??? tip "test abstract classes"
+ To test non-abstract code of abstract classes,
+ you can instantiate a mock of it through Mockito,
+ set to call the real methods:
+
+ ```java
+ instance = mock(ClassUnderTest.class,
+ withSettings().useConstructor().defaultAnswer(CALLS_REAL_METHODS));
+ ```
+
+## Documentation
+
+Documentation for the project is done entirely in Markdown
+and rendered through MkDocs to a Website.
+The repository global `README.md` just points to the documentation root,
+which is `/docs/index.md`.
+The same applies for the `CONTRIBUTING.md`.
+`CHANGELOG.md` and `LICENSE.md` are kept with content in project root,
+they are linked with a relative soft-link into the documentation folder.
+
+Files related to the documentation:
+
+| path | description |
+| :----------------- | :---------------------------------------------- |
+| `mkdocs.yml` | configuration file for mkdocs |
+| `requirements.txt` | needed pypi packages to pass to pip for install |
+| `/docs/**/*` | documentation files |
+| `/docs/index.md` | Pages root |
+
+With the aim to give the documentation an appealing appearance,
+additional to the default markdown specification,
+a few extensions are enabled in the mkdocs config.
+Please have a look at them and make use of,
+where it seems adequate.
+Reference for them can be found in the [MkDocs-Material site][mat-mkdocs-ext-ref].
+
+To make any kind of diagram, sketch or similar,
+use [PlantUML][puml].
+You have to surround the PlantUML code with code fences,
+marked as `plantuml` as language identifier.
+Then they will be rendered into an svg on pages creation.
+
+!!! bug
+ I tried to put this into an collapsed example admonition,
+ but the PlantUML diagram get's always placed outside the admonition.
+ Same applies for a tabbed environment.
+
+Example:
+__code:__
+``````
+```plantuml
+queue "write\nmarkdown" as write
+queue "commit/push/\nmerge changes" as update
+queue "pipeline\ntriggered" as cicd
+queue "MkDocs\nMaterial" as MkDocsMat
+queue "transpiled HTML\nonline" as deployed
+
+write -right-> update
+update -right-> cicd
+cicd -right-> MkDocsMat
+MkDocsMat -right-> deployed
+```
+``````
+
+__result:__
+```plantuml
+queue "write\nmarkdown" as write
+queue "commit/push/\nmerge changes" as update
+queue "pipeline\ntriggered" as cicd
+queue "MkDocs\nMaterial" as MkDocsMat
+queue "transpiled HTML\nonline" as deployed
+
+write -right-> update
+update -right-> cicd
+cicd -right-> MkDocsMat
+MkDocsMat -right-> deployed
+```
+
+## Schedule a release
+
+For releases this project uses [standard-version][std-ver].
+This generates an automatic changelog based on the commits
+and tags it.
+The version of the library has three numbers
+and has to follow the [semantic-version][semver] scheme.
+
+Tags marking a release have the format `^[0-9]+\.[0-9]+\.[0-9]+$`.
+Pushing these tags is restricted in the GitLab Repo settings
+for maintainers only.
+Pushing a release tag triggers the CI/CD release pipeline for the maven project.
+
+## CI/CD
+
+This project uses GitLab-CI pipelines for
+
+- publishing the maven library to the repository own package registry
+- deploying this pages documentation
+
+These pipelines are defined in several files:
+
+| file | content |
+| :---------------------- | :------------------------------------------------------------ |
+| `.gitlab-ci.yml` | root file, stages definition, include of other pipeline parts |
+| `.gitlab-ci-maven.yml` | jobs regarding java library |
+| `.gitlab-ci-mkdocs.yml` | jobs regarding pages documentation |
+
+pipeline graph overview:
+```plantuml
+rectangle "compile" as stageCompile {
+ ' maven
+ agent "maven:compile" as mvnCompile
+
+ ' mkdocs
+ agent "mkdocs:compile" as mkdocsCompile
+}
+rectangle "test" as stageTest {
+ ' maven
+ agent "maven:test" as mvnTest
+
+ ' mkdocs
+ agent "none" as mkdocsTest
+}
+rectangle "deploy" as stageDeploy {
+ ' maven
+ agent "maven:publish:master" as mvnPublMaster
+ agent "maven:publish:release" as mvnPublRelease
+ label "get's deployed with\n'devel' as version" as labelMvnPublMaster
+ label "get's deployed\nwith release version" as labelMvnPublRelease
+
+ ' mkdocs
+ agent "mkdocs:bundle" as mkdocsBundle
+ agent "mkdocs:deploy" as mkdocsDeploy
+ label "creates tar archive as\ndownloadable job artifact" as labelMkdocsBundle
+ label "only triggered\non master branch" as labelMkdocsDeploy
+}
+
+' maven pipeline connections
+mvnCompile -right-> mvnTest
+mvnTest -right-> mvnPublMaster
+mvnTest -right-> mvnPublRelease
+
+mvnPublMaster -right- labelMvnPublMaster
+mvnPublRelease -right- labelMvnPublRelease
+
+' mkdocs pipeline connections
+mkdocsCompile -right-> mkdocsTest
+mkdocsTest -right-> mkdocsBundle
+mkdocsTest -right-> mkdocsDeploy
+
+mkdocsBundle -right- labelMkdocsBundle
+mkdocsDeploy -right- labelMkdocsDeploy
+
+' compile stage keep in place
+mvnCompile --[hidden]down- mkdocsCompile
+
+' test stage keep in place
+mvnTest --[hidden]down-mkdocsTest
+
+' deploy stage keep in place
+mvnPublMaster -[hidden]down- mvnPublRelease
+mvnPublRelease -[hidden]down- mkdocsBundle
+mkdocsBundle -[hidden]down- mkdocsDeploy
+```
+
+These jobs are defined with the `needs` keyword,
+to make them only depend on exactly the needed previous jobs.
+This makes it possible to run docs and library pipelines in parallel,
+without waiting that all jobs of a stage must have finished before entering the next stage.
+
+With the `only` keyword the trigger of these pipelines is optimized,
+to only run if necessary.
+In general the final deployment jobs have configurations to run only on the secured branches/tags.
+Additionally all jobs are configured to only run,
+if changes on related files of this pipeline were made.
+
+[conv-comm]: https://www.conventionalcommits.org/en/v1.0.0/
+[conv-change]: https://github.com/conventional-changelog/conventional-changelog
+[lib-repo-home]: https://transfer.hft-stuttgart.de/gitlab/9Lukas5/unified-ticketing/
+[m4lab]: https://www.hft-stuttgart.de/forschung/innovative-hochschule-m4-lab
+[mat-mkdocs-ext-ref]: https://squidfunk.github.io/mkdocs-material/reference/abbreviations/
+[puml]: https://plantuml.com/
+[setup-guide]: /404.html
+[semver]: https://semver.org/
+[std-ver]: https://github.com/conventional-changelog/standard-version
+[tr-gitlab]: https://transfer.hft-stuttgart.de/gitlab/explore/projects
+[tr-portal]: https://transfer.hft-stuttgart.de/
diff --git a/docs/index.md b/docs/index.md
index 89802646862816fe7be48552e85509066943765c..14ae6b667f62fb2dc526143ca7585261b7e8d558 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -1,3 +1,78 @@
+[![maven][badge-latest-tag]][project-packages]
+[![pipeline state][badge-master-pipe]][project-pipelines]
+[![latest dev pipeline][badge-latest-pipe]][project-pipelines]
+[![License GPLv3][badge-gplv3]][gplv3]
+[![Conventional Commits][badge-conventional-commits]][convcomm]
+
# Unified Ticketing
-!!! Todo
+This is the documentation for a Java-library called `unified-ticketing`.
+This lib provides generic interfaces to interact with tickets
+from different ticket systems out of your Java code.
+
+This library is a maven artifact,
+published under the [GNU GPL-v3][gplv3] license.
+The source code is publicly available from the [transfer portal][transferportal] of the [University of Applied Sciences Stuttgart][hfthome].
+
+## What to find where
+
+The documentation is split in three main parts, navigable on the top-bar.
+Each main-part gives you a navigation of it's content on the left.
+On the right, the currents page table of contents is shown.
+The icon in the upper left brings you from anywhere back to this start-page.
+In the upper right you can go to the source code repository of this library and documentation.
+Leftwards a full-text search is provided.
+
+The part you are reading right now (__Home__), is the main website.
+Following is a list, what each site contains:
+
+ - __Changelog:__ auto-generated changelog from the commits
+ - __Contributing:__
+ - Prerequisites to be able to be a contributor to this project
+ - __License:__ GNU GPLv3 content
+ - __Usage:__
+ - needed entries to get this library into your own maven-project
+ - some code-snippets showing the libs capabilites
+
+The __API__ part holds a detailed description, for each publicly accessible class and their methods.
+There is an own index file, explaining the package structure of the library
+and how it is documented.
+
+The __Developers Guide__ is the part, you have to lookup how to setup your machine and conventions and workflows used in this project,
+if you decide to contribute to it.
+
+## Maintainer
+
+This library and it's development belongs to the University of Applied Sciences Stuttgart.
+
+It was originally developed as bachelors-thesis by Lukas Wiest
+[:material-email-send:{: style="color: black"}][9l5-hft-mail]
+[:fontawesome-brands-twitter:{: style="color: #1DA1F2"}][9l5Twitter]
+[:fontawesome-brands-github:{: style="color: black"}][9l5GH]
+[:fontawesome-brands-gitlab:{: style="color: orange"}][9l5GL].
+The guardian professor was Prof. Dr. Gero Lueckemeyer
+[:material-email-send:{: style="color: black"}][lueck-hft-mail]
+[:fontawesome-solid-university:{: style="color: black"}][lueck-hft-profile]
+[:fontawesome-brands-github:{: style="color: black"}][lueck-GH]
+[:fontawesome-brands-xing:{: style="color: teal"}][lueck-Xing].
+He is the current maintainer for this project and the appropriate contact for questions, access request, etc.
+
+[9l5-hft-mail]: mailto:62wilu1bif@hft-stuttgart.de
+[9l5GH]: https://www.github.com/9Lukas5
+[9l5GL]: https://www.gitlab.com/9Lukas5
+[9l5Twitter]: https://twitter.com/9Lukas5
+[badge-conventional-commits]: https://img.shields.io/badge/Conventional%20Commits-1.0.0-orange.svg
+[badge-gplv3]: https://img.shields.io/badge/License-GPLv3-blue.svg
+[badge-latest-pipe]: https://img.shields.io/badge/dynamic/json?color=lightgrey&label=latest%20dev%20pipeline&query=%24%5B0%5D.status&url=https%3A%2F%2Ftransfer.hft-stuttgart.de%2Fgitlab%2Fapi%2Fv4%2F%2Fprojects%2F154%2Fpipelines%3Fper_page%3D1
+[badge-latest-tag]: https://img.shields.io/badge/dynamic/json?color=green&label=maven&query=%24%5B0%5D.name&url=https%3A%2F%2Ftransfer.hft-stuttgart.de%2Fgitlab%2Fapi%2Fv4%2Fprojects%2F154%2Frepository%2Ftags%3Fper_page%3D1
+[badge-master-pipe]: https://transfer.hft-stuttgart.de/gitlab/9Lukas5/unified-ticketing/badges/master/pipeline.svg
+[convcomm]: https://conventionalcommits.org
+[gplv3]: unified-ticketing/license-softlink.md
+[hfthome]: https://www.hft-stuttgart.de
+[lueck-GH]: https://github.com/lueckemeyer
+[lueck-hft-mail]: mailto:gero.lueckemeyer@hft-stuttgart.de
+[lueck-hft-profile]: https://www.hft-stuttgart.de/p/gero-lueckemeyer
+[lueck-Xing]: https://www.xing.com/profile/Gero_Lueckemeyer
+[project-packages]: https://transfer.hft-stuttgart.de/gitlab/9Lukas5/unified-ticketing/-/packages
+[project-pipelines]: https://transfer.hft-stuttgart.de/gitlab/9Lukas5/unified-ticketing/pipelines
+[transferportal]: https://transfer.hft-stuttgart.de
diff --git a/docs/unified-ticketing/changelog-softlink.md b/docs/unified-ticketing/changelog-softlink.md
new file mode 120000
index 0000000000000000000000000000000000000000..699cc9e7b7c5bf63c3549abe36e3eecf8efab625
--- /dev/null
+++ b/docs/unified-ticketing/changelog-softlink.md
@@ -0,0 +1 @@
+../../CHANGELOG.md
\ No newline at end of file
diff --git a/docs/unified-ticketing/contributing.md b/docs/unified-ticketing/contributing.md
new file mode 100644
index 0000000000000000000000000000000000000000..ccdc25e47930548ae5bb63a2a0d3689ebb3d566c
--- /dev/null
+++ b/docs/unified-ticketing/contributing.md
@@ -0,0 +1,19 @@
+# Contributing
+
+To contribute to this project,
+you primarily have to be a member of the University of Applied Sciences Stuttgart.
+This project is hosted on our Transferportal's GitLab instance,
+to which only HFT members have access to my knowledge.
+
+Apart from that, for contributing to the library code itself,
+you should be able to program Java and be familiar with maven.
+For the documentation you need to have Python installed and know how to write Markdown.
+
+For all contributions you need to use Git.
+
+For details see the [Developer Guide][dev-guide].
+There you can find information about getting ready,
+what rules to follow
+and more developers than user based documentation about the library.
+
+[dev-guide]: ../developers-guide/machine-setup.md
diff --git a/docs/unified-ticketing/license-softlink.md b/docs/unified-ticketing/license-softlink.md
new file mode 120000
index 0000000000000000000000000000000000000000..f0608a63ae16053f55e32ab4abf40e7a61f2dccb
--- /dev/null
+++ b/docs/unified-ticketing/license-softlink.md
@@ -0,0 +1 @@
+../../LICENSE.md
\ No newline at end of file
diff --git a/docs/unified-ticketing/usage.md b/docs/unified-ticketing/usage.md
new file mode 100644
index 0000000000000000000000000000000000000000..a7c834db5406e01ab3d7f6546d23dc49f39d6f1c
--- /dev/null
+++ b/docs/unified-ticketing/usage.md
@@ -0,0 +1,66 @@
+# Usage
+
+## Add as dependency in own project
+
+This library can be used as maven dependency in an own project.
+
+!!! attention
+ As it is not published to maven central,
+ but the GitLab integrated package registry,
+ you must configure an additional repository in your pom.
+
+__repository config:__
+```xml
+
+ unified-ticketing
+ https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/154/packages/maven
+
+```
+
+__dependency information:__
+```xml
+
+ de.hftstuttgart
+ unified-ticketing
+ 0.1.0
+
+```
+
+??? tip "example how your pom should look like"
+ ```xml
+
+
+
+
+
+ de.hftstuttgart
+ unified-ticketing
+ 0.1.0
+
+
+
+
+
+
+ gitlab-maven
+ https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/154/packages/maven
+
+
+
+
+ ```
+
+## Use in code
+
+There are two central classes: `TicketSystem` and `Ticket`.
+The majority of the library is written with the fluent-api design pattern.
+
+To begin, you'll need an instance of `TicketSystem`.
+This can be done, by calling the builder mechanism or pass a URI with all needed information.
+
+Using this `TicketSystem` object you can search for tickets in the connected space,
+change and save them or create new tickets.
+
+To get full details of the available API, please switch to the [API docs](../api/index.md).
+There you can find information and examples regarding the generic parts of the library,
+as-well as system specific information, e.g. how an URI instantiation string has to look like, etc.
diff --git a/mkdocs.yml b/mkdocs.yml
index 46a70d5b4f162be2bf11700d1c9b71f7b38b0d6e..e3df64ad89299ebcbbbb0dfdfc4e0ef76c128f24 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -1,42 +1,66 @@
-site_name: Unified Ticketing Doku
+site_name: Unified Ticketing Docs
-repo_name: 'Unified Ticketing Java Bibliothek'
-repo_url: 'https://transfer.hft-stuttgart.de/gitlab/9Lukas5/unified-ticketing'
-edit_uri: 'blob/master/docs/'
docs_dir: docs
+edit_uri: 'blob/master/docs/'
+repo_name: 'Code on Transfer Portal'
+repo_url: 'https://transfer.hft-stuttgart.de/gitlab/9Lukas5/unified-ticketing'
-copyright: 'Copyright © 2020 Hochschule für Technik Stuttgart'
+copyright: 'Copyright © 2020 University for Applied Sciences Stuttgart'
use_directory_urls: false
nav:
- Home:
- Index: 'index.md'
+ - Changelog: 'unified-ticketing/changelog-softlink.md'
+ - Usage: 'unified-ticketing/usage.md'
+ - Contributing: 'unified-ticketing/contributing.md'
+ - License: 'unified-ticketing/license-softlink.md'
+ - API:
+ - Index: 'api/index.md'
+ - Core:
+ - Logging: 'api/core/logging.md'
+ - Ticket: 'api/core/ticket.md'
+ - Ticketsystem: 'api/core/ticket-system.md'
+ - Exceptions: 'api/exceptions.md'
+ - Systems:
+ - GitLab:
+ - Ticket: 'api/systems/gitlab/ticket.md'
+ - Ticketsystem: 'api/systems/gitlab/ticket-system.md'
+ - Developers Guide:
+ - Machine Setup: 'developers-guide/machine-setup.md'
+ - Styleguide: 'developers-guide/styleguide.md'
+ - UML Diagram: 'developers-guide/uml.md'
+ - Workflow: 'developers-guide/workflow.md'
theme:
+ features:
+ - navigation.tabs
+ icon:
+ logo: material/book-open
+ language: 'en'
name: 'material'
palette:
- primary: 'white'
- accent: 'teal'
- language: 'en'
- feature:
- tabs: true
- logo:
- icon: library_books
+ accent: 'blue'
+ primary: 'red'
markdown_extensions:
-- admonition
-- codehilite:
- linenums: true
-- toc:
- permalink: True
-- footnotes
-- tables
-- plantuml_markdown:
- server: http://plantuml.com/plantuml
- format: svg
-- pymdownx.emoji:
- emoji_generator: !!python/name:pymdownx.emoji.to_svg
-- pymdownx.tasklist
-- pymdownx.details
-- pymdownx.superfences
+ - admonition
+ - attr_list
+ - footnotes
+ - markdown_del_ins
+ - plantuml_markdown:
+ format: svg
+ server: http://plantuml.com/plantuml
+ - pymdownx.details
+ - pymdownx.emoji:
+ emoji_index: !!python/name:materialx.emoji.twemoji
+ emoji_generator: !!python/name:materialx.emoji.to_svg
+ - pymdownx.highlight:
+ linenums: true
+ - pymdownx.superfences
+ - pymdownx.tabbed
+ - pymdownx.tasklist
+ - toc:
+ permalink: True
+ - tables
diff --git a/requirements.txt b/requirements.txt
index 916d0f154b4884ab7f867f308a5a54687261df49..c67bf3f3efbe9a08b2ba68f8800b1b483716c7f3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,8 @@
+certifi~=2020.11
+markdown_del_ins~=1.0
Markdown~=3.1
+mkdocs-material~=6.0
mkdocs~=1.0
-mkdocs-material~=4.0
-plantuml~=0.2
plantuml-markdown~=3.1
-pymdown-extensions~=6.2
-certifi~=2019.9
+plantuml~=0.2
+pymdown-extensions~=8.0