AtNotes Übersicht Willkommen Gast. Bitte einloggen oder registrieren.
04.08.20 - 10:06:34
Übersicht Hilfe Regeln Glossar Suche Einloggen Registrieren
News:
Schnellsuche:
+  Das Notes Forum
|-+  Lotus Notes / Domino Sonstiges
| |-+  Java und .NET mit Notes/Domino (Moderatoren: Axel, m3)
| | |-+  Mock-Framework für JUnit Tests
« vorheriges nächstes »
Seiten: [1] 2 Nach unten Drucken
Autor Thema: Mock-Framework für JUnit Tests  (Gelesen 25746 mal)
flaite
Gold Platin u.s.w. member:)
*****
Offline Offline

Beiträge: 2966


WWW
« am: 15.10.07 - 18:21:20 »

Hi,

ich arbeite an der entgültigen Strategie zum Junit-Testing von Notes-Agents.

Was ich will:
1. Notes soll für Junit Tests von Notes Agenten nicht gestartet werden.
2. Junit Tests sollen relativ einfach geschrieben werden können.

Denke nun, dass Stubbing und nicht die verschiedenen Mock-Frameworks (wie JMock1 ) einfacher und flexibler ist.
Was verstehe ich unter Stubs?
Einfach Klassen, die die Notes Interfaces implementieren. Schliesslich läuft der gesamte öffentliche Zugriff auf die Notes Api ja über Interfaces.
Stubs für Notes Java Klassen lassen sich mit Eclipse sehr einfach erstellen:
Beispiel: Klasse DocumentStub erzeugen, die einfach das Interface lotus.domino.Document implementiert. Für alle Methoden des Interfaces lotus.domino.Document werden von Eclipse schon Methodenrümpfe erstellt. Die kann ich dann möglichst wiederverwendbar erweitern.
Kann man z.B. für getItemValue, getItemValueString und getItemValueInteger so implementieren:
Code:

public Vector getItemValue(String name) throws NotesException {
Vector ret = new Vector();
Object val = itemValueMap.get(name);
if (val != null) {
ret.add(val);
}
return ret;


}

public int getItemValueInteger(String name) throws NotesException {
Vector vec = getItemValue(name);
if (vec.size() == 0) return 0;
Object firstEntry = vec.get(0);
if (firstEntry instanceof Number) {
if ((firstEntry instanceof Double)|| (firstEntry instanceof Float)) {
return ((int) Math.round(((Double)firstEntry).doubleValue()));
} else {
return (int) ((Long) firstEntry).intValue();
}
} else {
return 0;
}
}

public String getItemValueString(String name) throws NotesException {
Vector vec = getItemValue(name);
if (vec.size() == 0) return null;
Object firstEntry = vec.get(0);
if (firstEntry instanceof String) {
return (String) firstEntry;
} else {
return null;
}
}
Das liesse sich dann für alle Projekte  benutzen.
Die Stub Objekte besitzen eine private HashMap itemValueMap, in der die Feldwerte drinstehen:
Code:
private Map itemValueMap = new HashMap();

public void addItemValue(String name, Object value) {
itemValueMap.put(name, value);
}
Diese itemValueMap kann über addItemValue von aussen gefüllt  werden.
Solche bei Bedarf immer mehr zu verfeinernden allgemein-verwendbare Notes Stub Objekte für Junit-Testing tu ich in ein eigenes Eclipse Projekte, dass ich dann problemlos in spezielle Projekte einbinden kann.

Oder ist das Quatsch? Ich halte die Idee zur Zeit für so großartig, dass ich mich wundere, warum kein anderer darauf gekommen ist.

Gruß Axel
« Letzte Änderung: 24.10.07 - 08:41:13 von Axel Janssen » Gespeichert

Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile
MadMetzger
Gold Platin u.s.w. member:)
*****
Offline Offline

Geschlecht: Männlich
Beiträge: 1052


f.k.a. Alexis Pyromanis


« Antworten #1 am: 15.10.07 - 19:20:22 »

Hm... Nach meinem Verständnis von Mocks und Stubs, könnte man deine Klasse auch als Mock, heißt übersetzt Attrappe, bezeichnen. Auf Basis der Übersetzung passt das, was du baust sehr gut dazu, so ich finde. Ein Stub (dt. Stummel) ist ja auch nicht viel anders, nur hätte ich gedacht, dass da zT konstante Werte zurückgegeben werden. An sich finde ich die Idee aber gut, vor allen Dingen kann man damit leichter Unit-Tests durchführen und teilweise auch testgetrieben entwickeln. Wenn ich diese Klasse sehe, fällt mir noch ein, dass man ja den Mock eigentlich auch noch testen muss, was du aber bestimmt auch tust.

Dabei kommt mir aber noch eine weitere Idee: Kann man das nicht auch für andere Notes-Objekte machen und das als "Test-Framework" zusammenstellen?
Gespeichert

flaite
Gold Platin u.s.w. member:)
*****
Offline Offline

Beiträge: 2966


WWW
« Antworten #2 am: 16.10.07 - 10:06:35 »

Du hast Recht.
Ich benutze auf jeden Fall nicht Mock-Tools wie EasyMock und JMock1 (JMock2 ist nur für Java5). Das verleitete mich zu falschen Begriffen. Das ist mehr eine Art eigenes Notes-Mock-Objekte Package. 
Es ist ein bischen wie Spring-mock.jar (das dort für Integration-Testing verwendet wird).
http://static.springframework.org/spring/docs/1.2.x/reference/testing.html#integration-testing
Notes-Mock wäre mehr für Unit-Testing. Sobald eine einzelne Klasse Abhängigkeiten zu lotus.domino.* Klassen hat, benötigt man Mocks (oder Stubs), um das zu testen, ohne mit Notes selbst zu kommunizieren.
Notes mocken funktioniert ziemlich gut, weil die ganze apis aus Interfaces besteht.
Wobei ...Für bestimmte Notes-Methoden wirds vermutlich ziemlich schwierig dort geeignete Mock-Klassen selbst zu schreiben (z.B. RichText). Die Brot-und-Butter-Funktionalität (wichtigsten Funktionen von Database, View, DocumentCollection, Document, Item) lassen sich aber vermutlich mit vertretbaren Aufwand mocken.
Die Notes-Designer Funktionalität, java-Source Files über den Edit-Projekt Button direkt von dem entsprechenden Verzeichnis im Eclipse Projekt zu importieren funktioniert für Java-SkriptBibliotheken (nicht zu verwechseln mit JavaScript-ScriptBibliotheken) und Java-Agenten sehr gut.
Mit funktionierenden Notes-Mock-Packet lassen sich Notes-Agenten (und Notes Java-ScriptBibliotheken) sehr schnell testgetrieben oder/und unit-testgestützt entwickeln.
Ich könnte den Import von der Platte-wo-Eclipse-das-hinlegt in den Notes-Agenten oder die Notes Java-ScriptBibliothek noch per Ant-Script automatisieren. Oder Domiclipse verwenden, das aber nicht weiterentwickelt wird.
Ein falscher Weg ist imho, dass mehrere  Entwickler mit Domiclipse den GLEICHEN Notes-Java-Agenten oder NOTES-Java-Scriptbiothek entwickeln zu lassen. Dann eher schon erst testgestützt/testgetrieben entwickeln, den Code in einem Versionierungssystem halten und zu einem geeigneten Zeitpunkt dann die neuen Source Files dann auf den eigentlichen Testserver spielen. Die Prozesse könnte man natürlich noch mit sowas wie CruiseControl automatisieren.
Ich schau mal wie weit ich komme.
Einen Markt für Notes-Agenten gibts schon. Wenn z.B. Dateien als zips in eine Mail-In-DB kommen und dann weiterverarbeitet werden sollen, Zugriff über HTTP auf andere Server, aus einem gif Informationen herausholen, wie breit und hoch die ist, etc.

Gruß Axel
Gespeichert

Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile
MadMetzger
Gold Platin u.s.w. member:)
*****
Offline Offline

Geschlecht: Männlich
Beiträge: 1052


f.k.a. Alexis Pyromanis


« Antworten #3 am: 17.10.07 - 07:49:43 »

Was die technische Umsetzung anbelangt in Bezug auf "Koppelung" von externen Java-IDEs wie Eclipse mit dem Designer habe ich mir noch nicht so wirklich Gedanken gemacht, da es bisher für mich nicht aktuell war. Wird es wohl die nächste Zeit auch nicht werden, da in meinem neuen Unternehmen überhaupt kein Notes eingesetzt wird.

Genau den Gedanken für die Basis-Funktionen hatte ich auch, eine View oder auch eine Collection ist wohl mit vertretbarem Aufwand zu simulieren in einigen Bereichen. Man sollte aber auch hier eben durch Tests versuchen sicherzustellen, dass die Attrappen auch tun, was sie sollen.

Ich denke mal, dass testgetriebene Entwicklung eine gute Sache ist, da man durch die Unit-Tests eine Menge Sicherheit in Bezug auf Änderungen bekommt, sofern die existierenden Testfälle gut sind.
Gespeichert

flaite
Gold Platin u.s.w. member:)
*****
Offline Offline

Beiträge: 2966


WWW
« Antworten #4 am: 17.10.07 - 10:13:34 »

Übrigens benutzen auch unsere Sharepoint-Entwickler Unit-Testing.
Was die technische Umsetzung anbelangt in Bezug auf "Koppelung" von externen Java-IDEs wie Eclipse mit dem Designer habe ich mir noch nicht so wirklich Gedanken gemacht,
Wenn man den richtigen Prozess hat, kann man Notes Agenten vollständig in Eclipse entwickeln.
Völlig problemlos. Man braucht nicht mal Domiclipse. Alles andere sind Mythen. Hat mich selbst ein wenig überrascht.
Im Agenten Fenster im Designer kann man über Edit Process / Local File System / Base Directory auf src Ordner des Eclipse Projekts auf der Platte stellen und Import. Importiert neue, ersetzt bestehende. Und zwar alles unterhalb des src Ordners.
Man entwickelt den Agenten und die Java-ScriptBibliotheken in Eclipse (mit der Notes Java VM als eingetragene VM für das Projekt). Die dort erzeugten Java Klassen kann man problemlos vom Designer aus importieren. Das ist Deployment.
Vereinfacht gesprochen hat man für deployment-Prozesse immer ein Source-Repository auf der einen Seite und eine Zielplattform auf der anderen Seite. In ant-getriebenen Prozessen, pusht man den Inhalt des source-repository in die Zielplattform. In Notes pullt man aus der Zielplattform die Inhalte des source repository. Dieser Pull-Prozess ist nur ein wenig umständlicher. Ich könnte vermutlich eine funktionierende ant-Erweiterung schreiben, die pusht. Schliesslich besitzt Domiclipse den entsprechenden Code. So wichtig ist das aber gar nicht, da pull nur wenig zeitaufwendiger ist. 

Für jede Java-ScriptBibliothek hab ich ein eigenes Projekt in Eclipse. Jeder Agent auch. Die Abhängigkeiten zwischen Agenten - Java-Scriptbibliotheken und Java-ScriptBibliotheken lassen sich in Eclipse problemlos nachbilden (JavaBuild Path, Project - Tab). Das sind dann natürlich recht viele Projekte. Die organisiere ich aber unter einem Working-Set in Eclipse.
Ich bemühe mich um separation of concern (kommt man über testgestützte Entwicklung quasi von alleine drauf). D.h. Notes wird sowieso nur in sehr wenig Klassen angesprochen. Der Rest ist sowieso problemlos unit-testbar.
Java Agenten nimmt man für Spezialaufgaben, für die es in Notes allenfalls plattformabhängige Möglichkeiten mit C-Apis gibt. Z.B. entzippen von Bildern, ausmessen von height, width, grösse in Bytes der Bilder und importieren der Bilder in Notes RichText Objekte. Oder Kommunikation mit externen Webservices. In solchen Agenten ist der Anteil Klassen, die mit Notes kommunizieren, ohnehin relativ gering. Die Kern-Funktionalität ist von Notes unabhängig und somit Unit- und Integrations-testbar. Ein solches Notes-Mock Paket wäre quasi nur noch die letzte Meile, dass auch Methoden, die in Notes Agenten Notes-Klassen ansprechen, unit-testbar werden.



Gespeichert

Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile
MadMetzger
Gold Platin u.s.w. member:)
*****
Offline Offline

Geschlecht: Männlich
Beiträge: 1052


f.k.a. Alexis Pyromanis


« Antworten #5 am: 17.10.07 - 17:03:59 »

Das klingt ja doch recht praktikabel... Habe mich zu "Notes-Zeiten" da nie intensiv mit auseinandergesetzt, da Java nicht benötigt wurde und es ansonsten auch niemand beherrscht bei meinem vorherigen AG.
Gespeichert

flaite
Gold Platin u.s.w. member:)
*****
Offline Offline

Beiträge: 2966


WWW
« Antworten #6 am: 17.10.07 - 18:08:06 »

Wär eine Sache, die ich auf unseren Unternehmensblog stellen könnte:
Agile Java Entwicklungstechniken mit Lotus Domino 7.
Wenn hier nicht so viel zu tun ist.
Gespeichert

Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile
flaite
Gold Platin u.s.w. member:)
*****
Offline Offline

Beiträge: 2966


WWW
« Antworten #7 am: 07.11.07 - 08:32:27 »

Mein entsprechender Vorschlag auf idea jam hat sehr wenig Interesse generiert (http://ideajam.net/IdeaJam/P/ij.nsf/0/0A44CD430184CF7D8625738A003B1180?OpenDocument). Naja. Zumindest ist einer der beiden promoter Vorgesetzter. Hab am WE letztens ein bischen weitergeschrieben und hoffe am nächsten WE einen ersten Prototypen zu haben. Bislang siehts sehr machbar aus und es bringt eine Menge für einen deutlich effizienteren Prozess des Schreibens von Java Agenten für Lotus Domino.
Die unterstützen Klassen sind: Database, Document, Item, View, ViewColumn, DocumentCollection, Session und AgentContext.
Unmittelbare Kandidaten sind: Agent, DateTime, DateRange und Stream.
Gespeichert

Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile
MadMetzger
Gold Platin u.s.w. member:)
*****
Offline Offline

Geschlecht: Männlich
Beiträge: 1052


f.k.a. Alexis Pyromanis


« Antworten #8 am: 07.11.07 - 08:47:28 »

Das klingt sehr vielversprechend, was du da schreibst. Ich beschäftige mich auch gerade mit Tests...
Gespeichert

flaite
Gold Platin u.s.w. member:)
*****
Offline Offline

Beiträge: 2966


WWW
« Antworten #9 am: 28.12.07 - 15:10:53 »

Jetzt hab ich endlich Zeit.
Die Mock-Klassen Item und Document sind schon relativ komplett. Geb mir echt Mühe, es richtig zu machen. Gibt eine Menge Details (das nicht sehr Java kompatible Typ System, Response-Beziehungen, etc).
Werd wohl auch die Kandidaten (Agent, DateTime, DateRange und Stream).
Hoffe am 6.1. relativ weit zu sein und kann dann meinen Arbeitgeber fragen, ob wir das openSourcen können (wird wohl klappen).
Mein entsprechender Vorschlag auf idea jam brachte sehr gemischte Reaktionen.
http://tinyurl.com/2bqjle
Its because the naysayers just don't get it.  Grin
Es bringt nämlich unmittelbare und sehr offensichtliche Vorteile für den Prozess zur Entwicklung von Java-Agenten, Java-Skriptbibliotheken und Code für Notes-Zugriff.
Und ist auch für verschiedene Zielgruppen an Entwicklern gerichtet
Gruppe A:  Java Programmierer ohne viel Notes Erfahrung
Gruppe B:  Notes Entwickler ohne viel Java oder Unit-Testing Erfahrung
Gruppe C:  Angeber, die behaupten sowieso alles zu können

Wenn Gruppe B keine Lust auf Junit-Tests hat, kann man das Mock-Framework sogar benutzen, ohne überhaupt selbst Junit-Tests zu schreiben. Es ist einfach ein Nachbau der Notes Api und der Notes-Datenbank-Struktur, die völlig ohne Notes und sehr gut in Eclipse, Netbeans, Intelij-IDEA, etc. lebt.
Der Code kann direkt in einer IDE geschrieben und getestet werden und wird dann erst am Ende in die reale Notes-Datenbank exportiert. 
Ansonsten ist es heute zwar sehr einfach Notes-Java Code in Eclipse zu schreiben und das dann auch in Notes importieren. Der Bruch findet nur immer dann statt, wenn man testen will. Das importieren selbst sind zwar wenige aber immerhin Handgriffe. Ausserdem kann man nur remote debuggen und das macht überhaupt keinen Spaß.
Mit dem Framework kann man lokal debuggen und nahtlos code-schreiben / testen.
Für Unit-Test aficionados kommt natürlich die Möglichkeit von Test Driven Development und das Vorhandensein eines Regressions-Test-Sicherheits-Netz hinzu.

Inzwischen gibts übrigens ein Projekt auf openNTF, das auf Unit-Testing für LotusScript abzielt (http://tinyurl.com/ypdm3t). Werd das auf jeden Fall ausprobieren. Kann mir nicht vorstellen, dass das Sinn macht. Das können aber Vorurteile sein.

Gruß Axel
Gespeichert

Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile
flaite
Gold Platin u.s.w. member:)
*****
Offline Offline

Beiträge: 2966


WWW
« Antworten #10 am: 01.01.08 - 18:34:52 »

Sieht gut aus.
Falls jemand Interesse hat, schick ich bis zum 15.1. eine einfach zu benutzende Ausstattung mit Beschreibung der Einrichtung einer Umgebung in Eclipse.
(axel punkt janssen at gmail punkt com
Das ist keine Bug-Show. Ist dann wirklich stabil.
Meine eigene Implementierung unterstützt die grundlegenden Merkmale einer Notes Datenbank, die für die Aufgabe benötigt werden.
Ansichten mit Selektionsformeln (zur Zeit: Itemname-Formeln, dh. sowas wie Select form = "maske1" und @all) und Sortierung.
DocumentCollection
Spalten. 
Dokumente, Profil-Dokumente.
Items (kein RichText, z.Zt. keine Datumsfelder).
AgentBase, Session und AgentContext müssen noch. Die sind aber auch nicht so groß. 

Liefer das mit Beispielen aus und will nicht endlos erklären.
Kann wirklich auch für Java noobs interessant sein. 
Gespeichert

Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile
flaite
Gold Platin u.s.w. member:)
*****
Offline Offline

Beiträge: 2966


WWW
« Antworten #11 am: 03.01.08 - 21:25:18 »

Hier mein erster Agent auf meinem eigenen Notes:

Man beachte, dass die ganzen verwendeten Notes Klassen quasi "Nachbauten" sind. Für dieses Testsystem, braucht kein Notes auf dem Rechner vorhanden sein. Ok. Ausnahme ist noch die Klasse lotus.domino.NotesException. Ist ja auch ne beta  Grin

Ging eigentlich ziemlich gut, wobei mein eigenes Notes nicht komplett ist.
Aber zumindest ich brauch für die meisten Java Agenten eben diese Klassen.
Weitere Klassen können natürlich noch hinzugefügt werden. RichText wird vermutlich nicht so einfach, aber wer weiss.
Ziemlich gut gelungen ist schon die Sortierung von Ansichten.  Cool

Code:
package de.spintegration.mock.examples;

import java.util.Vector;

import java.util.Iterator;

import lotus.domino.NotesException;

import de.spintegration.notes.mock.AgentBase;
import de.spintegration.notes.mock.AgentInfo;
import de.spintegration.notes.mock.Database;
import de.spintegration.notes.mock.Document;
import de.spintegration.notes.mock.DocumentCollection;
import de.spintegration.notes.mock.Item;
import de.spintegration.notes.mock.MockFactory;
import de.spintegration.notes.mock.View;
import de.spintegration.notes.mock.ViewColumn;

/**
 * @author ajanssen
 *
 */
public class SimpleAgent extends AgentBase {


/* (non-Javadoc)
* @see de.spintegration.notes.mock.AgentBase#NotesMain()
*/
public void NotesMain() {
try {
System.out.println ("********************************");
System.out.println ("SESSION.GETNOTESVERSION :-). ");
System.out.println ("********************************");

System.out.println(session.getNotesVersion());
Database dbCur = agentContext.getCurrentDatabase();
View vw1 = dbCur.getView("ansicht1");


System.out.println ("********************************");
System.out.println ("ANSICHT");
System.out.println ("********************************");

System.out.println(vw1.prettyPrint());

Document docAfro = vw1.getDocumentByKey("Afrika");
Vector itemAfro = docAfro.getItems();
Iterator itItemAfro = itemAfro.iterator();

System.out.println ("********************************");
System.out.println ("FELDWERTE DES PER DOKUMENT-by-Key(Afrika) gefundenen Dokuments");
System.out.println ("********************************");

while (itItemAfro.hasNext()) {
String fieldName = itItemAfro.next().toString();
Item item = docAfro.getFirstItem(fieldName);
System.out.println(item.getName() + "-->" + item.getValues());
}

System.out.println ("********************************");
System.out.println ("KONGO-Dokument einfügen");
System.out.println ("UND BEACHTET WIE SICH DAS EINSORTIERT, KONTINENT UND LAND SIND SORTIERTE SPALTEN,s. main Methode oben");
System.out.println ("********************************");


Document docNewAfro = dbCur.createDocument();
docNewAfro.replaceItemValue("form", "maske5");
docNewAfro.replaceItemValue("kontinent", "Afrika");
docNewAfro.replaceItemValue("land", "Kongo");
docNewAfro.replaceItemValue("staedte", "Kinshasa");
docNewAfro.save();

System.out.println(vw1.prettyPrint());


System.out.println ("********************************");
System.out.println ("Dokument Collection-> GIBT JA JETZT 2 DOKUMENTE MIT KEY AFRIKA");
System.out.println ("********************************");

DocumentCollection colAfro = vw1.getAllDocumentsByKey("Afrika");
docAfro = colAfro.getFirstDocument();

while (docAfro != null) {
itemAfro = docAfro.getItems();
itItemAfro = itemAfro.iterator();

System.out.println ("********************************");
System.out.println ("Dokument IN Collection");
System.out.println ("********************************");

while (itItemAfro.hasNext()) {
String fieldName = itItemAfro.next().toString();
Item item = docAfro.getFirstItem(fieldName);
System.out.println(item.getName() + "-->" + item.getValues());
}

docAfro = colAfro.getNextDocument();
}




} catch (NotesException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


}

public static void main (String[] args) throws NotesException {
/*
* ERSTMAL MUSS DIE DATENBANK DEFINIERT WERDEN
* IST ZUGEGEBEN EIN WENIG MÜHSELIG.
* WERD ABER EINE MÖGLICHKEIT DER DEFINITION DER DATENBANK MIT XML ANBIETEN.
*/
MockFactory fac = MockFactory.getInstance();
Database parentDatabase = fac.getDatabase("test", "test.nsf");

// view definieren -> SORTIERUNG BEACHTEN.
View vw1 = fac.addView(parentDatabase, "ansicht1", "@all");
fac.addViewColumn(vw1, "form", "form");
fac.addViewColumn(vw1, "kontinent", "kontinent", ViewColumn.SORT_ASCENDING);
fac.addViewColumn(vw1, "land", "land", ViewColumn.SORT_ASCENDING);
fac.addViewColumn(vw1, "städte", "staedte");


// DOKUMENTE DIE VOR LAUF DES AGENTEN DA SIND. 
Document doc1 = fac.addDocumentWithForm(parentDatabase, "maske1");
doc1.replaceItemValue("kontinent", "Europa");
doc1.replaceItemValue("land", "Deutschland");
Vector vecStädteDoc1 = new Vector();
vecStädteDoc1.add("Köln");
vecStädteDoc1.add("Hannover");
vecStädteDoc1.add("Frankfurt");
doc1.replaceItemValue("staedte", vecStädteDoc1);
doc1.save();

Document doc2 = fac.addDocumentWithForm(parentDatabase, "maske2");
doc2.replaceItemValue("kontinent", "Europa");
doc2.replaceItemValue("land", "Groß Britannien");
Vector vecStädteDoc2 = new Vector();
vecStädteDoc2.add("London");
vecStädteDoc2.add("Glasgow");
vecStädteDoc2.add("Manchester");
doc2.replaceItemValue("staedte", vecStädteDoc2);
doc2.save();

Document doc3 = fac.addDocumentWithForm(parentDatabase, "maske3");
doc3.replaceItemValue("kontinent", "Amerika");
doc3.replaceItemValue("land", "Argentinien");
Vector vecStädteDoc3 = new Vector();
vecStädteDoc3.add("Buenos Aires");
vecStädteDoc3.add("Cordoba");
vecStädteDoc3.add("Mendoza");
doc3.replaceItemValue("staedte", vecStädteDoc3);
doc3.save();

Document doc4 = fac.addDocumentWithForm(parentDatabase, "maske4");
doc4.replaceItemValue("kontinent", "Asien");
doc4.replaceItemValue("land", "Indien");
Vector vecStädteDoc4 = new Vector();
vecStädteDoc4.add("Mumbai");
vecStädteDoc4.add("Kalkutta");
vecStädteDoc4.add("Bangalore");
doc4.replaceItemValue("staedte", vecStädteDoc4);
doc4.save();

Document doc5 = fac.addDocumentWithForm(parentDatabase, "maske5");
doc5.replaceItemValue("kontinent", "Afrika");
doc5.replaceItemValue("land", "Maroko");
Vector vecStädteDoc5 = new Vector();
vecStädteDoc5.add("Marakesch");
vecStädteDoc5.add("Fes");
vecStädteDoc5.add("Rabat");
doc5.replaceItemValue("staedte", vecStädteDoc5);
doc5.save();

// set AGENTIFO
AgentInfo agInfo = new AgentInfo(fac);
agInfo.setCurrentDatabase(parentDatabase);


// AGENT STARTEN
SimpleAgent sa = new SimpleAgent();
sa.startup(agInfo);
}

}

und hier die Ausgabe:

Code:
********************************
SESSION.GETNOTESVERSION :-).
********************************
Happy Sandbox Notes, Release 0.4 Copper Edition|21st Century.
********************************
ANSICHT
********************************
Datenbank=test(test.nsf)
Ansicht=ansicht1, Selektionsformel=@all

form  |kontinent|land           |städte                      |
______|_________|_______________|____________________________|
maske5|Afrika   |Maroko         |Marakesch,Fes,Rabat         |
______|_________|_______________|____________________________|
maske3|Amerika  |Argentinien    |Buenos Aires,Cordoba,Mendoza|
______|_________|_______________|____________________________|
maske4|Asien    |Indien         |Mumbai,Kalkutta,Bangalore   |
______|_________|_______________|____________________________|
maske1|Europa   |Deutschland    |Köln,Hannover,Frankfurt     |
______|_________|_______________|____________________________|
maske2|Europa   |Groß Britannien|London,Glasgow,Manchester   |
______|_________|_______________|____________________________|

********************************
FELDWERTE DES PER DOKUMENT-by-Key(Afrika) gefundenen Dokuments
********************************
staedte-->[Marakesch, Fes, Rabat]
form-->[maske5]
land-->[Maroko]
kontinent-->[Afrika]
********************************
KONGO-Dokument einfügen
UND BEACHTET WIE SICH DAS EINSORTIERT, KONTINENT UND LAND SIND SORTIERTE SPALTEN,s. main Methode oben
********************************
Datenbank=test(test.nsf)
Ansicht=ansicht1, Selektionsformel=@all

form  |kontinent|land           |städte                      |
______|_________|_______________|____________________________|
maske5|Afrika   |Kongo          |Kinshasa                    |
______|_________|_______________|____________________________|
maske5|Afrika   |Maroko         |Marakesch,Fes,Rabat         |
______|_________|_______________|____________________________|
maske3|Amerika  |Argentinien    |Buenos Aires,Cordoba,Mendoza|
______|_________|_______________|____________________________|
maske4|Asien    |Indien         |Mumbai,Kalkutta,Bangalore   |
______|_________|_______________|____________________________|
maske1|Europa   |Deutschland    |Köln,Hannover,Frankfurt     |
______|_________|_______________|____________________________|
maske2|Europa   |Groß Britannien|London,Glasgow,Manchester   |
______|_________|_______________|____________________________|

********************************
Dokument Collection-> GIBT JA JETZT 2 DOKUMENTE MIT KEY AFRIKA
********************************
********************************
Dokument IN Collection
********************************
staedte-->[Kinshasa]
form-->[maske5]
land-->[Kongo]
kontinent-->[Afrika]
********************************
Dokument IN Collection
********************************
staedte-->[Marakesch, Fes, Rabat]
form-->[maske5]
land-->[Maroko]
kontinent-->[Afrika]

Gespeichert

Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile
MadMetzger
Gold Platin u.s.w. member:)
*****
Offline Offline

Geschlecht: Männlich
Beiträge: 1052


f.k.a. Alexis Pyromanis


« Antworten #12 am: 03.01.08 - 21:47:05 »

Da hast du aber bisher ganze Arbeit geleistet, Axel! Sieht echt nicht schlecht aus...
Gespeichert

flaite
Gold Platin u.s.w. member:)
*****
Offline Offline

Beiträge: 2966


WWW
« Antworten #13 am: 03.01.08 - 22:09:36 »

Danke. Vor allem mehr Arbeit als ich dachte.
Ich feil noch ein paar Ecken ab, bau vielleicht noch ein paar Features ein (so dafür Zeit ist) und geb das am 15. raus.
Ich kanns wirklich selbst gebrauchen, wobei ich natürlich auch nicht weiss, ob ich nächstes Jahr viele Notes Agenten schreiben werde.
Hat aber auch wirklich Spaß gemacht das zu schreiben.
UniqueIDs und DocIDs gibts auch (ist auch nicht so schwierig, weils nicht verteilt ist).
Nächstes Feature wären Leserfelder wirklich unterstützen. Vielleicht das Notes-Datumszeugs. Gehen tut das alles.
Vielleicht interessieren sich Kerr Rainey oder Ben Poole dafür.
Mein AgentContext hat vor und nach Aufruf von NotesAgent einen Interceptor. Damit kann man difs vor und nach dem Agentlauf für Unit-Tests schreiben. Ist aber noch nicht getestet.
Gespeichert

Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile
flaite
Gold Platin u.s.w. member:)
*****
Offline Offline

Beiträge: 2966


WWW
« Antworten #14 am: 07.01.08 - 16:46:17 »

Vielleicht verwende ich irgendwann couchDB als Persistenz-Speicher, hihi. (http://damienkatz.net/2008/01/new_gig.html)
Zur Zeit ist das ja eine reine in-memory Datenbank, was für unit-Tests auch völlig richtig ist.

Gruß Axel 
Gespeichert

Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile
flaite
Gold Platin u.s.w. member:)
*****
Offline Offline

Beiträge: 2966


WWW
« Antworten #15 am: 14.01.08 - 10:38:56 »

... in der attachten html-Datei.
hellgrün -> implementiert.
rotbraun -> nicht implementiert.

Manche der nicht implementierten Methoden sind recht obskur oder betreffen das UI (z.B. setShowTwistie() in der Klasse ViewColumn).
Die Datei ist generiert mit einem zusäztlichen Hilfs-Projekt, einfach mit Java-Reflection.

Neue Features können noch recht schnell hinzugefügt werden
- folders
- "Mail"-Methoden wie document.send() -> mit interceptoren, die die vom Agenten "versendeten" Mails in eine Art Queue schreiben, so dass sie etwa durch Unit-Tests überprüfbar sind.

Auf ein interessantes Problem bin ich gestossen:
Unterschiedlicher State von Dokumenten. Wenn ich den state eines vorher gespeicherten Dokuments ändere. (Etwa durch doc.replaceItemValue(fieldName, value), sind diese Werte ja nicht im Notes-Dokument abgebildet, wenn ich es über das Backend neu lade (etwa per database.getDocumentByUNID) bevor ich die State-Änderungen per doc.save() ins Backend schreibe. Da weiss ich noch nicht richtig, wie ich das abbilde. Sollte jemand das Problem verstehen und eine Idee haben, immer her damit. Vielleicht bietet es sich an, couchDB - an dem ja der wieder-IBM Mitarbeiter Damien Katz weiterarbeitet - als eine Art Persistenzmanager zu verwenden. Muß das aber noch prüfen. Ist jetzt aber sowieso nicht top-Prio.

Gruß Axel
« Letzte Änderung: 14.01.08 - 10:58:03 von Axel Janssen » Gespeichert

Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile
MadMetzger
Gold Platin u.s.w. member:)
*****
Offline Offline

Geschlecht: Männlich
Beiträge: 1052


f.k.a. Alexis Pyromanis


« Antworten #16 am: 14.01.08 - 14:36:07 »

Hm... Ich habe gerade dein Posting gelesen. Nach wie vor finde ich das ein gutes Projekt und bin doch sehr überrascht, wie stark man Notes doch "mocken" kann.

Zu deiner Frage:
Kann man dein Problem nicht evtl über eine Art Caching-Mechanismus und Proxies lösen? Also die Dokumente liegen in einem zentralen Cache, aus dem sie bei den verschiedenen Lade-Methoden als Proxy ausgeliefert werden. Beim Speichern wird dann der Proxy an den Cache gegeben, wo er versucht die neuen Daten ins Original zurückzuschreiben. Nur so als Idee. An der Stelle hast du dann auch die Chance Replizierkonflikte zu erzeugen, wenn nämlich zwei zur gleichen Zeit geholte Dokumente zu unterschiedlichen Zeiten zurückschreiben wollen. Was hälst du von dem Vorschlag?

EDIT: Noch eine weitere Idee, zur Ansiedlung des Dokumenten-Cache: Der sollte vielleicht je Notesdatenbank verfügbar sein.
« Letzte Änderung: 14.01.08 - 15:07:03 von MadMetzger » Gespeichert

flaite
Gold Platin u.s.w. member:)
*****
Offline Offline

Beiträge: 2966


WWW
« Antworten #17 am: 14.01.08 - 15:26:56 »

Mit Proxy hat das glaub ich nichts zu tun.

Durch die Persistenz in Notes, können unterschiedliche Versionen von Document-Objekten mit der gleichen DocUnid existieren.
Code:
Document docNew = db.createDocument();
docNew.replaceItemValue("form", "form1");
docNew.save();
Document docFromPersistedMem = db.getDocumentByUNID(docNew.UniversalID);
docNew.replaceItemValue("land", "Germany");

docNew und docFromPerstistedMem haben die gleiche UniversalID.
Das Objekt docNew hat am Ende des scripts ein Feld "land".
Das Objekt docFromPersistedMem hat dieses Feld dagegen nicht.
Erst durch ein docNew.save() würden beide Versionen wieder synchronisiert.

Das ist durch mein MockFramework zur Zeit schwer abzubilden, da es gar keinen persistenten Speicher hat. Die Dokumente sind rein in-Memory, dh. sie liegen in Database in (mehreren) Maps.

Zur Abbildung wäre es vermutlich am einfachsten, wenn ich eine Persistenzschicht einziehen würde. Eine Persistenzschicht zu simmulieren, dürfte auch machbar sein.
Allerdings bewege ich mich hier schon in Corner-Cases, die nicht Bestandteil der 1. Version sind.
Gespeichert

Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile
MadMetzger
Gold Platin u.s.w. member:)
*****
Offline Offline

Geschlecht: Männlich
Beiträge: 1052


f.k.a. Alexis Pyromanis


« Antworten #18 am: 14.01.08 - 15:33:14 »

Stimmt, richtige Proxies sind das nicht so wirklich. Es sind ja keine Stellvertreter in dem Sinne.

Aber vom Prinzip würde ich nur Kopien ausliefern und die dann auf die Originale zurückschreiben.
Gespeichert

flaite
Gold Platin u.s.w. member:)
*****
Offline Offline

Beiträge: 2966


WWW
« Antworten #19 am: 15.01.08 - 09:16:43 »

Das stimmt vermutlich mit den Kopien. Nur muss ich die eben als tiefe Kopien ausliefern.
Ein Document enthält Item Objekte. Da können nicht einfach die Referenzen kopiert werden, sondern es müssen eben echte Kopien erstellt werden. In den Items sind wiederum String-, Number- und Datums-Objekte. Da können immer dann Referenzen kopiert werden, wenn die Klasse inmutable ist.
Gespeichert

Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile
Seiten: [1] 2 Nach oben Drucken 
« vorheriges nächstes »
Gehe zu:  


Einloggen mit Benutzername, Passwort und Sitzungslänge

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006, Simple Machines Prüfe XHTML 1.0 Prüfe CSS
Impressum Atnotes.de - Powered by Syslords Solutions - Datenschutz | Partner: