Unit: Interactive Forms Integration into Web Dynpro for Java Topic: Offline interactive form based on sending and receiving emails
At the conclusion of this exercise, you will be able to: Send emails with an attached interactive form Read received emails with an attached interactive form Use the Java Mail API Integrate an interactive form within a Web Dynpro application Think of a company where employees need to fill out forms offline. Offline in this case means that the employees make their form entries on their local host without a server connection (e.g. at home, at a customer site, while traveling, etc.). This tutorial explains how to develop an offline interactive form scenario based on sending and receiving emails. In this case, an employee receives an email containing an empty or prefilled form, makes entries offline, and, after filling out the form, sends an email with the attached form back to a mail server. The server can identify the email with the attached form, extract the data and pass it to a backend system. You can use the Adobe integration within Web Dynpro for this purpose. This exercise will show you which steps are necessary to develop such a scenario based on a travel request form.
Page 1 / 18
1 Overview
The following screenshot shows the user interface of the Web Dynpro application you will develop in this exercise. Using the upper view, you can send an email with an attached travel request form to the address you enter. In the lower view, you can display all unread messages in your inbox containing an attached travel request form after clicking the Refresh button.
2 Prerequisites
To be able to use PDF forms in Web Dynpro applications, the following prerequisites apply: 2-1 The SAP NetWeaver Developer Studio (Support Package Stack 11) including Adobe LiveCycle Designer (forms design tool) is installed on your computer. Use the SAP NetWeaver 04 installation CDs/DVDs if it is not yet installed. You have access to the SAP J2EE Engine (Release 6.40). (Note that you can download an evaluation version (Sneak Preview SAP Web Application Server 6.40 Java) from the SDN Download Area at https://www.sdn.sap.com/sdn/downloadarea.sdn.) Adobe Reader 7.0.1 is installed on your computer. If this is not the case, download Adobe Reader 7.0.1 from the Adobe homepage (http://www.adobe.com) at http://www.adobe.com/products/acrobat/readstep2.html). The Active Component Framework (ACF) of the Interactive Forms integration is installed on your computer. With SP Stack 11, calling a Web Dynpro application that includes a PDF form for the first time should automatically install the ACF in the background. If you experience difficulties that may be related to the frontend installation, please see SAP Note 766191 on the SAP Service Marketplace for manual installation. The Adobe document services are configured on the SAP J2EE Engine you are using. To access the Installation and Configuration Guides for Adobe document services, go Page 2 / 18
2-2
2-3
2-4
2-5
to http://service.sap.com/nw04installation SAP Web AS SAP Web AS 6.40 SR1 and Related Documentation Adobe Document Services. 2-6 Basic knowledge of developing Web Dynpro applications. For helpful information about Web Dynpro, go to https://www.sdn.sap.com/sdn/developerareas/webdynpro.sdn?node=linkDnode6-2.
3-1
3-2 3-3
3-4
Page 3 / 18
Web Dynpro project structure Web Dynpro project: TutWD_EmailInteractiveForm_Init Web Dynpro application: EmailInteractiveFormApp The application EmailInteractiveFormApp displays the interface view of the Web Dynpro component EmailInteractiveFormComp in the browser window. Web Dynpro component: EmailInteractiveFormComp This is the Web Dynpro component that contains our entire application. View: SendView In this view, you can enter the recipients email address, and, upon clicking the Send button, send an email with the attached travel request form to this address. View: ReceivedView After clicking the Refresh button, this view displays all unread messages with an attached travel request form. View: FormView This view displays the content of the received interactive form. Window: Window Initially contains a view set with two view areas represented by the two cells (ViewSet Definition: GridLayout with one column and two rows). The two views SendView and ReceivedView are already embedded. The FormView becomes visible when doubleclicking one of the unread messages. The attached travel request form is then displayed, and you can return from the FormView to the ReceivedView.
Page 4 / 18
In the Navigation Modeler, which you can reach by double-clicking on the Window node, the initial Web Dynpro project looks as follows: The Window contains a ViewSet, which consists of 2 view areas. The upper view area contains the SendView and the lower one the ReceivedView. The FormView is plugged via an inbound and an outbound plug to and from the ReceivedView.
Page 5 / 18
To design this view, we have to add the UI elements listed below and set their properties. In order to add these UI elements, choose the Layout tab of the SendView, add the UI elements in the Outline view, and set their properties as stated below in the corresponding Properties tab: UI Element Type Label UI Element Name To_label Embedded in ... (Container Name) Group0 UI Element Property Properties of Label - text Properties of Label labelFor (Set this property after you entered the next UI element) InputField To Group0 Properties of InputField value Email.To (Select button on the right in Properties window, then select To field from the context tree.) <> (Note: Leave blank!) Value
To: To
Button
Button
Group0
Page 6 / 18
Page 7 / 18
5-5
Add the following coding lines to the onActionSendForm method in order to send an email with an attached interactive form using the Java Mail API. Do not forget to enter the mail server host you want to use in the second line of this code snippet.
Properties props = new Properties(); String host = "your.smtp host"; props.put("mail.smtp.host", host); Session session = Session.getInstance(props, null); MimeMessage message = new MimeMessage(session); Address toAddress = new InternetAddress(); Address fromAddress = new InternetAddress(); Address ccAddress = new InternetAddress(); Address bccAddress = new InternetAddress(); try { /* Creates an email object with different parts, one for the text and another for the attached file */ MimeMultipart multipart = new MimeMultipart(); BodyPart messageBodyPart = new MimeBodyPart(); /* the following statements build up the email */ if (! wdContext.currentEmailElement().getFrom().equals("")) { fromAddress = new InternetAddress(wdContext.currentEmailElement(). getFrom()); message.setFrom(fromAddress); } if (! wdContext.currentEmailElement().getTo().equals("")) { toAddress = new InternetAddress(wdContext.currentEmailElement(). getTo()); message.setRecipient(Message.RecipientType.TO, toAddress); } if (! wdContext.currentEmailElement().getCc().equals("")) { ccAddress = new InternetAddress(wdContext.currentEmailElement(). getCc()); message.setRecipient(Message.RecipientType.CC, ccAddress); } if (! wdContext.currentEmailElement().getBcc().equals("")) { bccAddress = new InternetAddress(wdContext.currentEmailElement(). getBcc()); message.setRecipient(Message.RecipientType.BCC, bccAddress); } if (! wdContext.currentEmailElement().getSubject().equals("") ) { message.setSubject(wdContext.currentEmailElement(). getSubject()); Page 8 / 18 }
if (! wdContext.currentEmailElement().getBody().equals("")) { messageBodyPart.setText(wdContext.currentEmailElement() .getBody()); } multipart.addBodyPart(messageBodyPart); /* a new part will be added, in the complete email this will be the attachment */ messageBodyPart = new MimeBodyPart(); String filename = "temp\\webdynpro\\web\\local\\TutWD_EmailInteractiveForm _Init\\Components\\com.sap.tut.wd.emailinteractiveform.EmailIn teractiveFormComp\\TravelRequest.pdf"; DataSource source = new FileDataSource(filename); messageBodyPart.setDataHandler(new DataHandler(source)); messageBodyPart.setFileName(source.getName()); messageBodyPart.setHeader("Content-Type","application/pdf"); multipart.addBodyPart(messageBodyPart); message.setContent(multipart); Transport.send(message); } /* the exceptions part */ catch (AddressException e) { wdComponentAPI.getMessageManager().reportWarning(e. getLocalizedMessage()); e.printStackTrace(); } catch (SendFailedException e) { wdComponentAPI.getMessageManager().reportWarning(e. getLocalizedMessage()); e.printStackTrace(); } catch (MessagingException e) { wdComponentAPI.getMessageManager().reportWarning( e.getLocalizedMessage()); e.printStackTrace(); }
5-6
Include the Java Mail API. You can do this by choosing Properties in the context menu of the TutWD_EmailInteractiveForm_Init node in the Web Dynpro Explorer view. Then choose Java Build Path, switch to the Libraries tab, select Add Variable, choose ECLIPSE_HOME, press the Extend button, navigate to plugins com.tssap.ext.libs.j2ee_1.3 lib, choose activation.jar, and press OK. Repeat these steps for the library mail.jar, and press OK. Select OK to close the Properties dialog. On the Implementation tab of the SendView, choose Source Organize Imports from the context menu. This will automatically add all necessary import statements to your Page 9 / 18
5-7
source code. Select only types in the javax.mail.* or javax.activation.* packages for this process. 5-8 Save the new metadata by choosing the (Save All Metadata) icon from the toolbar.
6-2
6-3
Page 10 / 18
To design this view, we have to add the UI elements listed below and set their properties. In order to add these UI elements, double-click on the ReceivedView within the Web Dynpro Explorer, choose the Layout tab of the ReceivedView, add the UI elements in the Outline view, and set their properties as stated below in the corresponding Properties tab: UI Element Type ToolBarButton UI Element Name RefreshButton Embedded in ... (Container Name) ToolBar8 UI Element Property Properties of Element - text Properties of Element dataSource Properties of Element - width Properties of Element readOnly Value <> (Leave blank!) Email
Table
Table
Group3
100% true
Open the context menu of the Table node in the Outline view. Choose Create Binding. Check the context elements Attachment, SentDate, From, Subject, and ContentType. Press Next. On the following screen, you can change the order of the table columns. Press Finish. Save the new metadata by choosing the (Save All Metadata) icon from the toolbar. Page 11 / 18
6-5 6-6
while (!wdContext.nodeEmail().isEmpty()) { wdContext.nodeEmail().removeElement(wdContext.nodeEmail().getElementAt(0)); } wdContext.nodeEmail().invalidate(); Message[] message = new Message[1000]; IPublicEmailInteractiveFormComp.IEmailElement newEmailNodeElement; //Set properties // enter email server, for example Microsoft Exchange Server, here String host = "your.mail.server"; // enter email account user name here String username = "your username"; // enter email account password here String password = "your password"; Properties props = new Properties(); props.put("mail.smtp.host", host); //Set Session Session session = Session.getInstance(props, null); //Set the store try { Store store = session.getStore("imap4"); store.connect(host,username,password); //Get folder Folder folder = store.getFolder("INBOX"); folder.open(Folder.READ_ONLY); //Get Mails message = folder.getMessages(); //Fill table with mails for (int i = 0; i < message.length; i++) { // look for attachments only in mail which are marked as unread if (message[i].isSet(Flags.Flag.SEEN) == false) {
Page 12 / 18
// only the mails with the right subject a processed if (message[i].getSubject().equals("Travel Request Form")) { newEmailNodeElement = wdContext.createEmailElement(); newEmailNodeElement.setFrom(message[i].getFrom()[0].toString()); newEmailNodeElement.setSubject(message[i].getSubject()); newEmailNodeElement.setSentDate(message[i].getSentDate().toString()); //Check for right Attachment and extract it from the mail body Object content = message[i].getContent(); if ( content != null && content instanceof Multipart) { for (int j = 0 , n = ((Multipart)content).getCount(); j < n; j++) { Part part = ((Multipart)content).getBodyPart(j); String disposition = part.getDisposition(); if ( disposition != null && (disposition.equals(Part.ATTACHMENT) || disposition.equals(Part.INLINE))) { if (part.getFileName().equals("TravelRequest.pdf")) { newEmailNodeElement.setAttachment(true); newEmailNodeElement.setContentType(part.getContentType().toString()); InputStream is = part.getInputStream(); ByteArrayOutputStream bo = new ByteArrayOutputStream(); int c; while ((c = is.read()) > -1) bo.write(c); byte[] pdfSource = bo.toByteArray(); newEmailNodeElement.setPdfSource(pdfSource); break; } else { newEmailNodeElement.setAttachment(false); } } } } wdContext.nodeEmail().addElement(newEmailNodeElement); } } } //Close connection and save changes (e.g. mark touched mails as read) folder.close(true); store.close(); } catch (MessagingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
Page 13 / 18
6-7
On the Implementation tab of the EmailInteractiveFormComp, choose Source Organize Imports from the context menu. This will automatically add all necessary import statements to your source code. Select only types in the javax.mail.* or javax.io.* packages for this process. Open the Actions tab of the ReceivedView. Create a new action called RefreshPressed, and set Refresh as text. Use the default settings for all other options. Click Finish.
6-8 6-9
6-10 Apply the new action to the button on the Layout tab. To do so, switch to the Layout tab of the ReceivedView, select the button in the Outline view, switch to the corresponding Properties tab, and set the onAction property of the button to RefreshPressed. 6-11 Switch to the Implementation tab of the ReceivedView, and add the following source code at the end of the onActionRefreshPressed method.
wdThis.wdGetEmailInteractiveFormCompController().readInbox();
Page 14 / 18
To display the interactive form you received, you need to map the PdfSource context element of the component controller and design the FormView layout. 7-1 Open the DataModeler of the EmailInteractiveFormComp by double-clicking the Email InteractiveFormComp node in the Web Dynpro Explorer view. Create a data link between FormView and the Component Controller. To do so, use the arrow icon on the tool bar on the left side of the Diagram View. Drag and drop the Email node from the right onto the Context node on the left side, select PdfSource, and confirm with OK. Choose Finish.
7-2
7-4 7-5
In the Outline view, insert a child of type InteractiveForm and Id InteractiveForm1 in the Group1. Select the InteractiveForm1 element in the Outline view, switch to the corresponding Properties tab, and change the properties as shown below. Reference the corresponding dataSource and pdfSource from the context, and set the height, mode, width, hAlign and vAlign properties as shown below:
The dataSource property is used to specify the data source. The data source encapsulates the data you can display in the form at runtime. For the dataSource property, you need to specify the path to the context node providing the data. In this step, we reference the DataSource context node, which is already defined in the context structure of the template used (see Context tab of the FormView):
Page 16 / 18
For more information related to context structures refer to the following tutorial, which you can find in the standard SAP library documentation: Application of Context Programming and Data Binding The usePdf value of the mode property is used for displaying the original PDF document. The data source and the template for the creation of the PDF document are ignored. The pdfSource property specifies the path of the context element that contains the PDF document. You must bind this property to a context attribute of the type binary. In this tutorial, the context attribute has already been defined in the context structure (see graphic above). This property allows an application developer to access the binary file and download it to the local hard disk or read and send the data to a backend. 7-6 Choose the Layout tab of the FormView. In the Outline view, insert a ToolBarItem of type ToolBarButton into the ToolBar, and call it SubmitButton.
7-9
7-10 Switch to the Layout tab of the ReceivedView. In the Outline view, choose Table, and assign this new action to the onLeadSelect property. 7-11 Save the new metadata by choosing the (Save All Metadata) icon from the toolbar.
Page 17 / 18
Page 18 / 18