package documentDataStructures; public class BasisDokument { // URL des Dokuments aufgeschluesselt public String serverName = ""; public String pfadName = ""; public String dateiName = ""; // Zugriffsmethode auf das Dokument, z.B. FTP... public String zugriffsMethode; // Nummer, falls Fehler mit Dokument aufgetreten public int fehlernummer = 0; // Name des Betreuers, falls vorhanden public String betreuer; // ermittelt den Namen des Dokuments public String name() { // existiert ein Dateiname if (! dateiName.equals("")) return dateiName; // oder nur ein Pfadname else if (! pfadName.equals("")) return pfadName; // oder vielleicht nur eine Serverbezeichnung else return serverName; } //ermittelt die URL des Dokuments public String url() { return zugriffsMethode + "://" + serverName + pfadName + dateiName; } //liefert ausfuehrliche Fehlerbeschreibung public String fehlerText() { String fehler = ""; switch (fehlernummer) { case 400: fehler = "Falsche URL Syntax"; break; case 401: fehler = "keine Zugriffsberechtigung"; break; case 402: fehler = "Payment Required"; break; case 403: fehler = "Zugriff verweigert"; break; case 404: fehler = "Dokument nicht gefunden"; break; case 405: fehler = "falsche Zugriffsmethode"; break; case 406: fehler = "Accept Klausel falsch"; break; case 407: fehler = "Password benoetigt"; break; case 408: fehler = "Timeout"; break; case 409: fehler = "beim abspeichern"; break; case 410: fehler = "Dokument wurde geloescht"; break; case 411: fehler = "Content Length falsch"; break; case 412: fehler = "Unless erfuellt"; break; case 500: fehler = "Serverfehler"; break; case 501: fehler = "Zugriffsmethode nicht unterstuetzt"; break; case 502: fehler = "Proxyfehler"; break; case 503: fehler = "Server nicht erreichbar"; break; case 504: fehler = "Proxy Timeout"; break; // LinkTest interne Fehler case 600: fehler = "Socket nicht erstellbar"; break; case 601: fehler = "Rechnerverbindung unmoeglich"; break; case 602: fehler = "Domain nicht erreichbar"; break; case 603: fehler = "Leere Seite"; break; } return fehler; } } package documentDataStructures; import documentDataStructures.BasisDokument; import java.util.Vector; public class VollDokument extends BasisDokument { public String name; public String[] vaterName; public Vector sohn = new Vector(1,1); public Vector vater = new Vector(1,1); } package documentDataStructures; import documentDataStructures.BasisDokument; import java.awt.Point; public class Dokument extends BasisDokument { // Liste der Indizes von direkten Vorfahren und Nachfolgern public int[] vater; public int[] sohn; // Ort, an dem das Dokument dargestellt wird Point Darstellungsort = new Point(0,0); // Kontrollvariable zur Erkennung erledigter Dokumente boolean visited = false; // setzen der Kontrollvariable public void setVisited() { this.visited = true; } // loeschen der Kontrollvariable public void clearVisited() { this.visited = false; } // abfragen der Kontrollvariable public boolean isVisited() { return this.visited; } // setzen der Koordinaten public void setzeKoordinaten(Point Koordinaten) { this.Darstellungsort.x = Koordinaten.x; this.Darstellungsort.y = Koordinaten.y; } // abfragen der Koordinaten public Point liesKoordinaten() { Point Koordinaten = new Point(this.Darstellungsort.x,this.Darstellungsort.y); return Koordinaten; } // kopieren eines Dokuments public Dokument copy() { Dokument Kopie = new Dokument(); Kopie.zugriffsMethode = new String(this.zugriffsMethode); Kopie.dateiName = new String(this.dateiName); Kopie.pfadName = new String(this.pfadName); Kopie.serverName = new String(this.serverName); Kopie.sohn = new int[this.sohn.length]; for (int i = 0; i < this.sohn.length; i++) { Kopie.sohn[i] = this.sohn[i]; } Kopie.vater = new int[this.vater.length]; for (int i = 0; i < this.vater.length; i++) { Kopie.vater[i] = this.vater[i]; } if (this.betreuer != null) Kopie.betreuer = new String(this.betreuer); Kopie.fehlernummer = this.fehlernummer; return Kopie; } } package documentDataStructures; import java.awt.Point; import java.util.Vector; import java.io.*; import documentDataStructures.*; public class LinkStructure { //Variablen fuer den Zugriff auf die Daten // Dies ist die Liste aller Dokumente public Dokument[] dokumentListe; // Index der Basis URL public int startDokument; // Variablen fuer die Darstellung // benoetigte Flaeche public int maxRadius = 0; // erweiterung des Radius fuer jeden Kreis final int addRadius = 90; // maximaler Winkel fuer die Soehne final double MaxWinkel = (9*Math.PI)/18; // Konstanten fuer die Bearbeitung der Log Dateien // Kennzeichen eines Datensatzes im File final String Datensatzkennzeichen = "Intern --:"; // Feldseparator im Datensatz final String feldSeparator = ";"; // Kennzeichen fuer das Ende des Vaternamens final String endeDesVaternamens = ":"; // Kennzeichen fuer einen weiterne Vaternamen final String naechsterVater = "|"; // Namenserweiterungen fuer die LOG Dateine final String erledigtExtension = ".ERL.LOG"; final String ausserhalbExtension = ".NEU.LOG"; final String fehlerExtension = ".ERR.LOG"; // Zur Berechnung benoetigte Klassenglobale Variablen // zum zwischenspeichern der eingelesenen Dokumente Vector gefundeneDokumente = new Vector(50,50); //Zaehler zum Datei einlesen und ermitteln einer neuen Struktur int letzterEintrag = 0; // Konstruktor bei Aufruf durch Zoom public LinkStructure(LinkStructure ausgangsstruktur, int startIndex) { // rekursives ermitteln den neuen Struktur dokumentListe = getLinkStructure(new int[ausgangsstruktur.dokumentListe.length], ausgangsstruktur, startIndex); // berechnen der Koordinaten in der Liste zur Darstellung Display(); } // Konstruktor bei erstmaligem Aufruf public LinkStructure(String Dateiname, int selectLogFiles) { // alle angeforderten Logfiles einlesen dateiEinlesen(Dateiname+erledigtExtension); switch (selectLogFiles) { case 0: dateiEinlesen(Dateiname+ausserhalbExtension); dateiEinlesen(Dateiname+fehlerExtension); break; case 1: dateiEinlesen(Dateiname+ausserhalbExtension); break; case 2: dateiEinlesen(Dateiname+fehlerExtension); break; } // erzeugung des Link - "Graphen" und speichern in dokumentListe dokumentListe = getLinkStructure(gefundeneDokumente); // berechnen der Koordinaten in der Liste zur Darstellung Display(); } void dateiEinlesen(String Dateiname) { String gelesen = ""; String Datensatz; // Einlesen der Datei try { try { // oeffnen des Eingabestromes aus der Datei mit den erledigten Dokumenten DataInputStream Datei = new DataInputStream(new FileInputStream(Dateiname)); //System.out.println("Bearbeitung des Files: "+Dateiname); // solange noch Zeichen in der Datei vorhanden while (gelesen != null) { //einlesen einer Zeile der aktuellen Datei gelesen = Datei.readLine(); if (gelesen == null) break; // test ob die Zeile einen Datensatz enthaelt if (gelesen.startsWith(Datensatzkennzeichen)) { // wenn ja entsprechenden Datensatz uebernehmen Datensatz = gelesen.substring(Datensatzkennzeichen.length() + 1); gefundeneDokumente.addElement(getEntry(Datensatz)); //ist Dokument eine Mail adresse if (((VollDokument)gefundeneDokumente.elementAt( letzterEintrag)).zugriffsMethode.equals("MAILTO")) { // dann verwerfen gefundeneDokumente.removeElementAt(letzterEintrag); } // ansonsten Anzahl erhoehen else letzterEintrag++; } } // nach Beendigung Datei schliessen Datei.close(); } catch (FileNotFoundException e) { // Fehlerbehandlung falls Datei nicht existiert System.out.println("Achtung: Datei "+Dateiname+" nicht gefunden"); } } catch (IOException e) { // Fehlerbehandlung falls Datei nicht gelesen werden konnte System.out.println("Fehler: Probleme beim auslesen der Datei aufgetreten"); } } // diese Methode loescht alle visited Eintraege public void clearVisited() { try { for(int i = 0; i < dokumentListe.length; i++) { dokumentListe[i].clearVisited(); } } // bei falscher benutzung tritt ein Fehler auf catch (NullPointerException e) { System.out.println("clearVisited() erst nach Initialisierung von dokumentListe benutzen"); } } // diese Methode wandelt einen Datensatzstring in ein Volldokument um VollDokument getEntry(String input) { // Variable zur aufnahme der Information VollDokument aktuellesDokument = new VollDokument(); // Hilfsvariable zum zerlegen des inputstrings String[] eintragsliste = new String[4]; // Hilfsvariable zum zerlegen der Vaeterinformation Vector Vaeter = new Vector(1,1); // Indizes zum zerlegen des inputstrings int lastIndex = 0; int nextIndex; // zerlegen des Inputstrings in einzelne Eintraege for(int i = 0; i < 4; i++) { // ermittle Index des naechsten Separators nextIndex = input.indexOf(feldSeparator,lastIndex); // Index gueltig ? if (nextIndex == -1) { // wenn nein, Schleife mit Fehlermeldung beenden System.out.println("Datensatz im File fehlerhaft"); i = 5; } // sonst Feldeintrag uebernehmen else { try { eintragsliste[i] = input.substring(lastIndex,nextIndex); // und naechsten Startindex weiterschalten lastIndex = nextIndex + 1; } // dieser Fehler sollte nie auftreten, // muss aber syntaktisch abgefangen werden catch(StringIndexOutOfBoundsException e) { System.out.println("Datensatz im File fehlerhaft"); i = 5; } } } // aktuelles Dokument mit ermittelten Werten belegen aktuellesDokument.name = eintragsliste[0]; aktuellesDokument.zugriffsMethode = eintragsliste[1]; // eintrag fuer Fehler oder Betreuer try { if (! eintragsliste[3].equals("")) { // Fehlernummer abspeichern aktuellesDokument.fehlernummer = Integer.parseInt(eintragsliste[3]); } } catch (NumberFormatException e) { //wenn es keine Fehlernummer war, enthaelt der Eintrag den Betreuer aktuellesDokument.betreuer = eintragsliste[3]; // und das Dokument ist fehlerfrei aktuellesDokument.fehlernummer = 0; } // ermittlung der Vaeter try { // solange noch Vaeter vorhanden while (eintragsliste[2] != null) { // gibt es einen Vater ? nextIndex = eintragsliste[2].indexOf(endeDesVaternamens); if (nextIndex == -1) { // wenn nein, Schleife mit Fehlermeldung beenden System.out.println("Datensatz zu " +aktuellesDokument.name +" im File fehlerhaft"); eintragsliste[2] = null; } // sonst den Namen des Vaters bestimmen else Vaeter.addElement(eintragsliste[2].substring(0,nextIndex)); // folgt ein weiterer Vater ? nextIndex = eintragsliste[2].indexOf(naechsterVater); if (nextIndex != -1) { // dann eintragsliste[2] um bisherigen Vater verkuerzen eintragsliste[2] = eintragsliste[2].substring(nextIndex + 1); } // sonst Schleife beenden else eintragsliste[2] = null; } } catch (StringIndexOutOfBoundsException e) { // dieser Fehler sollte auch nie vorkommen System.out.println("Datensatz zu "+aktuellesDokument.name +" im File fehlerhaft"); } // gefundene Vaeter in aktuelles Dokument eintragen aktuellesDokument.vaterName = new String[Vaeter.size()]; Vaeter.copyInto(aktuellesDokument.vaterName); // ermitteltes Ergebnis zurueckgeben return aktuellesDokument; } //erzeugt aus einer vorgegebenen Liste eine neue beginnend mit startIndex Dokument[] getLinkStructure(int[] neueNamen, LinkStructure alteStruktur, int startIndex) { Vector neueStruktur = new Vector(50,50); Dokument[] erzeugteListe; // markieren aller Indizes als noch nicht in neuerStruktur enthalten for (int i = 0; i < neueNamen.length; i++) { neueNamen[i] = -1; } // markieren aller Dokumente als Unbesucht alteStruktur.clearVisited(); // erzeuge rekursiv die Unterstruktur ausgehend von startIndex createSubtree(neueNamen, neueStruktur, alteStruktur, startIndex); // uebernahme der Struktur in Rueckgabevariable erzeugteListe = new Dokument[neueStruktur.size()]; neueStruktur.copyInto(erzeugteListe); // berichtigen der Vater/Sohn Indizes for (int i = 0; i < erzeugteListe.length; i ++) { for (int j = 0; j < erzeugteListe[i].sohn.length; j++) { // jeden Sohnindex mit neuer Nummer versehen erzeugteListe[i].sohn[j] = neueNamen[erzeugteListe[i].sohn[j]]; } for (int j = 0; j < erzeugteListe[i].vater.length; j++) { // jeden Vaterindex mit neuer Nummer versehen achte auf undef. Vaeter if (erzeugteListe[i].vater[j] != -1) { erzeugteListe[i].vater[j] = neueNamen[erzeugteListe[i].vater[j]]; } } } // Uebertragung begann mit erstem Dokument startDokument = 0; // bei diesem sind die Vaeter ueberfluessig erzeugteListe[startDokument].vater = new int[0]; return erzeugteListe; } // rekursives erzeugen einer Zoomstruktur void createSubtree(int[] neueNamen, Vector neueStruktur, LinkStructure alteStruktur, int index) { // Dokument als besucht markieren alteStruktur.dokumentListe[index].setVisited(); // Dokument in die neue Struktur kopieren neueStruktur.addElement(alteStruktur.dokumentListe[index].copy()); // index des Dokuments in der neuen Struktrur speichern neueNamen[index] = letzterEintrag++; // alle unbesuchten Soehne rekursiv abklappern for (int i = 0; i < alteStruktur.dokumentListe[index].sohn.length; i ++) { if (! alteStruktur.dokumentListe[ alteStruktur.dokumentListe[index].sohn[i]].isVisited()) { createSubtree(neueNamen, neueStruktur, alteStruktur, alteStruktur.dokumentListe[index].sohn[i]); } } } //erzeugt aus den gefundenen Dokumenten die gesamtListe Dokument[] getLinkStructure(Vector gefundeneDokumente) { int[] hilfsliste; // instanziieren der Liste fuer die bearbeiteten Dokumente Dokument[] bearbeiteteDokumente = new Dokument[gefundeneDokumente.size()]; // uebernahme aller Variablen for(int i = 0; i < gefundeneDokumente.size(); i++) { // neuer Eintrag bearbeiteteDokumente[i] = new Dokument(); // Aufspaltung der URL String name = ((VollDokument)gefundeneDokumente.elementAt(i)).name; try { bearbeiteteDokumente[i].serverName = name.substring(0,name.indexOf("/")+1); bearbeiteteDokumente[i].pfadName = name.substring(name.indexOf("/")+1,name.lastIndexOf("/")+1); bearbeiteteDokumente[i].dateiName = name.substring(name.lastIndexOf("/")+1); } catch (StringIndexOutOfBoundsException e) { // ist kein Fehler, sondern Dateiname fehlt oder URL ist Server } bearbeiteteDokumente[i].zugriffsMethode = ((VollDokument)gefundeneDokumente.elementAt(i)).zugriffsMethode; bearbeiteteDokumente[i].betreuer = ((VollDokument)gefundeneDokumente.elementAt(i)).betreuer; bearbeiteteDokumente[i].fehlernummer = ((VollDokument)gefundeneDokumente.elementAt(i)).fehlernummer; bearbeiteteDokumente[i].sohn = new int[0]; bearbeiteteDokumente[i].vater = new int[0]; // wenn TOP als Vatereintrag steht, ist dies das StartDokument if (((VollDokument)gefundeneDokumente.elementAt(i)).vaterName[0]. equals("TOP")) { startDokument = i; //System.out.println("Start bei: "+startDokument); } } // erzeugen der logischen Struktur Vater - Sohn // fuer jedes gefundene Dokument for(int i = 0; i < gefundeneDokumente.size(); i++) { // fuer jeden Vater dieses Dokuments for(int j = 0; j < ((VollDokument)gefundeneDokumente.elementAt(i)).vaterName.length; j++) { // fuer alle gefundenen Dokumente for(int k = 0; k < gefundeneDokumente.size(); k++) { // welches Dokument ist der Vater if (((VollDokument)gefundeneDokumente.elementAt(i)).vaterName[j]. equals(((VollDokument)gefundeneDokumente.elementAt(k)).name)) { // Beim Sohn k-tes Dokument als Vater eintragen hilfsliste = bearbeiteteDokumente[i].vater; bearbeiteteDokumente[i].vater = new int[hilfsliste.length +1]; for(int l = 0; l < hilfsliste.length; l++) { bearbeiteteDokumente[i].vater[l] = hilfsliste[l]; } bearbeiteteDokumente[i].vater[hilfsliste.length] = k; // Beim Vater i-tes Dokument als Sohn eintragen hilfsliste = bearbeiteteDokumente[k].sohn; bearbeiteteDokumente[k].sohn = new int[hilfsliste.length +1]; for(int l = 0; l < hilfsliste.length; l++) { bearbeiteteDokumente[k].sohn[l] = hilfsliste[l]; } bearbeiteteDokumente[k].sohn[hilfsliste.length] = i; } } } } // Rueckgabe der kompletten Liste return bearbeiteteDokumente; } void Display() { // Variable zur verschiebung der Koordinaten Point Koo; // jedes Dokument als unbesucht markieren clearVisited(); //berechnen der Koordinaten aller Dokumente // zuerst das Startdokument dokumentListe[startDokument].setzeKoordinaten(new Point(0,0)); dokumentListe[startDokument].setVisited(); // dann rekursive Berechnung der restlichen Struktur int kill = berechnePosition(0, 2*Math.PI, startDokument, addRadius); //Berechnen der endgueltigen Koordinaten int sizeHaelfteFlaeche = maxRadius; for (int i = 0; i < dokumentListe.length; i++) { Koo = new Point(0,0); Koo = dokumentListe[i].liesKoordinaten(); Koo.x += sizeHaelfteFlaeche; Koo.y += sizeHaelfteFlaeche; dokumentListe[i].setzeKoordinaten(Koo); } } int berechnePosition(double from, double to, int dokumentNr, int radius) { int anzahlSoehne; double sektor; double winkel; boolean[] hierZuBesuchen; //Maximalen Wert fuer Radius feststellen if (maxRadius < radius) maxRadius = radius; //Anzahl und Liste der noch nicht berechneten Soehne ermitteln // Anzahl der Soehne feststellen anzahlSoehne = dokumentListe[dokumentNr].sohn.length; // und Liste entsprechender Groesse erzeugen hierZuBesuchen = new boolean[anzahlSoehne]; //fuer alle Soehne des aktuellen Dokuments for (int i = 0; i < dokumentListe[dokumentNr].sohn.length; i++) { // fuer jeden bereits dargestellten Sohn ein Sektor weniger if (dokumentListe[dokumentListe[dokumentNr].sohn[i]].isVisited()) { anzahlSoehne = --anzahlSoehne; // und er muss nicht von dieser Inkarnation aus berechnet werden hierZuBesuchen[i] = false; } else { // ansonsten schon hierZuBesuchen[i] = true; } } //keine unbesuchten Soehne, keine Arbeit mehr :-) if (anzahlSoehne == 0) return anzahlSoehne; //Winkelbereich, der jedem Sohn zur Darstellung zur Verfuegung steht sektor = (to - from)/anzahlSoehne; //Ausrechnen der Koordinaten fuer alle noch nicht berechneten Soehne // winkel initialisieren winkel = (from + (sektor/2)); for (int i = 0; i < dokumentListe[dokumentNr].sohn.length; i++) { // wenn i-ter Sohn noch zu berechnen if (hierZuBesuchen[i]) { // Koordinaten des i-ten Sohnes berechnen dokumentListe[dokumentListe[dokumentNr].sohn[i]].setzeKoordinaten( new Point((int)(radius * Math.cos(winkel)), (int)(radius * Math.sin(winkel)))); // Berechnungswinkel weiterschalten winkel = winkel + sektor; // und diesen Sohn als besucht markieren dokumentListe[dokumentListe[dokumentNr].sohn[i]].setVisited(); } } //Erweitern der Darstellungsflaeche durch erhoehen des radius' radius += addRadius; //rekursiver Aufruf von berechnePosition fuer alle Soehne double sektorende = sektor; for (int i = 0; i < dokumentListe[dokumentNr].sohn.length; i++) { // wenn i-ter Sohn noch unbesucht if (hierZuBesuchen[i]) { // rekursiver Aufruf mit diesem Sohn int Neffen = berechnePosition(from, from + sektorende, dokumentListe[dokumentNr].sohn[i], radius); // Darstellungsbereich nur weiterschalten, wenn Vorgaenger Soehne hatte if (Neffen != 0) { from = from + sektorende; sektorende = sektor; } else sektorende = sektorende + sektor; if (sektorende > MaxWinkel) { from = from + (sektorende - MaxWinkel); sektorende = MaxWinkel; } } } return anzahlSoehne; } }