Compare commits
2 commits
50f80d3397
...
9d0efb2a68
Author | SHA1 | Date | |
---|---|---|---|
9d0efb2a68 | |||
a35d259fd8 |
10 changed files with 199 additions and 97 deletions
|
@ -29,6 +29,8 @@ public class Main {
|
|||
s.createContext("/", new RootView());
|
||||
s.createContext("/main", new StartView());
|
||||
s.createContext("/auth", new AuthView());
|
||||
s.createContext("/tree", new TreeView());
|
||||
s.createContext("/object", new ObjectView());
|
||||
s.setExecutor(null);
|
||||
s.start();
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -1,56 +1,42 @@
|
|||
package hsmw.jotto5.beleg.data;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* Basisklasse für ein beliebiges DataObject.
|
||||
*
|
||||
* Alle spezifischen Objekte (im Sinne dieser Anwendung) erben von dieser Klasse.
|
||||
* DataObjects haben eine UID. Diese wird im Model vergeben, und ist einmalig.
|
||||
* Vorgesehen ist die UID als Pfad-formatierter String mit "/" als Trennsymbol, um
|
||||
* DataObjects hierarchisch zu gliedern - der Inhalt ist aber eigentlich egal
|
||||
* (solange eindeutig).
|
||||
* <p>
|
||||
* Für alle DataObjects gilt, dass der Zugriff auf Methoden und Felder der Objekte
|
||||
* nicht definiert ist, solange sie nicht an ein Modell gebunden sind.
|
||||
* Das DataObject und alle Kindklassen sind für Klassen außerhalb des Data-Pakets vollständig mutable,
|
||||
* um das Bearbeiten über das Webinterface zu erlauben.
|
||||
*/
|
||||
public abstract class DataObject {
|
||||
|
||||
protected Model model; // DataObjects speichern eine Referenz auf das Modell zu dem sie gehören
|
||||
protected String uid; // einmalige UID des Objektes
|
||||
protected String displayName;
|
||||
/**
|
||||
* Annotation um über das Webinterface abrufbare Felder zu kennzeichnen.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface WebField {
|
||||
public String displayAs() default "";
|
||||
}
|
||||
|
||||
@WebField(displayAs = "Anzeigename")
|
||||
public final String displayName;
|
||||
|
||||
// Wird absichtlich nicht angezeigt, als Demonstration
|
||||
public final String uid;
|
||||
|
||||
/**
|
||||
* Konstruktor für manuelles Erzeugen.
|
||||
*
|
||||
* Wird nur von Kindklassen verwendet. Dient dazu, ein temporäres
|
||||
* DataObject ohne Model-Bindung zu erzeugen.
|
||||
* @param uid Die vorgegebene UID des Objektes (wird beim Binden an ein Model verwendet)
|
||||
* @param displayName Der Anzeigename des Objektes
|
||||
*/
|
||||
protected DataObject(String uid, String displayName) {
|
||||
this.model = null;
|
||||
this.uid = uid;
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Model.
|
||||
*
|
||||
* Nur aus dem Model zu verwenden!
|
||||
*/
|
||||
protected void setModel(Model m) {
|
||||
this.model = m;
|
||||
}
|
||||
|
||||
public Model getModel() {
|
||||
return this.model;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return this.displayName;
|
||||
}
|
||||
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,11 +15,4 @@ public class Group extends DataObject {
|
|||
super(uid, displayName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt das DataObject mit der gegebenen UID zu der Gruppe hinzu.
|
||||
*/
|
||||
public void addMember(String uid) {
|
||||
this.model.addRelation(this.uid, uid);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,53 +46,52 @@ public class Model {
|
|||
* Füllt das Model mit Beispieldaten.
|
||||
*/
|
||||
public void fillMockData() {
|
||||
Group g1, g2, g3;
|
||||
|
||||
// Studierende
|
||||
this.add(new Student("students/jotto5", "Jocelyn", "Otto"));
|
||||
this.add(new Student("students/vnachn", "Vorname", "Nachname"));
|
||||
this.add(new Student("students/alovel", "Ada", "Lovelace"));
|
||||
this.add(new Student("students/aturin", "Alan", "Turing"));
|
||||
this.add(new Student("students/dknuth", "Donald", "Knuth"));
|
||||
this.add(new Student("students/ltorva", "Linus", "Torvalds"));
|
||||
this.add(new Student("students/dritch", "Dennis", "Ritchie"));
|
||||
this.add(new Student("students/jotto5", "Jocelyn", "Otto", "0001"));
|
||||
this.add(new Student("students/vnachn", "Vorname", "Nachname", "0002"));
|
||||
this.add(new Student("students/alovel", "Ada", "Lovelace", "0003"));
|
||||
this.add(new Student("students/aturin", "Alan", "Turing", "0004"));
|
||||
this.add(new Student("students/dknuth", "Donald", "Knuth", "0005"));
|
||||
this.add(new Student("students/ltorva", "Linus", "Torvalds", "0006"));
|
||||
this.add(new Student("students/dritch", "Dennis", "Ritchie", "0007"));
|
||||
|
||||
// Gruppen
|
||||
g1 = new Group("groups/IF24wS2-B", "Softwareentwicklung WiSe 24/25 Seminargruppe 2");
|
||||
g2 = new Group("groups/admins", "Administrator:innen");
|
||||
g3 = new Group("groups/alumni", "Alumni");
|
||||
this.add(new Group("groups/IF24wS2-B", "Softwareentwicklung WiSe 24/25 Seminargruppe 2"));
|
||||
this.add(new Group("groups/admins", "Administrator:innen"));
|
||||
this.add(new Group("groups/alumni", "Alumni"));
|
||||
this.add(new Group("groups/leer", "Leere Gruppe"));
|
||||
this.add(g1);
|
||||
this.add(g2);
|
||||
this.add(g3);
|
||||
g1.addMember("students/jotto5");
|
||||
g2.addMember("students/vnachn");
|
||||
g2.addMember("students/ltorva");
|
||||
g3.addMember("students/alovel");
|
||||
g3.addMember("students/aturin");
|
||||
g3.addMember("students/ltorva");
|
||||
|
||||
this.addRelation("groups/if24ws2-b", "students/jotto5");
|
||||
this.addRelation("groups/admins", "students/vnachn");
|
||||
this.addRelation("groups/admins", "students/ltorva");
|
||||
this.addRelation("groups/alumni", "students/alovel");
|
||||
this.addRelation("groups/alumni", "students/aturin");
|
||||
this.addRelation("groups/alumni", "students/ltorva");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt ein neues DataObject hinzu, also bindet es an das Model.
|
||||
* Fügt ein neues DataObject hinzu.
|
||||
*/
|
||||
public void add(DataObject a) {
|
||||
// TODO: Auf doppelte UIDs überprüfen!
|
||||
this.objs.put(a.uid, a);
|
||||
a.setModel(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Folgende Funktionen sind nur durch die DataObject-Objekte
|
||||
* zu verwenden, und sind daher protected.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fügt eine neue Objekt-Beziehung hinzu.
|
||||
*/
|
||||
protected void addRelation(String a, String b) {
|
||||
public void addRelation(String a, String b) {
|
||||
// TODO: Prüfen ob die Objekte existieren!
|
||||
this.relations.put(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt das DataObject mit der angegebenen UID zurück
|
||||
* oder null wenn es keines gibt.
|
||||
*/
|
||||
public DataObject get(String path) {
|
||||
if ( !objs.containsKey(path) ) return null;
|
||||
return objs.get(path);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
28
src/data/Person.java
Normal file
28
src/data/Person.java
Normal file
|
@ -0,0 +1,28 @@
|
|||
package hsmw.jotto5.beleg.data;
|
||||
|
||||
/**
|
||||
* Verkapselt einige Daten die über alle Arten von Personen wichtig sind.
|
||||
*/
|
||||
public abstract class Person extends DataObject {
|
||||
|
||||
@WebField(displayAs = "Vorname")
|
||||
public final String name;
|
||||
|
||||
@WebField(displayAs = "Nachname")
|
||||
public final String lastName;
|
||||
|
||||
/**
|
||||
* Konstruktor.
|
||||
*
|
||||
* Der displayName wird aus Vor- und Nachname zusammengesetzt.
|
||||
* @param uid Die zu vergebende UID
|
||||
* @param name Der Vorname
|
||||
* @param lastName Der Nachname
|
||||
*/
|
||||
public Person(String uid, String name, String lastName) {
|
||||
super(uid, lastName + ", " + name);
|
||||
this.name = name;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
}
|
|
@ -3,40 +3,23 @@ package hsmw.jotto5.beleg.data;
|
|||
/**
|
||||
* Beschreibt eine studierende Person.
|
||||
*/
|
||||
public class Student extends DataObject {
|
||||
public class Student extends Person {
|
||||
|
||||
private String name;
|
||||
private String lastName;
|
||||
@WebField(displayAs = "Matrikelnummer")
|
||||
public String studentNumber;
|
||||
|
||||
/**
|
||||
* Konstruktor zum manuellen Erzeugen.
|
||||
*
|
||||
* Der displayName wird aus Vor- und Nachname zusammengesetzt. Beim Ändern der
|
||||
* Namensattribute wird die UID NICHT neu vergeben!
|
||||
* Siehe auch Konstruktor der Person-Klasse.
|
||||
* @param uid Die zu vergebende UID
|
||||
* @param name Der Vorname
|
||||
* @param lastName Der Nachname
|
||||
* @param number Die Matrikelnummer
|
||||
*/
|
||||
public Student(String uid, String name, String lastName) {
|
||||
super(uid, lastName + ", " + name);
|
||||
this.name = name;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return this.lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
public Student(String uid, String name, String lastName, String studentNumber) {
|
||||
super(uid, name, lastName);
|
||||
this.studentNumber = studentNumber;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ package hsmw.jotto5.beleg.views;
|
|||
*/
|
||||
public class Defaults {
|
||||
|
||||
public static final String HTMLHEADER = "<!DOCTYPE html><html><title>Beleg SoSe 2025</title><link rel=stylesheet href=\"/style.css\"><head></head><body><main>";
|
||||
public static final String HTMLFOOTER = "</main></body></html>";
|
||||
public static final String HTMLHEADER = "<!DOCTYPE html><html><title>Beleg SoSe 2025</title><link rel=stylesheet href=\"/style.css\"><head></head><body><div id=\"content\"><main><hr>";
|
||||
public static final String HTMLFOOTER = "</main><footer><i><center>Hier könnte ihr Text stehen!</center></i></footer></div></body></html>";
|
||||
|
||||
}
|
||||
|
|
57
src/views/ObjectView.java
Normal file
57
src/views/ObjectView.java
Normal file
|
@ -0,0 +1,57 @@
|
|||
package hsmw.jotto5.beleg.views;
|
||||
|
||||
import hsmw.jotto5.beleg.data.DataObject;
|
||||
import hsmw.jotto5.beleg.data.Model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import com.sun.net.httpserver.*;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
public class ObjectView implements HttpHandler {
|
||||
|
||||
public void handle(HttpExchange t) throws IOException {
|
||||
String response;
|
||||
String objectPath;
|
||||
OutputStream os;
|
||||
Model m = Model.getModel();
|
||||
DataObject obj = null;
|
||||
|
||||
// Das angefragte Objekt finden
|
||||
objectPath = t.getRequestURI().toString();
|
||||
if (objectPath.length() >= 9) {
|
||||
objectPath = objectPath.substring(8);
|
||||
obj = m.get(objectPath);
|
||||
}
|
||||
|
||||
if ( obj == null ) return; // TODO: 404 oder 500 zurückgeben!
|
||||
|
||||
// Die Tabelle ausgeben
|
||||
response = Defaults.HTMLHEADER + "<h1>Beleg - Objektansicht</h1>";
|
||||
response += "<table class=\"objecttable\">";
|
||||
try {
|
||||
for (Field f : obj.getClass().getFields()) {
|
||||
if (f.isAnnotationPresent(DataObject.WebField.class)) {
|
||||
// Das Feld hat die "WebField"-Annotation, ist also anzuzeigen
|
||||
response += "<tr><td>" + f.getAnnotation(DataObject.WebField.class).displayAs() + "</td>";
|
||||
// Feld anzeigen
|
||||
response += "<td><input type=\"text\" value=\"" + f.get(obj).toString() + "\" disabled /></td></tr>";
|
||||
}
|
||||
}
|
||||
} catch(IllegalAccessException e) {
|
||||
// hier sollten wir niemals her kommen
|
||||
// TODO: 500 werfen
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
response += "</table><button>Speichern</button>";
|
||||
|
||||
response += Defaults.HTMLFOOTER;
|
||||
os = t.getResponseBody();
|
||||
|
||||
t.sendResponseHeaders(200, response.length());
|
||||
os.write(response.getBytes());
|
||||
os.close();
|
||||
}
|
||||
|
||||
}
|
21
src/views/TreeView.java
Normal file
21
src/views/TreeView.java
Normal file
|
@ -0,0 +1,21 @@
|
|||
package hsmw.jotto5.beleg.views;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import com.sun.net.httpserver.*;
|
||||
|
||||
public class TreeView implements HttpHandler {
|
||||
|
||||
public void handle(HttpExchange t) throws IOException {
|
||||
String response;
|
||||
OutputStream os;
|
||||
|
||||
response = Defaults.HTMLHEADER + "<h1>Beleg - Objektübersicht</h1>" + Defaults.HTMLFOOTER;
|
||||
os = t.getResponseBody();
|
||||
|
||||
t.sendResponseHeaders(200, response.length());
|
||||
os.write(response.getBytes());
|
||||
os.close();
|
||||
}
|
||||
|
||||
}
|
|
@ -2,7 +2,40 @@
|
|||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #ccc;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
main {
|
||||
max-width: 600px;
|
||||
background-color: #fff;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
footer {
|
||||
background-color: #eee;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
padding-bottom: 75px;
|
||||
}
|
||||
|
||||
#content {
|
||||
max-width: 900px;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.objecttable {
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.objecttable td {
|
||||
border-bottom: black 1px solid;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.objecttable td input {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue