Lotus Notes / Domino Sonstiges > Java und .NET mit Notes/Domino

Wie fülle ich einen TreeViewer für Domino Objekte

(1/2) > >>

Mark³:
Bei JFace gibt es strukturierte Viewer, z.B. den TreeViewer. Dieser wird durch einen ViewContentProvider mit Objekten gefüllt. Die einfachste Form wird hier vorgestellt http://www-128.ibm.com/developerworks/lotus/library/notes-plugin-eclipse/.
Ich suche nun aber eine elegante Möglichkeit, um z.B. alle Dokumente einer View bereitzustellen und dabei möglichst viel Code wiederverwerten zu können.
Ein interessanter allgemeiner Ansatz ist bereits im RCP Mail Template von Eclipse enthalten. Ich habe aber Schwierigkeiten die allgemeinen TreeObjekte dort mit den konkreten Notes-Objekten zu verknüpfen.
Ein gutes Anwendungsbeispiel wäre z.B., einen Eclipse RCP zu bauen, der über CORBA die HELP!-Datenbank anspricht.
Noch ein paar Details zum tieferen Verständnis:

Der ViewContentProvider arbeitet nur mit Objekten (java.lang.Object). Dadurch könnte man nun ganz einfach ein Objekt vom Typ Document (lotus.domino.Document) übergeben und als Element das Subjekt einer Mail ausgeben

--- Code: ---((Document)Object).getItemValueString("Subject")
--- Ende Code ---
Das ist noch recht unspektakulär. Das Schöne am Treeviewer ist ja nun, dass er auch Parent/Child-Beziehungen abdeckt. Nun ist in Notes aber Parent eine View, Child ein Dokument und das Kind vom Dokument wieder ein Dokument. Da nur Objekte übergeben werden kann man das natürlich alles abbilden, aber wie das konkret geht weiß ich nicht so genau. Vielleicht hat ja jemand konstruktive Vorschläge dazu?

Mark³:
JFace unterstützt ja das MVC-Muster (Model-View-Controller). Das was ich suche ist nun das Model, also das Datenmodell von einer Notesdatenbank, welches ich im TreeViewer abbilden will.
Da ich verschiedene Objekte habe (View, Document, evt. Item) muss ich auf jeden Fall in meinem Model ermitteln, ob das momentane Objekt instanceof View, Document oder Item ist. Bei View würde getElements() alle Dokumente zurückliefern, bei Document alle Items und ResponseDocs.
Ein TreeViewer kann nun aber nicht nur einen ViewContentProvider nutzen, sondern auch einen ViewLabelProvider. Und wenn mein Objekt eine View ist muss getText View.getName liefern, bei einem Dokument Document.getSubject (bei Mails, bei Tickets in HELP vielleicht ReqNumber?) und bei einem Item item.getText

Ich glaube ich komme dem Ziel schon näher. Nicht dass jemand denkt, Axel postet nun unter meinem Usernamen ;D, ich finde es manchmal ganz hilfreich, laut zu denken und vielleicht interessiert es ja auch den einen oder anderen hier. Schließlich ist ja (wie ich immer gern wiederhole) die Technik Eclipse RCP = Lotus Workplace = Notes 8 oder 9

Mark³:
eine Anregung für die Verallgemeinerung des Ansatzes ist hier zu finden:
http://www.eclipsezone.com/eclipse/forums/t53983.html

Mark³:
Dank des eben erwähnten Artikels habe ich nun einen Ansatz gefunden:
Ich habe jeweils ein Node pro Hierarchie, d.h. ein DatabaseNode, ViewNode, DocumentNode.
Als Beispiel öffne ich die HELP-DB über CORBA und lasse mir alle Ansichten anzeigen, deren Name mit "N" beginnt. In den Views lasse ich mir dann alle Dokumente anzeigen. Pro Dokument zeige ich ReqNumber + ": " + Problem.

Hier die Nodes:

--- Code: ---public class DatabaseNode extends TreeNode {

private Database fDatabase; /* actual data object */

public DatabaseNode(Database database) {
this(null, database);
}

public DatabaseNode(ITreeNode parent, Database database) {
super(parent);
fDatabase = database;
}

public String getName() {
String databasename = null;
try {
databasename = fDatabase.getTitle();
} catch (NotesException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "Database: " + databasename;
}

public Image getImage() {
return null; /* TODO: Return View image */
}

protected void createChildren(List children) {
Object[] views = null;
try {
views = fDatabase.getViews().toArray();
} catch (NotesException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

for (int i=0;i<views.length;i++) {
View v = (View)views[i];
try {

if (v.getName().startsWith("N")) {
children.add(new ViewNode(this, v));
}
} catch (NotesException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


}

}

--- Ende Code ---


--- Code: ---public class ViewNode extends TreeNode {
private View fView; /* actual data object */

public ViewNode(View view) {
this(null, view);
}

public ViewNode(ITreeNode parent, View view) {
super(parent);
fView = view;
}

public String getName() {
String viewname = null;
try {
viewname = fView.getName();
} catch (NotesException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "VIEW: " + viewname;
}

public Image getImage() {
return null; /* TODO: Return View image */
}

protected void createChildren(List children) {
Document doc = null;
try {
doc = fView.getFirstDocument();

while (doc != null) {
children.add(new DocumentNode(this, doc));
doc = fView.getNextDocument(doc);
}
} catch (NotesException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}
--- Ende Code ---


--- Code: ---public class DocumentNode extends TreeNode {

private Document fDocument; /* actual data object */

public DocumentNode(ITreeNode parent, Document document)
{
super(parent);
fDocument = document;
}

public String getName() {
String text = null;
try {
text = fDocument.getItemValueString("ReqNumber") + ": " + fDocument.getItemValueString("Problem");
} catch (NotesException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return text;
}
 
public Image getImage() {
return null; /* TODO: Return File image */
}

protected void createChildren(List children) {
}

public boolean hasChildren() {
return false;
}

}

--- Ende Code ---

Es fehlen noch die Ikonen in der richtigen Größe...Aufgerufen wird so eine View einfach mit

--- Code: ---viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
viewer.setContentProvider(new TreeContentProvider());
viewer.setLabelProvider(new TreeLabelProvider());
Database db = HelpclientPlugin.getSession().getDatabase(null,"HELPDESK15.nsf");
viewer.setInput(new DatabaseNode(db));

--- Ende Code ---

flaite:
Cool.
Ich greife nicht direkt auf die Webservices-Daten zu, sondern packe einen Business Layer dazwischen, der ein eigenes Objekt-Modell der HELP-Daten liefert.
Diese Business Schicht liefert mir dann Maps und andere Objekte, auf die dann Swing Widgets zugreifen können, die übrigens auch MVC implementieren.
Der Vorteil besteht in einer besseren separation of concerns. Ausserdem kann man auf diese Business Schicht von beliebigen Clients zugreifen (Swing, Eclipse-RCP, Serlets/JSP, mobile Clients, Text-Konsole).
In der business-Schicht kann ich auch Caching, Security oder so Services implementieren.
Wenn es denn mal fertig wird (ich arbeite dran).

Gruß Axel

Navigation

[0] Themen-Index

[#] Nächste Seite

Zur normalen Ansicht wechseln