Hello Ulrich,
I am with Research In Motion, the makers of the BlackBerry solution.
We are currently looking to demonstrate at Lotusphere BlackBerry Mobile
Data Services 4.1 support for Domino 7 web services and your application
appeared as a candidate. Do you have any current work to extend the
application using the native D7 web services? Any means to get
development assistance from your team to add this into the application
(at least a few basic functions) in the next few weeks?
Thanks in advance,
Jon
_____________________________
Jonathan Christiansen
Senior Manager, Technical Services
Cingular Business Unit
Rogers Business Unit
Research In Motion Limited
Biete ab dem 29.12. meine konstruktive Mitarbeit an
<ticket>
<topic>
Der Button Neues Ticket in der Ansicht Ticket funktioniert nicht
</topic>
<createDateTime>
03.12.04 10:00:00
</createDateTime>
<creator>
Jupp Derwall
</creator>
<history>
<entry>
<date>
14.12.04 10:30:00
</date>
<user>
Sarah Burdenski
</user>
<content>
weiss nicht
</content>
</entry>
<entry>
<date>
14.12.04 10:35:00
</date>
<user>
Big Boss
</user>
<content>
wenn das nicht in 3 Tagen gelöst ist, gibts Ärger
</content>
</entry>
</ticket>
Hoffe das ist verständlich.
Oder man sendet ein paar Werte pro Ticket runter, die in einer Ansicht (nicht NotesView) auf Blackberry dargestellt werden können (etwa TicketNum, Datum, Priorität, Subject) etc und hat dann noch eine zweite Funktion, die nach Auswahl des Tickets aus der Blackberry Ansicht das gesamte Ticket zurückliefert (bzw. alle Teile des Tickets, die in Blackberries Detailansicht des Tickets dargestellt werden sollen).
oder createTicket(TicketDoc)
Ted Neward hat das mal damit verglichen:
Mit heutiger Technologie dauert es 38 Jahre, um von Pluto hin und zurück zu fliegen.
Auf Pluto gibt es total gutes Bier.
Wieviel Bier würde man mit einem Raumschiff von Pluto mitnehmen?
Soviel man tragen kann und sicher nicht jede Bierflasche einzeln (wie teilweise EJB2.0 in Websphere oder erst ticketNum und dann das dazugehörige Subject).
Ulrich, my apologies on the delayed response. All of the functions you described below were in line with my thoughts. Accessing collections of tickets, viewing tickets, search for ticket, creating and modifying tickets. We are looking for apps to demo against our MDS 41 web services consumer IDE (MDS studio) and would showcase the app at lotusphere. Any chance you can have something by January 10th?
Class Land
Private ses As NotesSession
Private db As NotesDatabase
Private vwLand As NotesView
Public Sub New
Set ses = New NotesSession()
Set db = ses.currentDatabase
Set vwLand = db.getView("land")
End Sub
Public Function getHauptstadt (land As String) As String
Dim docLand As NotesDocument
Set docLand = vwLand.GetDocumentByKey(land)
If docLand Is Nothing Then
getHauptstadt = "LAND <" & land & "> kann in der Datenbank nicht gefunden werden."
Else
getHauptstadt = docLand.Hauptstadt(0)
End If
End Function
Public Function getAllLands() As Variant
Dim retVal() As LandInst
Dim aCounter As Long
aCounter = -1
Dim aLandInst As LandInst
Dim docLand As NotesDocument
Set docLand = vwLand.getFirstDocument
Do Until docLand Is Nothing
aCounter = aCounter + 1
Set aLandInst = New LandInst()
aLandInst.name = docLand.land(0)
aLandInst.hauptStadt = docLand.hauptStadt(0)
Redim Preserve retVal(aCounter)
Set retVal(aCounter) = aLandInst
Set docLand = vwLand.GetNextDocument(docLand)
Loop
If aCounter > - 1 Then
getAllLands = retVal
Else
getAllLands = retVal
End If
End Function
End Class
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="urn:DefaultNamespace" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="urn:DefaultNamespace" xmlns:intf="urn:DefaultNamespace" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:message name="GETHAUPTSTADTResponse">
<wsdl:part name="GETHAUPTSTADTReturn" type="xsd:string"/>
</wsdl:message>
<wsdl:message name="GETALLLANDSRequest">
</wsdl:message>
<wsdl:message name="GETHAUPTSTADTRequest">
<wsdl:part name="LAND" type="xsd:string"/>
</wsdl:message>
<wsdl:message name="GETALLLANDSResponse">
<wsdl:part name="GETALLLANDSReturn" type="xsd:anyType"/>
</wsdl:message>
<wsdl:portType name="Land">
<wsdl:operation name="GETHAUPTSTADT" parameterOrder="LAND">
<wsdl:input message="impl:GETHAUPTSTADTRequest" name="GETHAUPTSTADTRequest"/>
<wsdl:output message="impl:GETHAUPTSTADTResponse" name="GETHAUPTSTADTResponse"/>
</wsdl:operation>
<wsdl:operation name="GETALLLANDS">
<wsdl:input message="impl:GETALLLANDSRequest" name="GETALLLANDSRequest"/>
<wsdl:output message="impl:GETALLLANDSResponse" name="GETALLLANDSResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="DominoSoapBinding" type="impl:Land">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="GETHAUPTSTADT">
<wsdlsoap:operation soapAction="GETHAUPTSTADT"/>
<wsdl:input name="GETHAUPTSTADTRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:DefaultNamespace" use="encoded"/>
</wsdl:input>
<wsdl:output name="GETHAUPTSTADTResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:DefaultNamespace" use="encoded"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GETALLLANDS">
<wsdlsoap:operation soapAction="GETALLLANDS"/>
<wsdl:input name="GETALLLANDSRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:DefaultNamespace" use="encoded"/>
</wsdl:input>
<wsdl:output name="GETALLLANDSResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:DefaultNamespace" use="encoded"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="LandService">
<wsdl:port binding="impl:DominoSoapBinding" name="Domino">
<wsdlsoap:address location="http://localhost"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
<wsdl:message name="GETALLLANDSResponse">
<wsdl:part name="GETALLLANDSReturn" type="xsd:anyType"/>
</wsdl:message>
Class TicketCollection
Public Tickets() As Ticket
Public Count As Integer
End Class
<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:GETALLLANDSResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="urn:DefaultNamespace">
<GETALLLANDSReturn xsi:type="ns1:LANDCOLWRAPPER">
<ALLLANDINST soapenc:arrayType="ns1:LANDINST[2]" xsi:type="soapenc:Array">
<item xsi:type="ns1:LANDINST"/>
<item xsi:type="ns1:LANDINST"/>
</ALLLANDINST>
</GETALLLANDSReturn>
</ns1:GETALLLANDSResponse>
</soapenv:Body>
</soapenv:Envelope>
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soapenv:Body>
<ns1:GETALLLANDSResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="urn:DefaultNamespace"><GETALLLANDSReturn xsi:type="ns1:LANDCOLWRAPPER"><ALLLANDINST xsi:type="soapenc:Array" soapenc:arrayType="ns1:LANDINST[2]"><item xsi:type="ns1:LANDINST"><ANAME xsi:type="xsd:string">Chile</ANAME><HAUPTSTADT xsi:type="xsd:string">Santiago</HAUPTSTADT></item><item xsi:type="ns1:LANDINST"><ANAME xsi:type="xsd:string">Deutschland</ANAME><HAUPTSTADT xsi:type="xsd:string">Berlin</HAUPTSTADT></item></ALLLANDINST></GETALLLANDSReturn></ns1:GETALLLANDSResponse>
</soapenv:Body>
</soapenv:Envelope><soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:GETALLLANDSResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="urn:DefaultNamespace">
<GETALLLANDSReturn xsi:type="ns1:LANDCOLWRAPPER">
<ALLLANDINST soapenc:arrayType="ns1:LANDINST[2]" xsi:type="soapenc:Array">
<item xsi:type="ns1:LANDINST">
<ANAME xsi:type="xsd:string">Chile</ANAME>
<HAUPTSTADT xsi:type="xsd:string">Santiago</HAUPTSTADT>
</item>
<item xsi:type="ns1:LANDINST">
<ANAME xsi:type="xsd:string">Deutschland</ANAME>
<HAUPTSTADT xsi:type="xsd:string">Berlin</HAUPTSTADT>
</item>
</ALLLANDINST>
</GETALLLANDSReturn>
</ns1:GETALLLANDSResponse>
</soapenv:Body>
</soapenv:Envelope><?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soapenv:Body>
<ns1:GETALLLANDSResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="urn:DefaultNamespace"><GETALLLANDSReturn xsi:type="ns1:LANDCOLWRAPPER"><ALLLANDINST xsi:type="soapenc:Array" soapenc:arrayType="ns1:LANDINST[2]"><item xsi:type="ns1:LANDINST"><ANAME xsi:type="xsd:string">Chile</ANAME><HAUPTSTADT xsi:type="xsd:string">Santiago</HAUPTSTADT></item><item xsi:type="ns1:LANDINST"><ANAME xsi:type="xsd:string">Deutschland</ANAME><HAUPTSTADT xsi:type="xsd:string">Berlin</HAUPTSTADT></item></ALLLANDINST></GETALLLANDSReturn></ns1:GETALLLANDSResponse>
</soapenv:Body>
</soapenv:Envelope>
Kann aber z.B. für die !!!Help!!!-Webservices auch einen Swing Client schreiben.
Ich habe den Code mal an die "Brombeeren" bei RIM geschickt; Testen in Eclipse oder der SoapGUI ist ja ganz nett, ich würde aber gerne auch wissen, ob die mit dem Zeugs was anfangen können.Weiss nicht. Vielleicht zu kompliziert. Hängt vom Tool ab. Zumindest für Java1.4 kann ich mit Eclipse für mein Beispiel eine Reihe von Klassen erzeugen, die als Subsystem definitiv funktionieren.
Public Function GetAllTicketsBySupporterView ( strSupporter As String) As TicketViewCollection
class TicketViewEntry
Public User As String
Public TicketNumber As String
Public Problem As String
Public lastChange As Date
end class
Public Function GetTicketBySupporterDetail ( TicketNumber As String) As Ticket
class Ticket
Public User As String
Public TicketNumber As String
Public Problem As String
Public lastChange As Date
Public String content
Public ticketHistoryCollection as TicketHistoryCollection ' oops neues Objekt
etc.
end class
Interessant finde ich die Benamsung. Da wird von Klassen ( class) geredet, wenn man doch eigentlich einen Type meint ...Eine Klasse hat für mich immer mindestens eine Property oder methode.SOAP ist heute offiziell kein Akronym mehr für "Simple Object Access Protocol" sondern ein Eigenname.
wie wäre es mit einem Client basierend auf der Eclipse Rich Client Platform (RCP) anstelle von Swing Client?Kannst du machen. ;)
Axel, du hast mehrfach angedeutet, daß du die Webservices langsam findest ( nehme an, du meinst den Response )7 Sekunden find ich eindeutig zu viel. Bin schliesslich kein Websphere-EJB2.0-Entwickler. Werd auf jeden Fall noch untersuchen, wo er so lange braucht. Meine Idee nur die Tickets runterzuladen, die später verändert worden sind als ein vom Client persistent abgelegter Zeitstempel halte ich nach wie vor für gut. Bin aber auch dafür, erst einmal eine Lösung mit Schwächen anzubieten.
Habe gerade mal ein wenig rumgespielt: Knapp 13 Sekunden braucht der Service, um 583 Tickets abzurufen. Also ich finde, das ist i.O., oder ?
rage mich gerade, ob es eigentlich sinnvoll ist, die einzelnen Services in einer "Klasse" zu kapseln.Nö. Eine wsdl Datei für sämtliche Funktionen, die irgendwie etwas mit Tickets zu tun haben. Das ist auch für die IDE auf Consumerseite wesentlich einfacher für die Code-Generierung.
For i = 0 To dc.Count
Set doc = dc.GetNthDocument ( i + 1 )
SOAP | Java | LotusScript |
xsd:dateTime | java.util.Calendar | XSD_DATETIME |
Hat HELP!!! eigentlich eine CMDB?
Diese Baumdarstellung, ist das in Swing schon drin oder musst du das bauen?javax.swing.JTree
Im RCP geht das nämlich ganz einfach über JFace TreeViewer...Gibt da auch ein Widget, das eine Art Mischung aus Tree und Table ist. Hab aber den Namen vergessen. Das würde Sinn machen. Swing ist aber auch nicht so schlecht.
Hat HELP!!! eigentlich eine CMDB? Die ist nämlich das Herzstück eines jeden TroubleTicket Systems. Wenn nicht, vielleicht kann ich da mal meine Erfahrung einbringen, irgendwann im nächsten Jahr...Configuration Management Database. Kannte die Abkürzung nicht.
Ist WTP 1.0 Eclipse + Web oder fehlt da irgendwas? Sonst kannst du damit ja einfach ein neues RCP-Projekt erstellen und deinen Code da reinziehen.ja. Das all-in-one Paket:
Das hängt jetzt davon ab.ZitatHat HELP!!! eigentlich eine CMDB?
Thomas hat da was in der Hinterhand; ist aber noch nicht freigegeben ...
Ich glaub was Mark meint ist eine Zentrale Konfigurations Datenbank. Für die ganze Anwendung und nein, das haben wir nicht.Tut mir leid, ich denke schon völlig in ITIL. Eine CMDB ist für mich wie oben gesagt die Configuration Management Database. Hier stehen alle Assets drin, das sind im Allgemeinen sämtliche Hardware die inventarisiert ist sowie alle Softwarelizenzen.
Ticket ticketBO = null;
// check ob in der Map ein Ticket mit dieser TICKETNUMBER schon da ist. Wenn ja überschreiben, sonst neu erzeugen.
if ((ticketBO = mTickets.get(ticketWs.getTICKETNUMBER())) != null) {
System.out.println("old.ticket"); // ja ich bau da gleich log4j ein :-)
ticketBO.setStatus(ticketWs.getSTATUS());
ticketBO.setUser(ticketWs.getUSER());
ticketBO.setProblem(ticketWs.getPROBLEM());
} else {
ticketBO = Ticket.getInstance(ticketWs.getTICKETNUMBER(),
ticketWs.getSTATUS(), ticketWs.getUSER(), ticketWs
.getPROBLEM());
mTickets.put(ticketBO.getTicketNumber(), ticketBO);
}
Die TicketNumber der Tickets eines Users mit sehr vielen Tickets ist für die einzelnen Dokumente nicht eindeutig.
At this time, there are no broadly-adopted specifications for Web services security. As a resultDies wäre so was wie ich oben gesagt habe. Das ist sicher machbar, aber vielleicht nicht interoperabel mit nicht-Java Clients und ausserdem bringt es Performanz-, Programmierungs- und Administrations-Overhead mit sich.
developers can either build up services that do not use these capabilities or can develop
ad-hoc solutions that may lead to interoperability problems.
GetTicketTodos gehört für mich zu GetTicketDetails.
Zumindest bräuchte ich da die Mappings dieser Zahlen zu den Namen der Stati.
Ein Punkt ist natürlich security. Vielleicht muß das für die demo nicht fertig sein.
ZitatZumindest bräuchte ich da die Mappings dieser Zahlen zu den Namen der Stati.
Sollst du bekommen; oder soll ich dann gleich im Klartext ausgeben ?
Ulrich, thanks for the update. I will test early next week and get back to you.
Happy New Years.
Cheers,
Jon
Nein nicht ganz, Axel. Das Prinzip von Help ist das es mehrsprachig ist. Das bedeutet für den Status eben auch, das er nur in verschlüsselter Form vorliegt und zur Laufzeit umgesetzt wird.Die Gui des Webservices wird natürlich auch internationalisiert sein. Fehlermeldungen, Bezeichner in Guis, etc. werden spätestens aber der Beta in einer properties Datei definiert werden können.
Das sollte man hier auch nicht aus den Augen verlieren. Ich denke auch bei den Webservices nicht. Vielleicht müssen wir tatsächlich (irgendwann, nicht gleich) einen Layer mitgeben, der in der definierten Sprache die jeweiligen Bezeichnungen für die Übergebenen Felder (so denn welche vorhanden sind) mitgibt.Ich würd sagen, wir machen dafür eine eigene Funktion in der WSDL Datei, die eine Map (LotusScript = List) runterliefert. Muß aber nicht sofort sein. Vielleicht bleibt auch Status das einzige internationalisierte Feld, das vom Webservice benutzt wird. Jedoch hat das schon mehrere Werte.
Vielleicht bleibt auch Status das einzige internationalisierte Feld, das vom Webservice benutzt wird.
Habe das Gerüst noch einmal geändert:Hi.
Es gibt jetzt eine neue Public Function GetTicketsByStatus ( status As String ) As TicketCollection
Das bietet ein wenig mehr Flexibilität.
Der strittige Punkt...
Vielleicht sollte man doch die Funktionen über mehrere WSDLs verteilen.
BastaEclipse packt es momentan nicht, daraus die stubs zu generieren. Ich weiss nicht warum. Möglicherweise weil die wsdl Datei zu umfangreich ist. Oder aus anderen Gründen. Ich probiere weiter.
wie, mit dem bisschen wird eclipse nicht fertig ??Nein. Momentan nicht. Bitte um Sachlichkeit.
Bitte um Sachlichkeit.kein Problem ...
hmm, traut sich keiner, mir eine neues Ticket via Service zu erstellen ?? :-:
Axel, ich denke momentan an das Projekt und nicht unbedingt so strukturiert, wie du es tust.Wow. Strukturiert. Was ein Wort ;D
ch hoffe der Service hat Sylvester überstanden, weil ich heute noch testen will
was im Webservice als "TICKETNUMBER" bezeichnet wird, immer id benamsen.yo, ändere ich ab
@Ulrich: Du kannst vielleicht die Blackberry Leute fragen, ob die damit etwas anfangen können. Erleichtert vielleicht Verständnis und Arbeit.So wie ich das verstanden habe, haben die eine eigene Entwicklungsumgebung für den MDS; da können die sich die Sachen aus dem WSDL zusammenklicken ...
Vor allem stellt sich bei mir eine supporter/user Verwirrung ein.
Beim Schließen eines Tickets ( auch beim Zuweisen oder Annehmen ) werden ja immer Mails losgetreten...Wer kennt das nicht. computeWithForm() ???
WAIT. Aber bitte nicht vor dem ersten Integrationstest ::)Zitatwas im Webservice als "TICKETNUMBER" bezeichnet wird, immer id benamsen.yo, ändere ich ab
da können die sich die Sachen aus dem WSDL zusammenklicken ...Ich hab ja selber hier quasi eine Klickie-Klickie Umgebung, aber das deckt meist nur 80% ab. Vielleicht hilft lauffähiger code ihnen, die restlichen 20% schnell zu implementieren.
Ich denke, entsprechende Fehlernummern mit einer Beschreibung ( ;D ) reichen aus, um das auf dem BB device entsprechend anzuzeigen ...Ja klar. Ich wollte damit nur sagen, dass Webservices afaik einen eigenen Mechanismus haben, der möglicherweise einfacher ist.
WAIT. Aber bitte nicht vor dem ersten Integrationstest Roll Eyes
Wer kennt das nicht. computeWithForm()sure, aber dann weiß ich trotzdem noch nicht, welche Sprache angezogen werden soll.
ticketV.setStatus(Integer.parseInt(ticketWs.getSTATUS()));
ticketV.setStatusCode(Integer.parseInt(ticketWs.getSTATUS()));
translations_de.properties:
status0=neu
status1=offen
status98=bearbeitet
status99=geschlossen
status0=new
status1=open
status98=resubmited
status99=closed
Ich tendiere dazu, es besser zu finden, dass im Webservice Producer die Funtktion CreateTickets mit CreateTickets(TicketDetails ticketDetails) implementiert würde und nicht CreateTicket(String userName, String Problem).
%REM
#####################################################
Public Function GetTicketDetails ( TicketNumber as String ) As TicketDetails
#####################################################
%END REM
Public Function GetTicketDetails ( TicketNumber as String ) As TicketDetails
On Error Goto ERRHANDLE
EXITPOINT:
exit function <-<<
[TicketPartial:
id: COMM-6KMUUW
statusCode: 0
user: Axel Janssen
problem: p1136155428718
newItem: true]
/*
* Test method for
* 'de.atnotes.help.wsclient.domain.BasicTicketsRepository.createTicket(String,
* String)'
*/
public void testCreateTicket() {
String user = "Axel Janssen";
String problem = "p" + System.currentTimeMillis();
TicketFull ticketFull = TicketFull.getInstanceUsingUserData(null, -1,
user, problem, null);
int ret = -1;
try {
ret = ticketsRep.createTicket(ticketFull);
} catch (EnvironmentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
assertEquals(0, ret);
// try to retrieve newly created ticket from remote database. Must have
// statusCode =0
Map<Integer, Set<TicketPartial>> mTicketsUserOrderedByStatus = null;
try {
mTicketsUserOrderedByStatus = ticketsRep
.getUserTicketsOrderedByStatus(user, true);
} catch (EnvironmentException e) {
e.printStackTrace();
}
Set<TicketPartial> set = mTicketsUserOrderedByStatus.get(0);
Iterator<TicketPartial> it = set.iterator();
TicketPartial ticketPartial = null;
boolean wasFound = false;
while (it.hasNext()) {
ticketPartial = it.next();
if (ticketPartial.getProblem().equals(problem)) {
wasFound = true;
System.out.println(ticketPartial);
break; // while
}
}
assertTrue(wasFound);
}
if (ret == 1) {
throw new EnvironmentException(AppUtils.getValue("exception.general.mandatoryParameterNotSet") +
"ticketFull.user=" + ticketFull.getUser() + "ticketFull.problem=" + ticketFull.getProblem());
}
if (ret == 2) {
throw new EnvironmentException(AppUtils.getValue("exception.environmentException.WebserviceErrorCode"));
}
Axel:GETALLTICKETSBYSUPPORTERR scheint hier bei leeren Collections null zu sein. Ich find das nicht so gut. Wenn es schon ein Objekt gibt, dass als eine Art von Container für den Array dient und dazu noch eine ARRAY.length Variable (wie immer die heisst) hält, dann sollte nicht das ganze Objekt null sein. Das muß irgendwie gehen, dass in GETALLTICKETSBYSUPPORTER ein Array[0] zurückgegeben wird. Das wäre wesentlich besser.
Wenn ein Supporter angegeben wird, der keine Tickets hat ( also nicht in der DB existiert ) springe ich aus der function mit exit function raus.
entsprechend wir das hier als response geliefert; kann man damit was anfangen, sprich im Frontend entsprechend behandeln ??
- <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <soapenv:Body>
<ns1:GETALLTICKETSBYSUPPORTERResponse xmlns:ns1="urn:DefaultNamespace" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</soapenv:Body>
</soapenv:Envelope>
package de.atnotes.help.wsclient.domain;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import de.atnotes.help.wsclient.gui.AppUtils;
import de.atnotes.help.wsclient.ws.TICKET;
import de.atnotes.help.wsclient.ws.TICKETCOLLECTION;
import de.atnotes.help.wsclient.ws.TICKETDETAILS;
import de.atnotes.help.wsclient.ws.TODO;
import de.atnotes.help.wsclient.ws.WsTicketProxy;
/**
* @author Axel
*
*/
public class BasicTicketsRepository implements TicketsRepository {
private WsTicketProxy ticketProxy;
private Map<String, TicketPartial> mTicketsSuporter;
private Map<String, TicketPartial> mTicketsUser;
private Map<String, TicketFull> mTicketsFull;
private Map<Integer, Set<TicketPartial>> userTicketsOrderedByStatus;
private Map<Integer, Set<TicketPartial>> suporterTicketsOrderedByStatus;
private Map<String, Set<TicketPartial>> suporterTicketsOrderedByUser;
public BasicTicketsRepository() {
}
/**
* to use in view
*
* @throws EnvironmentException
*/
public Map<Integer, Set<TicketPartial>> getUserTicketsOrderedByStatus(
String user, boolean retrieveRemotely) throws EnvironmentException {
// if null then retrieve allways from remote database
if (userTicketsOrderedByStatus == null)
retrieveRemotely = true;
if (retrieveRemotely) {
retrieveAllTicketsByUser(user);
if (userTicketsOrderedByStatus == null)
userTicketsOrderedByStatus = new HashMap<Integer, Set<TicketPartial>>();
else {
userTicketsOrderedByStatus.clear();
}
for (TicketPartial ticketPartial : mTicketsUser.values()) {
Set<TicketPartial> sTicketsPartial = userTicketsOrderedByStatus
.get(ticketPartial.getStatusCode());
if (sTicketsPartial == null) {
sTicketsPartial = new HashSet<TicketPartial>();
}
sTicketsPartial.add(ticketPartial);
userTicketsOrderedByStatus.put(ticketPartial.getStatusCode(),
sTicketsPartial);
}
}
return userTicketsOrderedByStatus;
}
/**
* to use in view
*
* @throws EnvironmentException
*/
public Map<Integer, Set<TicketPartial>> getSuporterTicketsOrderedByStatus(
String user, boolean retrieveRemotely) throws EnvironmentException {
// if null then retrieve allways from remote database
if (suporterTicketsOrderedByStatus == null)
retrieveRemotely = true;
if (retrieveRemotely) {
retrieveAllTicketsBySupporter(user);
if (suporterTicketsOrderedByStatus == null)
suporterTicketsOrderedByStatus = new HashMap<Integer, Set<TicketPartial>>();
else {
suporterTicketsOrderedByStatus.clear();
}
for (TicketPartial ticketPartial : mTicketsSuporter.values()) {
Set<TicketPartial> sTicketsPartial = suporterTicketsOrderedByStatus
.get(ticketPartial.getStatusCode());
if (sTicketsPartial == null) {
sTicketsPartial = new HashSet<TicketPartial>();
}
sTicketsPartial.add(ticketPartial);
suporterTicketsOrderedByStatus.put(ticketPartial
.getStatusCode(), sTicketsPartial);
}
}
return suporterTicketsOrderedByStatus;
}
/**
* to use in view
*/
public Map<String, Set<TicketPartial>> getSuporterTicketsOrderedByUser(
String user, boolean retrieveRemotely) throws EnvironmentException {
// if null then retrieve allways from remote database
if (suporterTicketsOrderedByUser == null)
retrieveRemotely = true;
if (retrieveRemotely) {
retrieveAllTicketsBySupporter(user);
if (suporterTicketsOrderedByUser == null)
suporterTicketsOrderedByUser = new HashMap<String, Set<TicketPartial>>();
else {
suporterTicketsOrderedByUser.clear();
}
for (TicketPartial ticketPartial : mTicketsSuporter.values()) {
Set<TicketPartial> sTicketsPartial = suporterTicketsOrderedByUser
.get(ticketPartial.getUser());
if (sTicketsPartial == null) {
sTicketsPartial = new HashSet<TicketPartial>();
}
sTicketsPartial.add(ticketPartial);
suporterTicketsOrderedByUser.put(ticketPartial.getUser(),
sTicketsPartial);
}
}
return suporterTicketsOrderedByUser;
}
/**
* calls Webservices to get a full ticket from the webservice to show in a
* form.
*
*
* @param String
* idTicket the id of the full ticket to retrieve.
*
* @return TicketFull
* @throws EnvironmentException
* called when webservice doesn't work or it returns an
* errorcode.
*/
public TicketFull getFullTicketById(String idTicket)
throws EnvironmentException {
TICKETDETAILS ticketFullWs = null;
try {
ticketFullWs = getTicketProxy().GETTICKETDETAILS(idTicket);
/*
* ERRORCODE !!! if (ticketF.getERRORCODE() != 0) throw new
* EnvironmentException( AppUtils
* .getValue("exception.environmentException.WebserviceErrorCode") +
* ticketColWs.getERRORCODE());
*/
} catch (RemoteException e) {
throw new EnvironmentException(
AppUtils
.getValue("exception.environmentException.ConnectionWithWebServiceFailed"),
e);
}
TODO[] toDosWs = ticketFullWs.getASSOCIATEDTODO().getTODOS();
List<TodoFull> todosFull = new ArrayList<TodoFull>();
if (toDosWs != null) {
for (TODO toDoWs : toDosWs) {
TodoFull todoFull = TodoFull
.getInstanceUsingWebserviceData(toDoWs);
todosFull.add(todoFull);
}
}
return TicketFull.getInstanceUsingWebserviceData(ticketFullWs,
todosFull);
}
/*
* (non-Javadoc)
*
* @see de.atnotes.help.goodies.bonus.wsclient.domain.TicketRepository#assignTicket(java.lang.String,
* java.lang.String)
*/
public int assignTicket(String id, String newSupporter)
throws EnvironmentException {
// TODO muss noch überarbeitet werden.
int ret = -1;
try {
ret = getTicketProxy().ASSIGNTICKET(id, newSupporter);
} catch (RemoteException e) {
throw new EnvironmentException(
AppUtils
.getValue("exception.environmentException.ConnectionWithWebServiceFailed"),
e);
}
return ret;
}
/*
* (non-Javadoc)
*
* @see de.atnotes.help.goodies.bonus.wsclient.domain.TicketRepository#closeTicket(java.lang.String)
*/
public int closeTicket(String id) throws EnvironmentException {
int ret = -1;
try {
ret = getTicketProxy().CLOSETICKET(id);
} catch (RemoteException e) {
throw new EnvironmentException(
AppUtils
.getValue("exception.environmentException.ConnectionWithWebServiceFailed"),
e);
}
return ret;
}
public int createTicket(TicketFull ticketFull) throws EnvironmentException {
short ret = -1;
try {
ret = getTicketProxy().CREATETICKET(ticketFull.getUser().trim(),
ticketFull.getProblem().trim());
if (ret == 1) {
throw new EnvironmentException(AppUtils
.getValue("exception.general.mandatoryParameterNotSet")
+ "ticketFull.user="
+ ticketFull.getUser()
+ "ticketFull.problem=" + ticketFull.getProblem());
}
if (ret == 2) {
throw new EnvironmentException(
AppUtils
.getValue("exception.environmentException.WebserviceErrorCode"));
}
} catch (RemoteException e) {
throw new EnvironmentException(
AppUtils
.getValue("exception.environmentException.ConnectionWithWebServiceFailed"),
e);
}
return ret;
}
/**
* calls Webservices to get partial tickets from a webservice. Can be used
* to implement a cache later
*
* @param mTicketsSuporter
* map of existing lands in business layer
* @return
* @throws EnvironmentException
* called when webservice doesn't work or it returns an
* errorcode.
*/
void retrieveAllTicketsBySupporter(String suporter)
throws EnvironmentException {
TICKET[] ticketsWs = new TICKET[0];
try {
TICKETCOLLECTION ticketColWs = getTicketProxy()
.GETALLTICKETSBYSUPPORTER(suporter);
if (ticketColWs.getERRORCODE() != 0)
throw new EnvironmentException(
AppUtils
.getValue("exception.environmentException.WebserviceErrorCode")
+ ticketColWs.getERRORCODE());
ticketsWs = ticketColWs.getTICKETS();
} catch (RemoteException rex) {
throw new EnvironmentException(
AppUtils
.getValue("exception.environmentException.ConnectionWithWebServiceFailed"),
rex);
}
mTicketsSuporter = generateTicketsPartialFromWsData(ticketsWs,
mTicketsSuporter);
}
/**
* calls Webservices to get a map of partial tickets from a webservice. Can
* be used to implement a cache later
*
* @param mTicketsSuporter
* map of existing lands in business layer
* @return Map <String, TicketPartial>
* @throws EnvironmentException
* called when webservice doesn't work or it returns an
* errorcode.
*/
void retrieveAllTicketsByUser(String user) throws EnvironmentException {
TICKET[] ticketsWs = new TICKET[0];
try {
TICKETCOLLECTION ticketColWs = getTicketProxy()
.GETALLTICKETSBYUSER(user);
if (ticketColWs.getERRORCODE() != 0)
throw new EnvironmentException(
AppUtils
.getValue("exception.environmentException.WebserviceErrorCode")
+ ticketColWs.getERRORCODE());
ticketsWs = ticketColWs.getTICKETS();
} catch (RemoteException e) {
throw new EnvironmentException(
AppUtils
.getValue("exception.environmentException.ConnectionWithWebServiceFailed"),
e);
}
mTicketsUser = generateTicketsPartialFromWsData(ticketsWs, mTicketsUser);
}
/**
* helper function used by getAllTicketsByUser and getAllTicketsBySupporter
*/
private Map<String, TicketPartial> generateTicketsPartialFromWsData(
TICKET[] ticketsWs, Map<String, TicketPartial> mTicketsPartial) {
// if (mTicketsPartial == null)
mTicketsPartial = new HashMap<String, TicketPartial>();
for (TicketPartial ticketBO : mTicketsPartial.values()) {
ticketBO.setNewItem(false);
}
for (TICKET ticketWs : ticketsWs) {
TicketPartial ticketV = null;
if ((ticketV = mTicketsPartial.get(ticketWs.getTICKETNUMBER())) != null) {
System.out.println("old.ticket");
ticketV.setStatusCode(ticketWs.getSTATUS());
ticketV.setUser(ticketWs.getUSER());
ticketV.setProblem(ticketWs.getPROBLEM());
} else {
ticketV = TicketPartial
.getInstanceUsingWebserviceData(ticketWs);
}
mTicketsPartial.put(ticketV.getId(), ticketV);
}
return mTicketsPartial;
}
/**
* @return Returns the ticketProxy.
*/
private WsTicketProxy getTicketProxy() {
if (ticketProxy == null)
ticketProxy = new WsTicketProxy();
return ticketProxy;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
Die Funktion getTicketDetails ist nicht implementiertRichtig, ebenso wie die AssignTicket; da existiert bisher nur ein func stub ...
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object.Hab unseren Proxy bereits eingetragen, klappt aber noch nicht...
org.xml.sax.SAXException: Bad types (class java.lang.String -> short)
ist die Testdatenbank noch online?Ich kann dir schicken, was ich bis jetzt fertig habe. Will das nicht unbedingt hier posten, weil das wg. der jars im Projekt ziemlich groß ist.
Todo ist weg.Du meinst das ToDo bei den Details ? Ja, ich war gestern zu blöd, ein array zu (re)-dimmen ... baue ich abe morgen wieder ein.
Haben eigentlich die Blackberry Leute etwas gesagt?
Warum kann ich nicht einfach ein Datum hochschicken und du sendest nur Tickets runter, die nach diesem Datum zuletzt geändert wurden.
Könnte es daran iegen, daß eine solche Funktion bisher noch nicht existiert ??Ja klar. Ich wollte nur andeuten, dass dies absolut Sinn machen würde. ;)
wenn der Client noch ein paar Tage am Laufen bleibt.
Läuft auch CORBA bei dir?
Ansonsten hast du ja sicher mein Selbstgespräch im Java-Bereich http://atnotes.de/index.php?topic=28027.0 mitverfolgt Azn
Falls ich den RCP noch etwas hübscher mache werde ich ihn mal komplett posten...
Ulrich,
You will hear back from me today on this.
Thanks,
Jon
Ulrich, so far so good. I was able to load the lss into a web service just fine. The web service imported into a MDS Studio project without problems. The final stage is to test the functionality through the service from our MDS connection service. Unfortunately, the service appears to be down in our lab right now. I have our admin looking at the problem but this may not be working again until Monday. Once up, I will complete the tests and get back to you with the results. I am suspecting that the services will be consumed by the client without problems.
Have a good weekend and you will hear from me by Monday or sooner. Thanks again for your work on this project. Assuming this all comes together on time, it will be a great showcase of your application and our platform capabilities.
BTW, how much effort was put into coding the scripts so far?
Regards,
Jon
I know a lot of people who work day by day with different collaboration tools (in ex. MSFT products), but only Notes flexibility give them needed satisfaction.haha. Es fühlt sich gut an, der erste von 100.000 zu sein.
Zitat
Ulrich, so far so good. I was able to load the lss into a web service just fine. The web service imported into a MDS Studio project without problems. The final stage is to test the functionality through the service from our MDS connection service. Unfortunately, the service appears to be down in our lab right now. I have our admin looking at the problem but this may not be working again until Monday. Once up, I will complete the tests and get back to you with the results. I am suspecting that the services will be consumed by the client without problems.
Have a good weekend and you will hear from me by Monday or sooner. Thanks again for your work on this project. Assuming this all comes together on time, it will be a great showcase of your application and our platform capabilities.
BTW, how much effort was put into coding the scripts so far?
Regards,
Jon
Nothing gets by you. We have been working on our domino and BES servers today. We have success!! I was able to successfully run most of the services through our BlackBerry runtime connecting to your web services! Create Ticket, Request by number, request by user, etc. We will need to adjust the services some to allow for more data to be returned when appropriate. Next steps:
1. I will send along some screen shots and descriptions so you can visualize the application and process.
2. Tomorrow I will be speaking with the rest of the team on next steps. There are a few options for building out the clients:
1) Our team builds out the front end using our MDS 4.1 Studio IDE application and your team tweaks the backend web service
2) Our team builds front end and takes care of back end tweaks
3) Your team takes full ownership and learns the Studio product and builds out front end
If you all are up for the challenge and would like to work on the BlackBerry client side (drag and drop plus very lightweight javascripting), we will support your setup, training and configuration.
Let me know.
Cheers,
Jon
@Axel:
Danke für die Anleitung; damit habe ich es geschafft, den Client zu installieren. Der Code sieht recht gut strukturiert aus, auch wenn ich noch nicht alles verstehe ...
Das hab ich auch mal geglaubt, mittlerweile nicht mehr. Bin mir aber nicht sicher.vielleicht muss ich vorher Tomcat installieren?? Ich probier das mal
Gut zu wissen. Man muss TomCat lokal installiert haben, um den Wizard zu nutzen (und um dort die Nutzung des lokalen TomCats abzuwählen)
Abhijit,
in case you have not tried it yet, the Internet Preferences page (Window ->
Preferences -> Internet) may be of help. You can use this preference page to
configure the Eclipse JRE to tunnel thru an HTTP proxy firewall.
Cheers - CB.
public DominoSoapBindingStub(java.net.URL endpointURL,
javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {
this(service);
super.cachedEndpoint = endpointURL;
// manual proxy
System.setProperty("http.proxyHost", "meinproxy.server");
System.setProperty("http.proxyPort", "1234");
// end proxy
}
verdammte schxxxe, es geht!Ich find das ziemlich ehrlichgesagt ziemlich bescheiden, dass man es offensichtlich nicht im Wizzard von Eclipse RTP 1.0 setzen kann. Grundsätzlichkeiten wie authentifizierende Proxies sollten wirklich berücksichtigt werden. Ort? Vermutlich die Daten in eine .properties-Datei in das Projekt tun?
Des Rätsels Lösung war wie immer einfach, wenn man sie kennt:
Ich habe meinen Proxy nun explizit gesetzt, und zwar hier (ist sicher noch nicht der ideale Ort dafür)
Ulrich, update from our team meeting. We are going to use the Help app in at least two of our hands-on training sessions at Lotusphere on Sunday and Monday. We have another presentation session on Wed where it may get highlighted. We have several booths on the showcase floor that will be demoing apps, and the App may make the these booth pods as well. I will give you materials from the training sessions, including the training guide and MDS Studio project files, that you can throw up on openntf if you like.
per Wizard aber wie immer gibt es irgendwelche doppelten Pfadeinträge (von Axis) bei mir.Die entsprechenden jars in das lib Verzeichnis des Projekts kopieren und in der Konfiguration des Projekts die Libs von da ziehen. Zur Zeit wird bei den axis - libs auf Libraries innerhalb des plug-in Verzeichnisses von WTP 1.0 verwiesen (guck dir .classpath an. Dann wird das klar).
MDS Studio ist doch kostenpflichtig, oder?Du kannst dir eine Einzelplatzversion + Lizenzschlüssel kostenlos bei RIM runterladen.
Habe ich mich gestern mit Thomas schon drüber unterhalten. Dürfte aber mit dem SWING Client von Axel oder dem RPC Client von Mark machbar sein.Leider so nicht. Pocket PC unterstützt nicht das vollständige Java 2 Standard Edition (J2SE). Man müßte den Client dann nochmal neu mit einer speziellen Java MObile Version programmieren: