JMP106: Introduction to Java for LotusScript ProgrammersSteve Brown, Iris Associates Gary Devendorf, Lotus Development This Presentation Prerequisite LotusScript After this Presentation Java basics Domino Java Classes Domino Java agent Domino JSP Recommend Java programming course OO design course Agenda Why Java ? Basic Java concepts Syntax / semantics Class methods Class packages, jar files Accessing Domino via Java Domino Objects Agents, Applications, Applets, Servlets, JSPs Demos throughout Java The Java programming language is a modern, evolutionary computing language that combines an elegant language design with powerful features that were previously available primarily in specialty languages. In addition to the core language components, Java platform software distributions include many powerful, supporting software libraries for tasks such as database, network, and graphical user interface programming. .LotusScript LotusScript is an embedded. BASIC scripting language with a powerful set of language extensions that enable object-oriented application development within and across Lotus products. LotusScript's Future LotusScript is going nowhere! Gary Devendorf .1998 . Why Java ? Java? Why Advantages Cross Platform Nonproprietary Richer class library Multithreading Code reuse across Agents. Applets. Applications. Servlets Integrates with 3rd party Java applications Object Oriented Language Features advanced architecture inheritance design patterns . etc.Why Java ? Some Backend Classes are only Java String Handling abilities are superior to LS Utility Classes for Web. Scalable Data Structures no arbitrary limits Collection Classes .Vector. Hashtable. etc. ListServers. Networking and XML JDBC to integrate with SQL data Everyone today has a Java API Help is everywhere : Books. Lots of IDEs to choose from . usergroups. Ok. How about URL encoding and unencoding ? . Give me one good example of why I would choose Java. URL Encoding LS Call an @function cmd = {@URLEncode("Platform".myLink(0) + {")} encURL = Evaluate( cmd ) ************************************************************* Encode a Link in LotusScript using a reentrant function function URLEncode(query As String) As String Dim c As Integer Dim x As Integer For x = 1 To Len(query) c = Asc(Right(Left(query. "} + doc.x).1)) If (c < 48) Or (c > 57 And c < 65) Or (c > 90 And c < 97) Or (c > 122) Then URLEncode = URLEncode & "%" & Hex(c) Else URLEncode = URLEncode & Chr(c) End If Next End Function . Encode a URL in Java String encURL = URLEncoder. .getItemValueString(myLink).encode(doc. g. *.exe Operating System .g.g. *.g. myprog.Traditional Programming Environment Class Libraries (e.obj O/S Specific Machine Code Your Machine at Runtime Executable e.C++ Objects e. myprog.exe Source Files e. *.lib) Compiler Linker Executable e.g. Java Environment Class Packages Source Files Compiler (analogy .class *.script libraries) Java ByteCode Files *.java Runtime Java Virtual Machine (JVM) Win32 JavaOs Solaris Mac Others "Write Once Run Anywhere" . class 4.x & Core Classes Notes Client API OS Forms execute Applets Agents imported Java Classes code Java directly compiled in Designer RPC .5 / 5.1.jar) JVM 1.6 / 5.0 .0 Notes Java Classes (Notes.6.Notes Client Notes Form 12 11 1 10 2 9 3 8 7 6 5 4 Notes Agent Applet *.NSF Domino Server Your Machine Notes 4. class *.Domino Server Server Notes Agent Servlets *.0 .NSF Domino 4.1. Agent Manager Imported Java Classes Written Java in Agent compiled in Designer Servlets Domino Servlet Engine Use Domino Classes ** RPC .jar) JVM 1.x & Core Classes Notes Client API OS Agents execute HTTP.6/5.class Notes Java Classes (Notes. 6 Java language binding to backend CAPI Agents.1.1. Applets JVM 1.06) New and enhanced classes Agents. Servlets.0 JVM 1.1 Enhanced in 5.8 (5. stand-alone apps*.Domino Java Classes Introduced in 4. Applets* retrieval of Session object different . Servlets*. stand-alone apps. JSP: NotesFactory.getSession() Applet: AppletBase.Session please! Agent: AgentBase. Servlet.createSession() .openSession() Application. In my environment the problem occurs consistently after 10331 documents.pid 0000035C Handles used so far 16415. I include the agent to reproduce the problem here since it is so short. Currently none. and Poing! every 10 000 documents. . It runs in an endless loop creating documents.Bug Report Brief Description:* Java agent crashes when creating a large number of documents ------------------------------------------------------------------------------------------------------------------Steps to Reproduce: If you create a Java agent to create large number of documents in a database. Work Around: None. apart from writing the script in LotusScript Impact: Potentially large. It prints Ping! to the console every 1000 documents. the agent will fail with error message: MemAlloc: OUT OF PRIVATE HANDLES! -. if (a % 1000 == 0 ) System.save()) System. if (a % 10000 == 0 ) System.createDocument(). a++.println("Unable to save document"). doc."Entry").4").out.getCurrentDatabase().out.appendItemValue("Form". while (true) { doc = db.2.out. "1. if (!doc.Bug Report Code Database db = agentContext. doc. } .println("Ping!").appendItemValue("Address".println("Poing!").3. Memory Management In LotusScript you don't worry about it. In Java you don't get Memory leaks but you can get yourself in to trouble with "unCollected" memory. in C you do. Java has a Garbage Collector that runs when Java thinks it should. But Java can only see the wrappers not the code under them. . Notes 4.dll ) .6/5.0 Java Notes Classes Java LotusScript Agents Events Agents* Applications Servlets Applets LotusScript Binding OLE Java Binding COM Notes Backend "C" API ( nlsxbe. The part that Java can see is the visible part of the iceberg.Like an Iceberg Actual memory usage is like an iceberg. Your application is the Titanic if you are not careful . The 7/8 under the water part is the back end classes. The answer is : Recycle() use doc.recycle() after .doc. .save(). stopped your script after 120K docs. Loops enumerating documents or items are good candidates for recycling . call recycle only after all threads exit. try recycle but adhere to the following guidelines: Recycle an object only if it is no longer needed. Recycling a parent recycles all the children. In Session. If you appear to have memory problems.Recycle() Garbage collection has no effect on Domino objects unless you first explicitly recycle them. Recycle an object in the same thread in which it is created. net www. .Recycle().Suggestion Go to : www.net and do a search on recycle.notes.looseleaf. . NotesDbDirectory NotesInternational create . NotesDateTime NotesNewsletter NotesName NotesLog NotesDateRange NotesTimer NotesRichTextStyle NotesRichTextParagraphStyle NotesRichTextTab Database NotesUIDocument Forms ACL Agents Outline AllDocuments FTSearch Replication NotesOutline Search NotesReplication getView Views NotesView NotesForm NotesACL NotesAgent NotesOutlineEntry NotesDocumentCollection NotesACLEntry NotesViewColumn NotesViewNavigator NotesViewEntryCollection NotesDocument NotesViewEntry NotesItem NotesRichTextItem NotesEmbeddedObject inherits Contains New Method NotesRegistration ...R5 LotusScript FRONT END CLASSES NotesUIWorkspace NotesUIDatabase NotesUIView BACK END CLASSES NotesSession get .. create .. DbDirectory DateTime DateRange International Name Log AgentContext Newsletter Registration RichTextStyle RichTextParagraphStyle RichTextTab createDocument Database getForms getACL getAgents getAllDocuments getReplication FTSearch Search ACL Agent Replication getOutline Outline getView getViews View Form OutlineEntry NotesDocumentCollection NotesACLEntry ViewColumn ViewNavigator ViewEntryCollection Document ViewEntry Item RichTextItem EmbeddedObject inherits NO FRONT END CLASSES NO NEW CLASS METHOD NO DIRECT PROPERTY ACCESS NO NOTESTIMER CLASS ..R5 Java getAgentContext getDocumentContext BACK END CLASSES Session get ... AgentContext() Class Session Class Property accessing methods getAddressBooks isOnServer getNotesVersion getPlatform getAgentContext getUserName getUserNameObject getCommonUserName getInternational AgentContext Class Property accessing Methods getCurrentAgent ** getCurrentDatabase ** getDocumentContext getEffectiveUserName getLastExitStatus getLastRun getSavedData ** getUnprocessedDocuments Methods createDateRange createDateTime createLog createName createNewsletter createRegistration createRichTextStyle ** evaluate freeTimeSearch getDatabase getDbDirectory getEnvironmentString getEnvironmentValue setEnvironmentVar openURLDatabase Methods unprocessedFTSearch unprocessedSearch updateProcessedDoc . Domino Java Classes All properties are accessed via methods is or has properties are accessed via the same method name doc.title is modified via db.getTitle( ) db.setTitle( ) .title is accessed via db.isNewNote is accessed via doc.isNewNote( ) remaining properties are accessed via get or set prefixed to the property name as a method db. doc.subject or doc.subject(0) Single value methods per datatype doc.e.getItemValueString( "fname" ) doc.getItemValue( "fname" ) returns a vector ( ~ dynamic array ) .getItemValueDouble( "fname" ) Multi value methods doc.getItemValueInteger( "fname" ) doc.Accessing Domino Data NO extended notation method i. . You can represent real world objects with these user-defined classes.Class The class construct supports the creation of user-defined data types. that represent both data and the methods used to manipulate the data. .bark().println("Woof").Dog class Dog { void bark() { System.out. } } MyAgent code: Dog Lassie = new Dog(). Lassie. v2 . . System. } } private instance properties constructor public instance method private instance method Sample Code Demo d = new Demo( 20. 10 ). int v2 ) { v1 = v1. } private int getMaximum( ) { if ( v1>v2) return v1.Basic Java Class public class Demo { private int v1. } public int getMax( ) { return getMaximum( ).println ( d. v2 = v2.getMax( ) ). public Demo( int v1. else return v2.out. getNextDocument(doc). while ( doc != null ) { // code doc = thisview. } .Object Reference Variables LotusScript Dim doc as NotesDocument set doc = view.getFirstDocument( ).getNextDocument(doc) wend Java Document doc = thisview.getfirstdocument while Not( doc Is Nothing ) ' code set doc = thisview. Inheritance In LotusScript the NotesRichTextItem class inherits properties and methods of the NotesItem Class This is called Inheritance or subclassing In Java inheritance is represented by the extends keyword class myapplet extends Applet mandatory for Applet classes class myagent extends AgentBase mandatory for Domino Java Agent classes . Database db = ac. AgentContext ac = s.Simple Java Agent BACK END CLASSES Session import lotus.getCurrentDatabase( ) System.* public class Demo1 extends AgentBase { getAgentContext getDatabase AgentContext public void NotesMain( ) { getCurrentDatabase Database LotusScript Dim s as new NotesSession Dim db as NotesDatabase Set db = s.printStackTrace().Title ) try { Session s = getSession( ). } catch( NotesException e ) { e.out.CurrentDatabase print( db.getTitle()).domino.getAgentContext( ). } } } Instance method of AgentBase Class .println(db. Loading a Java Agent Create instance of Java class Create and initialize AgentBase class Call the NotesMain() method . pw.io.PrintWriter. Output to Web Browser: import java. . PrintWriter pw = getAgentOutput(). dbgMsg ("Some helpful text").AgentBase Debugging Methods Output to console or Notes Log: setDebug (boolean debug).print("Output Text to Browser"). getAgentContext( ).text).getCurrentDatabase( ).* public class Demo1 extends AgentBase { public void NotesMain( ) { try { Session s = getSession( ). } Demo1. Domino methods throw exceptions ( NotesException Object) } } AgentContext ac = s.println(e.java .id + " " + e.printStackTrace(). Database db = ac.Exception Handling import lotus.out. } catch( NotesException e ) { System. e.domino. Exception Handling Exception throwing methods contained in a try block All Domino methods throw exceptions send exception object to runtime system Catching an Exception Runtime finds a routine to handle exception defined by catch block looks in current and calling methods program terminates if unsuccessful Java insists that you do it right ! . Java Primitive Datatypes LotusScript Java byte short int float double N/A N/A N/A char boolean Bytes 1 2 4 4 8 8 integer long single double currency string variant 2 (unicode) true or false . explicit value2 = 100 value3 = 100 int value1 = 100.CASE SENSITIVE . initial = 'J' .NO implicit . value2 . SEMI.COLONS .Java Variables LotusScript Dim value1 as integer. char initial .implicit declarations . value2 = 100 .explicit declarations .default values Java .NO default values . value 2 as integer declarations . . The Java compiler is complaining about the line highlighted in red on the next slide.Initializing variables Another customer report for Gary. x =1.Session session = getSession(). doc. Variable cRate may not have been initialized. Double cRate. } Database db=ac.replaceItemValue("Form".valueOf(sRate).getAgentContext(). AgentContext ac = session.getCurrentDatabase().createDocument(). Document doc = db.983". cRate = Double. doc. . int x. if (x==1){ sRate = "345."Test").true).cRate). String sRate.replaceItemValue("Value". doc.save(true. doc.cRate).This will compile Session session = getSession().save(true.valueOf(sRate). Double cRate = 0. AgentContext ac = session. x =1.983". doc. Document doc = db."Test"). if (x==1){ sRate = "345. cRate = Double. .createDocument().true).replaceItemValue("Value". int x. doc. String sRate = "0". } Database db=ac.getAgentContext().getCurrentDatabase().replaceItemValue("Form". Comparison / Logical Operators LotusScript = or and Java == || && != . else found = false. String age. j. <. j.IF Statement LotusScript Dim i. j=0. if (i ==10 || j == 30) { age = "Young". found = true. } else if (i == 20) found = true. >= same . <=. i=0. found as Integer if i=10 or j=30 then age = "Young" found = True elseif i=20 then found = True else found = False end if Java short i . >. boolean found. break. break. case 70 : person = "Old".Loops and Select LotusScript for ( i = 1 to 10 ) ' statements Next i Java for ( i = 1. i <= 10. i++ ) { // statements with . } while ( found = True ) ' statements wend do ' statements Loop while (found = True ) Select Case age Case 20 : person = "young" Case 70 : person = "old" Case Else : person = "dead" end select . } while ( found == true ) { // statements with . default : person = "dead". } do { // statements } while (found == true ) switch ( age ) { case 20 : person = "young". 34 ) ( static methods ) .min ( 44.Class Uses Instantiating objects Group common Methods and Properties never instantiated referenced via Class Name class methods and class properties Math Class Math.round ( 2. 90 ) Math.max ( 100.78 ) Class Properties Math. Math.E Math.PI.abs( 2. 999 ) Class Methods Math. int myValue = 50. Capitalization Matters !!!! b=a } System.Stump Gary x = 100 .println("The value of b is:" + b).out. semicolons semicolons MyValue = x. int a = 0. ! . if ( x == 100) { Semicolons. b = ? int x = 100. out.out.println("The value of b is:" + b). int b = 50. b = a. System. int a = 0. } System. if ( x == 100) { // Always use braces a = x. . b = a. if ( x == 100) a = x.println("The value of b is:" + b). int b = 50.What is the value of "b" if x is 45 int a = 0. } System. .println("The value of a is" + a).out. int a = 0.What is the value of "a" if x is 100 int a = 0.out. If 100 == x // "=" is not the same as "==" { a = 300. If x = 100 { a = 300.println("The value of a is" + a). } System. System.background agents Java Debugger Console .PrintStream Class Object The above java code prints to standard output Server Console.println("Hello World"). Notes Log .System Class Standard I/O Class Cannot be instantiated.foreground agents . PrintStream Instance Method System Class System Class Property .out. Integer. . Double i = new Double( "10" ). float. int. Long Class Classes for primitive datatypes double.Double. Float i = new Float(12. Float. long methods to manipulate primitives creation via passing primitive in constructor Integer i = new Integer( 10 ).89). replaceItemValue ( "fieldname". Float.toString(). // returns int value class methods Integer.toString( int d ) converts native data to String Domino Objects Some methods require Objects document.Double. Integer.3 ) "Becky Gibson" . // returns String representation i.valueof( String s ) returns Integer object Integer. Long Class instance methods to manipulate native data i.intValue(). object ) new Double( 12. toUpperCase. trim. Comparison via instance methods s..Pay attention this is important ! String Class NO string datatype but a String class Assignment via "=" String s = "hello world".valueOf ( primitives or objects ) .equalsIgnoreCase("Hello World") returns true Instance methods replace. etc .equals("HELLO WORLD") returns false s. CIass methods String. toLowerCase. You typically use string buffers for constructing character data dynamically. String and StringBuffer. The String class provides for strings whose value will not change. that store and manipulate strings-character data consisting of more than one character. . The StringBuffer class provides for strings that will be modified. you use string buffers when you know that the value of the character data will change.Why Two String Classes ? The Java platform provides two classes. 1).println(dest. } } . int len = palindrome. i--) { dest. This program uses both a string and a string buffer.Strings Demo Reverse the characters of a string. public class StringsDemo { public static void main(String[] args) { String palindrome = "Dot saw I was Tod". } System.out. StringBuffer dest = new StringBuffer(len). for (int i = (len .toString()).append(palindrome.charAt(i)). i >= 0.length(). Strings Demo Output The output from this program is: doT saw I was toD . e. SalesPerson = UserName ) Sales Report 1 SalesPerson : SalesPerson Total Sales : TotalSales .Demo : Report 1 Create a report document of Sales by the person running the agent (i. out. . myVector.addElement( new Integer(30) ).addElement( new Integer(10) ).addElement( new Integer(40) ).size() ). myVector.util.Vector.util. myVector. Vector myVector = new Vector( ).println( "elements : " + myVector.addElement( new Integer(20) ).Vector. System.Vectors ( dynamic arrays ) import java. Vector contains OBJECTS automatically increase in size on add LotusScript myArray( ) as Integer REDIM myArray(2) myArray(0) = 10 myArray(1) = 20 myArray(2) = 30 REDIM PRESERVE myArray(3) myArray(3) = 40 Java import java. myVector. Store each double sales amount value for customer create a Vector of Double objects Sales Report 2 SalesPerson : Customer Customers Sales Report 2 SalesPerson : Doctor Notes SalesPerson Sales Sales Customer Sales Total Sales : TotalSales Mary Smith Mary Smith Gary Martin Total Sales : 1000.90 6456.appendToTextList( String s ).00 2000.90 .00 3456.Demo : Report 2 Store customer values from all matching documents in Customers multivalue text field item. Class Packages Class Packages Class Packages Source Files Compiler (analogy .class *.java .script libraries) Java ByteCode Files *. java c:\work\ibm\input\Window1.class extension not required import Window1 import Window2 MyApp.class c:\work\ibm\input\Window2.Classes and Classpath The Import statement is used to find class files at compile and runtime .class CLASSPATH Environment variable searched at COMPILE / RUNTIME for imported classes Contains Imported Class filepaths CLASSPATH = c:\work\ibm\input . ..java COMPILING CLASSPATH = C:\NOTES .. Database.java COMPILE Class Packages Class Packages Database.. MyApp. .Classes of the same context can be grouped together Referenced easily as a whole Simplifies CLASSPATH This container is called a Package Relates to directory path of the class file defined at the top of source file via Package name package lotus. .class c:\notes\lotus\domino\ import lotus.* .domino .domino. util useful utility classes java.net network related classes java.applet applet classes Not Applicable for Java Agents java.awt ** windowing and graphic classes .io file input and output classes java.Core Java Packages Core Java Packages java.lang Java language related classes default package automatically imported java. JAR .class The path + jar filename is placed in the Classpath compiling / executing outside Domino SET CLASSPATH= .C:\NOTES\NOTES.JAR \lotus\domino\Session.class \lotus\domino\Document.class \lotus\domino\Database.Archive Files Files Archive Packages can be saved to zip or JAR file Java ARchive File Domino Java classes lotus.domino package Notes.jar ( installed Notes directory ) NOTES.class \lotus\domino\View.. .jar Notes..jar. rt.Domino Internal Classpath Domino has internal CLASSPATH Find Domino & JVM classes @ compile / runtime notes.. icsclass.jar Classes that access 'C' must be on disk .jar.c:\jdk\work\toolkit.ini variable extends internal CLASSPATH Add your own Classes and Jar files JavaUserClasses= .jar i18n. A JSP is compiled into a Servlet the first time it is accessed.What is a JSP ? JavaServer Pages (JSP) technology provides a simplified. JSPs run on a server and work with requests and responses. . fast way to create web pages that display dynamically-generated content. The response is usually in the form of an HTML document but can also be XML. They are HTML documents that include special tags and Java. jsp extension ? Web Server hands the request off to Web App Server The JSP source code turned into Servlet source code The Servlet source code is compiled and run HTML response is sent back to the Web Server and then to the browser The compiled servlet remains in memory .What happens when my browser hits a URL with a . Using JSPs with Domino Domino does not currently provide integrated JSP support Use a third party JSP container Tomcat.jsp?user Name=Becky . WebSphere Install JSP container Run Domino & JSP container For JSP support access JSP container directly http://bgibsontpad:8080/Hello. "Garnet" Code name for the new web programming model in the next release of Domino (Rnext) Garnet consists of: A Standard Servlet/JSP container A Custom tag library and Java classes over Domino Data "Template" applications Third Party Tool integration . Custom Tag Libraries JSP 1.1 .Custom Tags Domino Custom Tags Session Database View DocumentCollection Loop Mail Message . Simple.JSP . report1.jsp Let's take those LotusScript/Java reports and turn them into JSPs. . SQLdemo.jsp Ever want to build an application that could interact with SQL data ? . sinitThread(). password]). NotesThread.jar in CLASSPATH Java Classes Include Notes installed directory in path load DLLs Session NotesThread.stermThread(). Session s = NotesFactory.Java Applications 1 Setup Notes.createSession([user. Demo 4 . 0 CORBA Classes 1 HTTP HTTP Domino Server JVM + Core Classes IIOP OS DIIOP 2 Setup Select "Applet uses Notes CORBA Classes" property Session AppletBase.Applets / Browser Your Machine Browser HTML Page 12 11 1 10 2 9 3 8 7 6 5 4 Demo 6 R5.getSession( ) instance method . g.0 Java Classes Notes Client API JVM 1.Java Applications 1 Your Machine Stand Alone Java Application Notes 4.exe) at OS Access the Java Notes Classes Notes Client/Server Installed access local API Domino RPC Server .1 & Core Classes OS Executed by Java interpreter (e.6/5. java. g.exe) at OS Setup NCSO.jar in CLASSPATH Session NotesFactory.createSession( host ) IIOP Domino Server Notes 5.Java Applications 2 Your Machine Stand Alone Java Application NO Local Client/Server Executed by Java interpreter (e.0 CORBA Classes ( NCSO.JAR) JVM Classes OS Demo 5 . java. .getSession(). NotesThread. Session s = this.Applets / Notes Client Notes 5.sinitThread().jar) JVM Classes Notes Client API OS Setup Java Applet Security options in User Preferences Session NotesThread.stermThread().0 Notes Form 12 11 1 10 2 9 3 8 7 6 5 4 Demo 7 Applet Notes Java Classes (Notes. Graphical Java Agents Build your agent with a GUI (or not) Use AWT or Swing Swing."AgentName") Demo 8 .ini Attach your agent to an event Use Simple Action: Run Agent Use Formula @Command([ToolsRunMacro].jar not included with Domino import into agent or reference in Notes. Domino 5.x and Java Domino Java Objects new Package, new Classes, methods and properties CORBA implementation of Backend Classes Remote access of Domino Java Agents new programmers pane, Script Library Domino UI Applets Outline, Editor, View, Action Servlets 4.6 & enhanced for 5.0 Attend AD109 - Java Programming with Domino: A look at Servlets & JSPs Enterprise Integration Java Lotus Connectors Domino JDBC driver Attend AD203 - Know the Code: Integrating Relational Data Using Java Domino 5.x and Java (continued) Let's update your resumes Java Servlets Java Server Pages J2EE Technologies Other JSP Related Sessions TS102: Building and Deploying Java Web Applications on a Domino Server TS113: The Architecture of the New Web Programming Model in Rnext HC103: Building R5 Web Applications using JavaServer Pages and WebSphere HC109: Implementing the Domino Rnext JSP Tag Library HC114: Tools and Tips for Working with the Rnext JSP Tag Library Please complete your evaluations Summary Why Java ? Basic Java concepts Accessing Domino via Java JSP and Servlets . Questions? Please complete your evaluations .
Report "Introduction to Java for Lotus Script Programmers"