- How this Article is Organized
- Obtaining the Scripts and Tools for this Article
- Integration – A Historical Perspective
- Pre-Cooking and General Preparation
- Outlook Fat Client a la Carte Recipe
- Outlook Express Messaging Soup Recipe
- OWA Over a Netlet With a DNS Twist Recipe
- OWA Luau with Rewriter Fire Dancing: the 3 o'clock Show
- OWA Luau with Rewriter Hula Dancing: the 6 o'clock Show
- Glossary
- About the Author
- Acknowledgements
- Bibliography
- Ordering Sun Documents
- Accessing Sun Documentation Online
OWA Luau with Rewriter Fire Dancing: the 3 o'clock Show
Main course: Internet ExplorerIngredients:
Client
Internet Explorer 5.5SP2 with December 2002 Security update
Exchange
Eight modifications to exchweb scripts, HTML component files, or both
Portal Server
Sun ONE Portal Server 3.0SP4HP3 with 3.0SP4HP3Exchange2KSP3Fix or 3.0SP5
51 Gateway profile additions from vanilla SP4HP3 ruleset
Advantages:
No client required for access.
Exposes native Exchange functionality to the web browser.
No client configuration is required.
Encryption and decryption are done using SSL.
A script is included in this solution to automate rule generation.
The user interface is the same whether accessed from within or outside the internal corporate network.
Disadvantages:
Considerable understanding of both products is required to perform and test this integration.
Requires changes to Exchange server exposed scripts and component files in addition to configuration changes and fixes for the portal server.
Integration is fragile in the sense that rules and modifications are very strict and inflexible, or major functionality will fail or be inaccessible.
Sun ONE Portal Server 3.0 software cannot have a separate rule profile and Gateway instance specific to Exchange.
Exchange Feature Completeness ~99%
The following list describes the functionality and any known problems or limitations that you can expect in Exchange after the implementation of this recipe. Å@
Inbox shelf view, message 2 message navigation, page 2 page navigation, composition, reply, reply all, Forward, explicit check for new messages, message polling, new message notification, delete, move, address book, all 7 panel views, message status icons, message expansion and collapse, message ordering, message status icons, search.
Message Composition send, rich text editing, Address book (GAL) access to receiver fields, attachments, online help, options, save as draft, importance tagging. Print not tested and Check Names does not appear to do anything useful (but doesn't appear to be broken).
Calendaring daily view, weekly view, monthly view, month 2 month navigation, appt view and detail mouseover, day selection from calendar, today view, Address book, new appointment, check for messages. Alert polling, notification, and Print untested.
Calendar Appointments save/close, send, attachments, priority, recurrence, invite using Address book, availability, reminder, start time, end time, all day event, show time, and appointment icons.
Alerts alert polling, reminder pop-ups, snooze
Contacts new contact, check for new messages, six contact views, expansion and collapse under supported views, Address book (though all you can do with it is search), person 2 person navigation, page 2 page navigation, delete.
Contact Creation All fields work. Directions points to an Internet link and thus is not rewritten. Send works as well as Address book (which still doesn't do anything useful). Save/Close and online help work as well. Print untested.
Options All form fields. Password change requires Exchange code modification so that it does not use browser built-in variables to dynamically build the URL. View Items and recover deleted items untested. Selecting close goes to an empty un-named folder. The password change might require resetting user's basic authentication in order to connect again to Exchange.
Folder View All folders, URLs, icons, expansion and collapse, all shortcuts, all right mouseclick submenu functionality including update, open, move, copy and delete.
Journal, Notes, Tasks All feature complete, except for search and empty deleted items folder.
Known Problems With Exchange
Problem 1: Cannot Clean Up Deleted Items Folder
Reason: Exchange server returns an error when the DeletedItems folder is fetched using a rewritten URL. The following XML error might be returned by Exchange with a status code of 200:
<result><errorcode>5648</errorcode></result>
This might be an indication that there is some client-specific information in the encoded session ID. Due to the inability to work around this problem, you might want to open a problem case with Microsoft.
Problem 2: Audible Reminders Don't Work When Gateway is in HTTPs Mode
Reason: This is likely a problem where the audio file isn't cached, and therefore cannot be sent to a helper application. This is a known IE deficiency with HTTP cache control headers.
This is not a problem if you have SP5 installed on your portal server.
Problem 3: icon-contact.gif Not Shown in Expandable Contact Views
Reason: The icon-contact.gif URL is specified in a prop1 XML tag body of a DAV response. Unfortunately the tag usage is ambiguous, so if it is rewritten, any text data within that tag identifier is rewritten as well. Adding prop1 to the Gateway profile will prevent a warning about secure and insecure content being displayed and the images will show up, but the table headers of the affected views will become less readable because the text will be prepended with a fully qualified, rewritten URL. This affects the following contact views: By Location, Phone List, By Company, By Followup Flag.
What
Update the Gateway profile using the PS3luau script.
Install the portal server patch with the required Exchange fixes or 3.0SP5.
Update the Exchange Files.
Remove the XML namespace identifier from ctrl_Tree20.xsl.
Change tree state image manipulation in ctrl_FormatBar20.htc.
Create an interim variable in mf_Poll function of ctrl_Poll20.js.
Modify expIndicator URLs after XSLT transform in ctrl_Tree20.js.
Modify the icon image URLs when folders are expanded in ctrl_Tree20.js.
Strip the Portal Gateway Hostport off the deleted items in util_View20.js.
Create an interim variable in the mf_RemindersXML function of ctrl_reminder20.htc.
See "Obtaining the Scripts and Tools for this Article" on page 3.
This can be automated with the modfiles.ksh script.
NOTE
Microsoft does not support any change made to the Outlook Web Access source files (.htc, .js, or .xsl) that exist in the Exchweb folder.2 Any customization changes which affect these files that have already been made may affect or prevent a successful integration using these recipes. Future minor and major releases of Exchange from Microsoft may overwrite these changes, and make other modifications that break the integration through the rewriter. Upgrading to new releases of either product should be made in a controlled, responsible manner in a testing-only environment.
How
To Update the Gateway Profile Using the Rule Generation PS3luau Script
For information on obtaining this script, see "Obtaining the Scripts and Tools for this Article" on page 3.
As root on the profile server, run the PS3luau script with the -update flag.
Check that the iwtGateway.xml file was updated.
Restart the Gateway.
This script is meant to complement rules that already exist in the vanilla Gateway profile. If these rules are not present, the integration might not work.
# ./PS3luau -update Performing Update... Backing up Gateway Profile... Adding rules to Rewrite JavaScript Variables in URLs section of the Gateway profile... Adding rules to Rewrite HTML Attributes section of the Gateway profile... Adding rules to Rewrite JavaScript Variables Function section of the Gateway profile... Adding rules to Rewrite JavaScript Function Parameters Function section of the Gateway profile... Adding rules to Rewrite Text Data of XML Document section of the Gateway profile... Adding rules to Rewrite Attribute Value of XML Document... Updating iwtGateway Attributes... Operation completed successfully. Operation completed successfully. Removing temporary files ...
# diff /etc/opt/SUNWips/xml/iwtGateway.xml.pre3.0_luau /etc/opt/SUNWips/xml/iwtGateway.xml | wc -l 52
# /etc/init.d/ipsgateway start stopping gateway ... done. starting gateway ... done.
To Install the Sun ONE Portal Exchange Integration Patches
To perform this recipe, you must install one of the following:
Patch 112682-03 and patch 114621-01
Service Pack 5 (SP5)
To obtain the patches, contact Sun Online Support at the following URL:
http://cgi.iplanet.com/cgi-bin/c/ct-newcase.cgi
On both the profile and Gateway components, apply both patches using the Solaris patchadd command.
Example:
# patchadd 114621-01 Checking installed patches... Executing prepatch script... Verifying sufficient filesystem capacity (dry run method)... Installing patch packages... Patch number 114621-01 has been successfully installed. See /var/sadm/patch/114621-01/log for details Executing postpatch script... Checking for previous patch revisions... Making changes for 114621-01... Restarting iPS Server w/ new settings. stopping auth helpers ... done. stopping web server ... done. stopping directory server ... done. starting auth helpers ... done. removing /opt/netscape/directory4/slapd-exige/locks...done starting directory server ... done. starting web server ... done. Server restarted. Please wait a moment before connecting to it. Restarting iPS Gateway w/ new settings. stopping gateway ... done. starting gateway ... done. Gateway restarted. Please wait a moment before connecting to it. Postpatch processing complete. Patch packages installed: SUNWwtdt SUNWwtgwd SUNWwtsvd
To Update the Exchange Files
The following procedures require the scripts and tools for this article. See "Obtaining the Scripts and Tools for this Article" on page 3.
Determine the best approach for updating your Exchange files:
If the following files in ex_server_install/exchweb/controls have not been modified, you can run the modfiles.ksh script to update your Exchange files automatically (where ex_server_install is the full path to the Exchange installation, such as D:\Exchange). The files that the script modifies are:
If any of these files have been modified in any way, you must manually update the files, otherwise the script will overwrite any customizations that you have in these files. Refer to the following manual procedures:
"To Remove the XML Namespace Identifier From ctrl_Tree20.xsl" on page 30
"To Change Tree State Image Manipulation in ctrl_FormatBar20.htc" on page 31
"To Insert an Interim Variable in the mf_Poll() Function of ctrl_Poll20.js" on page 32
"To Modify Expindicator URLs after XSLT transform in ctrl_Tree20.js" on page 34
"To Modify Icon Image URLs When Folders Are Expanded in ctrl_Tree20.js" on page 35
"To Strip the Portal Gateway Hostport Off the Deleted Items in util_View20.js" on page 36
"To Create an Interim Variable in the mf_RemindersXML() Function of ctrl_reminder20.htc" on page 38
"To Add an Already Rewritten Interim Variable to the Img Src Attribute Value in ctrl_FreeBusy20.htc" on page 39
To use the modfiles.ksh script, go to the ex_server_install/Exchweb directory of the Exchange server. Right-select the controls folder and choose save as controls.zip.
Make a copy of the controls.zip file and name it orig_controls.zip.
Use ftp to copy the controls.zip file to the directory containing the portal integration tools that you have downloaded.
Run the modfiles.ksh script as shown.
Use ftp to copy the updated controls.zip file back to the ex_server_install/exchweb directory of the Exchange server.
Unzip the new controls.zip file so that it overwrites the current contents.
Test Exchange connectivity without going through the Gateway.
ctrl_Tree20.xsl ctrl_FormatBar20.htc ctrl_Poll20.js ctrl_Tree20.js util_View20.js ctrl_reminder20.htc ctrl_FreeBusy20.htc To run the modfiles.ksh script, go to Step 2 below.
# ls -1F PS3luau* change_gw_mimes.xml change_gw_mode.xml controls.zip cookbook.sxw iwtBookmarkProvider/ modfiles.ksh* rewriter_blueprint.pdf scripts/ # ./modfiles.ksh Found contols.zip...unzipping... Archive: controls.zip inflating: controls/ctrl_FormatBar20.htc inflating: controls/ctrl_FreeBusy20.htc inflating: controls/ctrl_Poll20.js inflating: controls/ctrl_reminder20.htc inflating: controls/ctrl_Tree20.js inflating: controls/ctrl_Tree20.xsl inflating: controls/util_View20.js Backing up original file as controls_orig.zip... Creating diffs directory for modified files at diffs/... Modifying ctrl_FormatBar20.htc ... Created diffs/ ctrl_FormatBar20.htc .diff... Modifying ctrl_FreeBusy20.htc ... Created diffs/ ctrl_FreeBusy20.htc .diff... Modifying ctrl_Poll20.js ... Created diffs/ ctrl_Poll20.js .diff... Modifying ctrl_Tree20.js ... Created diffs/ ctrl_Tree20.js .diff... Modifying ctrl_Tree20.xsl ... Created diffs/ ctrl_Tree20.xsl .diff... Modifying ctrl_reminder20.htc ... Created diffs/ ctrl_reminder20.htc .diff... Modifying util_View20.js ... Created diffs/ util_View20.js .diff... Zipping new file contents in to controls.zip... adding: controls/ctrl_FormatBar20.htc (deflated 74%) adding: controls/ctrl_FreeBusy20.htc (deflated 76%) adding: controls/ctrl_Poll20.js (deflated 70%) adding: controls/ctrl_reminder20.htc (deflated 66%) adding: controls/ctrl_Tree20.js (deflated 76%) adding: controls/ctrl_Tree20.xsl (deflated 73%) adding: controls/util_View20.js (deflated 70%) Done.#
If anything doesn't work, the modifications can be backed out by unzipping orig_controls.zip over the controls directory.
To Remove the XML Namespace Identifier From ctrl_Tree20.xsl
Only perform the following manual file change if you decided not to run the modfiles.ksh script.
In the Exchsvr\Exchweb\Controls directory on the Exchange server, make a backup copy of the ctrl_Tree20.xsl file.
Edit ctrl_Tree20.xsl and remove the root node: <?xml version="1.0"?>
Save the file and close it.
To Change Tree State Image Manipulation in ctrl_FormatBar20.htc
Only perform the following manual file change if you decided not to run the modfiles.ksh script.
Make the following change to the onDocumentReady() function body of ctrl_FormatBar20.htc file:
The following example uses the diff command to display the changes that you need to make in the ctrl_FormatBar20.htc file.
# diff -c ctrl_FormatBar20bak.htc ctrl_FormatBar20.htc *** ctrl_FormatBar20bak.htc Fri Feb 7 14:27:50 2003 --- ctrl_FormatBar20.htc Fri Feb 7 15:56:44 2003 *************** *** 307,313 **** var obj = m_eFormatbar.children[szButton]; if( null != obj ) { ! obj.innerHTML = szVal; } } if (null != this.dhtmlEdit) --- 307,332 ---- var obj = m_eFormatbar.children[szButton]; if( null != obj ) { ! //////////////////////////////////////// ! // Workaround for SunONE Portal ! // The img tag has already been stripped ! // off here so we need only replace the ! // src attr value with an already ! // rewritten one ! ! //alert ("Image tag before: " + szVal); ! var imgre = /src=/; ! var imgTag = szVal; ! var imgStartIndex = imgTag.search(imgre) + 5; ! var tmpImgTxt = imgTag.substr(imgStartIndex); var imgStopIndex = tmpImgTxt.lastIndexOf("'") + imgStartIndex; ! tmpImgTxt = imgTag.substring(imgStartIndex, imgStopIndex); ! var imgObj = tmpImgTxt.substr(tmpImgTxt.lastIndexOf("/")); ! imgTag = imgTag.substring(0, imgStartIndex) + imagePath + imgObj + imgTag.substr(imgStopIndex); ! obj.innerHTML = imgTag; ! //alert (Image tag after: " + obj.HTML); ! ////obj.innerHTML = szVal; ! ///////////////////////////////////////// } } if (null != this.dhtmlEdit) !
To Insert an Interim Variable in the mf_Poll() Function of ctrl_Poll20.js
Only perform the following manual file change if you decided not to run the modfiles.ksh script.
Make the following change to the mf_Poll() function body of the ctrl_Poll20.js file:
# diff -c ctrl_Poll20bak.js ctrl_Poll20.js *** ctrl_Poll20bak.js Fri Feb 7 14:22:06 2003 --- ctrl_Poll20.js Fri Feb 7 14:22:16 2003 *************** *** 247,252 **** --- 247,259 ---- // Check for notification by using stored subscription identifier function mf_Poll() { + //////////////////////////////////// + // Added for SunONE Portal Server + // + imgURL = m_szFolderURL; + m_szFolderURL = imgURL; + // + /////////////////////////////////// if( !m_fEnabled ) { return;
To Modify Expindicator URLs after XSLT transform in ctrl_Tree20.js
Only perform the following manual file change if you decided not to run the modfiles.ksh script.
Make the following change to the mfcb_AddHierarchy() function body of the ctrl_Tree20.js file:
# diff -c ctrl_Tree20bak.js ctrl_Tree20.js *** ctrl_Tree20bak.js Fri Feb 7 14:22:33 2003 --- ctrl_Tree20.js Fri Feb 7 14:30:36 2003 *************** *** 382,387 **** --- 382,403 ---- if(null != szDisplayName) { var objFolder = objFolderTLH.children[0]; + ///////////////////////////////////////// + // Added for the SunONE Portal Server to + // avoid unecessary redirects caused from + // the image URL being fetched using the + // Gateway host as the base. + // EX: https://gw/exchweb/img/tree-splus20.gif + + //alert("objFolderTLH.innerHTML is: " + objFolderTLH.innerHTML); + var curIMG = objFolder.children("expIndicator").src; + //alert("curIMG is: " + curIMG); + curIMG = curIMG.substring(curIMG.lastIndexOf("/")+1); + curIMG = m_szImagePath + curIMG; + //alert("Final curIMG is: " + curIMG); + objFolder.children("expIndicator").src = curIMG; + //alert("szDisplayName is: " + szDisplayName); + ////////////////////////////////////////// if(null != objFolder) { var objAnchor = objFolder.children(objFolder.url);
To Modify Icon Image URLs When Folders Are Expanded in ctrl_Tree20.js
Only perform the following manual file change if you decided not to run the modfiles.ksh script.
Make the following change to the mfcb_ExpandFolder() function body of the ctrl_Tree20.js file:
# diff -c ctrl_Tree20bak.js ctrl_Tree20.js *************** *** 1156,1161 **** --- 1172,1196 ---- objChildContainer.innerHTML = objXML.transformNode(objXSL.documentElement); if(objChildContainer.children.length > 0) { + /////////////////////////////////////////// + // Added for the SunONE Portal Server so + // that the icon images and expansion status + // symbols inside subfolders will be + // displayed correctly. + var curIMG; + for (var x=0; x<objChildContainer.children.length; x++) { + curIMG = objChildContainer.children(x).children("expIndicator").src; + //alert("curIMG is: " + curIMG); + curIMG = curIMG.substring(curIMG.lastIndexOf("/")+1); + curIMG = m_szImagePath + curIMG; + //alert("final curIMG is: " + curIMG); + objChildContainer.children(x).children("expIndicator").src = curIMG; + curIMG = objChildContainer.children(x).children("folderIcon").src; + curIMG = curIMG.substring(curIMG.lastIndexOf("/")+1); + curIMG = m_szImagePath + curIMG; + objChildContainer.children(x).children("folderIcon").src = curIMG; + } + //////////////////////////////////////////// objChildContainer.style.display = ""; objFolder.children("expIndicator").src = m_szImagePath + m_szMinusIcon; objFolder.expanded = "true";
To Strip the Portal Gateway Hostport Off the Deleted Items in util_View20.js
Only perform the following manual file change if you decided not to run the modfiles.ksh script.
Make the following change to the mfcb_AddHierarchy() function body of the util_View20.js file:
# diff -c util_View20bak.js util_View20.js *** util_View20bak.js Fri Feb 7 14:24:45 2003 --- util_View20.js Fri Feb 7 14:24:59 2003 *************** *** 64,69 **** --- 64,81 ---- szXMLBatchString = "<?xml version='1.0'?><D:" + szXMLCommand + " xmlns:D='DAV:'><D:target>"; for(var i = 0; i < objItems.length; i++) { + //////////////////////////////////////////// + // Change required for SunONE Portal Server + // a:href nodes from the DAV response must + // be rewritten in order for the tree view + // folder URLs to be correct, but they cannot + // be rewritten for a BMOVE request for a + // batch delete to work on the backend. + tmpURL = objItems(i).text + tmpURL = tmpURL.substring(tmpURL.lastIndexOf("http://")); + objItems(i).text = tmpURL; + /////////////////////////////////////////// + szXMLBatchString += "<D:href>" + objItems(i).text + "</D:href>"; } szXMLBatchString += "</D:target></D:" + szXMLCommand + ">";0
To Create an Interim Variable in the mf_RemindersXML() Function of ctrl_reminder20.htc
Only perform the following manual file change if you decided not to run the modfiles.ksh script.
- Make the following change to the mf_RemindersXML() function body of the ctrl_reminder20.htc file:
# diff -c ctrl_reminder20bak.htc ctrl_reminder20.htc *** ctrl_reminder20bak.htc Fri Feb 7 14:23:44 2003 --- ctrl_reminder20.htc Fri Feb 7 14:23:55 2003 *************** *** 86,91 **** --- 86,97 ---- // Search for reminders that should now be displayed function mf_RemindersXML() { + /////////////////////////////////// + // Added for SunONE Portal Server + imgURL = m_szFolderURL; + m_szFolderURL = imgURL; + // + ////////////////////////////////// if( !m_fEnabled || (CONST_B_SEARCH == (m_fState & CONST_B_SEARCH )) ) { return;
To Add an Already Rewritten Interim Variable to the Img Src Attribute Value in ctrl_FreeBusy20.htc
Only perform the following manual file change if you decided not to run the modfiles.ksh script.
- Make the following change to the ctrl_FreeBusy20.htc file:
# diff -c ctrl_FreeBusy20bak.htc ctrl_FreeBusy20.htc *** ctrl_FreeBusy20bak.htc Thu Feb 6 19:12:00 2003 --- ctrl_FreeBusy20.htc Thu Feb 6 21:27:08 2003 *************** *** 578,584 **** "<SPAN class='fbLegend2clr tentClr'> </SPAN><SPAN class='fbLegend2txt'>"+m_szTentative+"</SPAN>"+ "<SPAN class='fbLegend3clr busyClr'> </SPAN><SPAN class='fbLegend3txt'>"+m_szBusy+"</SPAN>"+ "<SPAN class='fbLegend4clr oofClr'> </SPAN><SPAN class='fbLegend4txt'>"+m_szOof+"</SPAN>"+ ! "<SPAN class='fbLegend5clr unknownClr'><IMG src='/exchweb/img/form-noinfo.gif'></SPAN><SPAN class='fbLegend5txt'>"+m_szUnknown+"</SPAN>"+ "</TD></TR></table>" + "<DIV id='_DIVFB' nowrap onselectstart='return(false)' class='fbbody'>" + "<div id='DIVHIDESPLITTERS' style='position:absolute;top:0px;width:"+m_iRecipWidth+"px;height:100%;b ackground-color:#b0b0b0;z-index:0;'></div>" + --- 578,586 ---- "<SPAN class='fbLegend2clr tentClr'> </SPAN><SPAN class='fbLegend2txt'>"+m_szTentative+"</SPAN>"+ "<SPAN class='fbLegend3clr busyClr'> </SPAN><SPAN class='fbLegend3txt'>"+m_szBusy+"</SPAN>"+ "<SPAN class='fbLegend4clr oofClr'> </SPAN><SPAN class='fbLegend4txt'>"+m_szOof+"</SPAN>"+ ! "<SPAN class='fbLegend5clr unknownClr'>" + ! "<IMG src='" + g_szVirtualRoot + "/img/form-noinfo.gif'>" + ! "</SPAN><SPAN class='fbLegend5txt'>"+m_szUnknown+"</SPAN>"+ "</TD></TR></table>" + "<DIV id='_DIVFB' nowrap onselectstart='return(false)' class='fbbody'>" + "<div id='DIVHIDESPLITTERS'
Why
Why Are Each Of the Rewriter Rules Necessary For the Integration to Work?
The ruleset was generated by meticulously tracking where and how URLs are used throughout the Exchange product when accessed with an Internet Explorer browser. The ruleset has been finely tuned to reduce or eliminate extraneous rules which might do more harm than good.
The following tables provide descriptions and usage examples of the changes made by the Luau script.
TABLE 1 iwtGateway-JavaScriptVariables / Rewrite JavaScript Variables in URLs
Rule Reason Usage Example
g_szUserBase |
Variable is used throughout Exchange to fully qualify relative URLs with the Exchange server hostport. | util_View20.js:
szDeletedItemsFolder = g_szUserBase + g_szDeletedItemsURL + "/"; |
g_szVirtualRoot |
Like g_szUserBase except g_szVirtualRoot points to /exchweb instead of /uid. |
vw_Calendar20.js: m_eCalendar.addBehavior(g_szVirtualRoot+ |
this.viewClass |
Loads the XSL required for a specific message view. | ctrl_View20.js:
this.viewClass = "/exchweb/controls/ctrl_View20.xsl"; |
g_szBaseURL |
Used as the base for dynamically building URLs for the Global Access List (GAL). |
dlg_GAL20.js: |
g_szURL* |
Used interchangeably with szURL. |
frm_ReadNote20.js: opener.idMsgViewer.seekURL(g_szURL,-1,window.name); |
g_szNewMailWav |
Used for new mail notification | vw_Navbar20.js: oSnd.src = g_szNewMailWav; |
g_szReminderWav | Used for audible notification of alerts. | vw_Navbar20.js: rgParams["WavFile"] = g_szReminderWav;o |
g_szPublicFolderUrl |
Used for accessing and manipulating files in the public folder. | m_szHttpFbServerUrl = g_szPublicFolderUrl + "?Cmd=freebusy"#´ |
g_szExWebDir* | Duplicate of g_szVirtualRoot. |
|
szViewClassURL |
Another variable used for URLs which point to XSL files used in creating specific panel views. | view.js: m_objTransFormXSL.load(m_szViewClassURL);pboard. |
m_szImagePath |
Used to create relative URLs from the Exchange server root. Many image URLs created using this variable are for icons and status. | ctrl_Tree20.js: objFolder.children("expIndicator").src = m_szImagePath + m_szMinusIcon; |
eSpan.src |
Used to set a status image in the appt creation page. | ctrl_FreeBusy20.htc: eSpan.src = "/exchweb/img/form-noinfo.gif"; |
TABLE 2 iwtGateway-Tags / Rewrite HTML Attributes
Rule |
Reason |
Usage Example |
url |
Used as an attribute value for an HTML component so that it can be accessed directly using the DOM. |
<DIV id="idMsgViewer" |
|
HTML component property used to keep track of the current view and of events which can operate on that view. Also referred to using the object path this.viewClass. |
view.htc:<property name="viewClass" |
draftsURL |
HTML component property used to keep track of the URL for the drafts folder. |
composeappt.js: |
imagePath |
HTML component property which stores the relative URL from the server root to the images directory. |
ctrl_View20.js: m_szImagePath = |
implementation |
HTML tag attribute value (really XML) used in attaching an HTML component file to a specific HTML element. |
<?IMPORT namespace="WM" |
folderUrl |
HTML component property used for storing a current folder's URL. |
vw_Calendar20.js: m_eCalMessaging. |
folder |
HTML component property. |
ctrl_Notify20.htc: |
t:src |
Used for audible event notification in the navbar. |
t:src="http://ex-server/exchweb/img/notify.wav" |
imageNextArrow |
Used for month 2 month navigation in the calendar view. |
ctrl_Calendar20.js: '<IMG border=0 |
imagePrevArrow |
Used for month 2 month navigation in the calendar view. |
ctrl_Calendar20.js: |
TABLE 3 iwtGateway-JavaScriptFunctionParameterConvert / Rewrite JavaScript Function Parameters Function
Rule |
Reason |
Usage Example |
objTree.addHierarchy:y |
Adds a new folder to the folder tree in the navbar. Some parameters may already be rewritten, SP4HP3 has a fix where the runtime rewriter function will correctly handle already rewritten URLs. |
navbar.js: objTree.addHierarchy |
requestFactory:y |
Used to create WebDAV requests using ActiveX initiated by the IE client. |
ctrl_Tree20.js: var objRequest = |
mf_Subscribe:y |
Used to poll for new messages and alerts. |
ctrl_Poll20.js: mf_Subscribe |
mf_setViewDescriptorNode:,,y |
The third parameter passed to this function in wfview.js is used to create the prepended relative URL path. This rule affects the images in the search results of the search view, and the phonelist order of the contacts view. |
wfview.js: mf_setViewDescriptorNode(objViewNode, |
TABLE 4 iwtGateway-XMLTextRewrite / Rewrite Text Data of XML Document
Rule |
Reason |
Usage Example |
imagepath |
DAV response artifact used in XSLT transformation for various images which have relative URLs defined in XSL files. |
<!-- Flag status col --> |
prop2 |
Another artifact used for message status image URLs. |
<?xml version="1.0">><a:multistatus... |
davhref |
Artifact used in various transforms. May also return the initial message to be viewed on a DAV SEARCH response for the Inbox contents. |
<davhref>http://ex-server/exchange/Administrator/Inbox/ |
xsl:attribute,name=src |
When an XSL file has an XML root element, the rewriter can use this rule to resolve multiple selects for image sources that all have relative URLs. Because of unpredictability when rewriting Exchange XSL files, it'' better to simply remove the XML root element if one exists.This is to used because XSL files with XML root nodes are not rewritten. |
<xsl: when test="inbox"> |
e:smallicon d:inbox d:calendar d:sentitems d:deleteditems d:contacts d:drafts d:outbox d:sendmsg d:msgfolderroot URL Icon g:smallicon d:smallicon |
Artifacts returned by a DAV PROPFIND request for the user's folder list. |
<?xml version="1.0"?><a:propfind
xmlns:a="DAV:" |
a:href |
Ambiguous artifact used for both request URLs and internal Exchange URLs to query the Microsoft datastore. |
ctrl_Tree20.js: szFolderURL = |
TABLE 5 iwtGateway-XMLAttributeRewrite / Rewrite Attribute Value of XML Document
Rule |
Reason |
Usage Example |
src,IMG |
XSL file contained its own IMG tag with an src attribute that would need to be rewritten if the root element was XML instead of XSL. |
ctrl_Calviewdaily20.xsl: <IMG class='dailyApptImg' src='/exchweb/img/view-reminder2.gif' height='13' border='0'></IMG> |
TABLE 6 iwtGateway-MimeTypeTranslatorClass / Mime Type Translator Class
Rule |
Reason |
Usage Example |
Add text/x-component to |
The Gateway needs to recognize *.htc files as HTML so that it can rewrite them as such. |
N/A |
Why Must a Portal Server Patch Be Applied For the Integration To Work?
The minimal Sun ONE Portal Server 3.0 install level must be 3.0SP4HP3, not only because it is the most current release and most robust rewriter implementation thus far, but it also has a specific rewriter fix where the runtime rewriter function will now correctly handle already rewritten URLs.
This fix is necessary for Exchange because of the large number of duplicative variable namesspecifically, function parameter values which may or may not have already been rewritten elsewhere. Previously, this situation would have simply resulted in a SCRIPT error. The following fixes are also required, and are included in the Portal/Exchange integration patch:
BugID 4780863 - Gateway strips off XML declaration tag
BugID 4788050 - Rewriter should ignore comments which occur prior to opening XSL tag
BugID 4777962 - Gateway should not automatically forward requests for nonexistent domains
Pages or response bodies that contain an XML namespace identifier which looks like <?xml version="1.0" ?> end up having the root tag dropped. The direct effect on Exchange is not clear unless something depends on this root element being present.
Currently, Microsoft has a copyright statement in the Exchange XSL files which precedes the XSL root element. These comments should be ignored to avoid the rewriter attempting to translate the XSL file and making mince meat out of it before sending it on its way to the browser.
Prior to this fix, the Gateway would create redirections to the portal login servlet for any requests which had no host header or protocol identifier, or didn't match a Gateway scheme (like statistics). This can create unhealthy burst transmissions on the login Servlet. Many of these requests are due to rewriter misconfigurations. Instead of redirecting to the login servlet, the Gateway will now send a 404 error response, and a log entry will be created when the Gateway log mode is set to message, which will make it easier to debug these kinds of situations. A log entry in iwtGateway might look like the following example: Warning: Rewriter misconfigured for embedded URL /exchweb/img/form-noinfo.gif from Referrer http://gw/http://exserver/exchange/Administrator/Calendar/?Cmd=new&mm=2&dd=6&yy=2003 We know the Referrer page was already loaded, so we can search up from this warning and find where the reference is being made to the embedded URL.
For Example . . .
eSpan = "/exchweb/img/form-noinfo.gif"; . . . means that eSpan has not been added to the Gateway profile.
There's a larger context of this fix as it relates to Exchange as well. Often when a DAV response is received, it will immediately perform a transform with the artifacts and an XSL file which has already been downloaded to the client. The browser might spawn requests for embedded content directly following that transform, using URLs which might not be rewritten. Instead of creating a flurry of login requests which would bog down the profile server, a 404 error is sent back, and the images will temporarily not be shown until they can be updated at a later point of execution.
BugID 4777957 - iplanet function does not check if variables are null
Exchange initializes many variables to null, which is a common Java programming practice. However, when the runtime rewriter function encounters a null variable, it is unable to operate on it. Similarly, Exchange has several areas where the RHS of an assignment is actually undefined at the point of assignment. Either of these cases results in SCRIPT errors, and will prevent other things from functioning normally.
BugID 4782435 - parser error when a style attribute is followed by a Boolean attribute and then another DOMString attribute.
The Portal Gateway log will indicate a StringOutOfBounds exception immediately after calling parseCSS, in this particular case. Both the Exchange alert popup and the search interface have HTML with this specific attribute order.
BugID 4825401 Gateway should redirect requests for URLs relative to the server root.
This Bug is related to BugID 4777962, and is actually more of an RFE. This fix allows the Gateway in some cases to forward a request for an embedded object whose URL is relative to the server root, so it can be fetched from the appropriate place. This is particularly valuable for Exchange because there are several areas where image URLs relative to the server root are hard coded in XSL templates. The images are fetched as soon as the DHTML resulting from the XSL transform is inserted into the DOM. Since all of this is done on the client side, there is no way for the Gateway to intervene until the image is requested from the wrong location. One area where this fix is noticeable is in the calendar appointment icons. Without this fix, the DHTML hierarchy would need to be traversed in order to insert an intermediary variable. This becomes increasingly difficult with multiple appointments on the same day, time block, and so on.
Why Does the XML Namespace Identifier Have to be Removed From ctrl_Tree20.xsl?
Having an XML root node for an XSL file forces the Gateway to interpret the file as though it were XML and rewrite it as such. Because of the syntax of most of the XSL files, it's better to not attempt to rewrite the XSL content, and either rewrite the XML prior to the transform or rewrite the resulting URL once the transform has completed. XSL content is rewritten by default and should not be changed.
Why is the Tree State Image Manipulation Necessary in ctrl_FormatBar20.htc?
In the message composition window, there is an HTML element with an ID of idFormatbar which contains an attribute called buttonHTML. This attribute value is assigned a chunk of data which is handled through regular expressions in the ctrl_FormatBar20.htc onDocumentReady function. The assignment looks something like: The RHS is arbitrary in nature, so we are forced to make the change where the UI is rendered. The way it is being done in the code modification is to extract the image object out of the IMG tag, rewrite it, and then reinsert it. We rewrite it using a known imagePath
buttonHTML="FontDialog::<IMG border='1' style='cursor:hand;border-color:buttonface' src='http://ex-server/exchweb/img/tool-font.gif'>"
attribute value which also exists for the idFormatbar element. The result is code that will render the UI the same whether or not the user is accessing Exchange directly or through the Gateway.
Why Must an Interim Variable be Inserted in the mf_Poll() Function of ctrl_Poll20.js?
The mf_Poll() function uses a variable m_szFolderURL which cannot be added to the Gateway profile without causing message polling to break. So before the value of m_szFolderURL is used to create a POLL request in mf_Poll, we insert a hook for the Gateway to rewrite it in a just-in-time (JIT) fashion within the function body. If the value is not rewritten, the POLL request will attempt to be made directly to the Exchange server and will fail (assuming the browser is unable to directly contact the Exchange server).
Why is it Necessary to Modify the expIndicator URLs After XSLT transform in ctrl_Tree20.js?
mfcb_AddHierarchy is used to create the tree view in the navbar when the folders button is selected from the left-hand frame. There are images used to determine folder state and whether or not the individual folders contain any children, such as subfolders or items. The tree is built dynamically, using the resulting message body contents returned from a DAV PROPFIND request. The XML contents of the message body are transformed, using a corresponding XSL file which determines the final image URLs used to fetch the individual icons. Prior to the Exchange Portal patch, this fetch would result in a redirection to the portal desktop login because the URL would look something like https://GW/exchweb/img/m_szPlusIcon. Either a 302 redirect or a 404 not found error message will be returned to the browser instead. If a 404 is returned, and before the dynamic HTML is inserted in to the DOM, we can rewrite the URLs so that the images can be fetched successfully. This is done by with another JavaScript variable m_szImagePath, which is initialized at the beginning of ctrl_Tree20.js that has already been added to the Gateway profile.
Why is it Necessary to Modify Icon Image URLs When Folders are Expanded in ctrl_Tree20.js?
When mfcb_ExpandFolder is called, only the outer expIndicator images are handled correctly because they are assigned using m_szImagePath that is rewritten at the point it is initialized in ctrl_Tree20.js. Unfortunately, all of the other children in each folder tree have URLs which are not rewritten, so we must explicitly set those URLs with rewritten equivalent values. This is done by first extracting out the image object, which is either a folder icon or a folder status image, and then assigning the value back using direct DOM access. This is done for the expIndicator as well as for the folderIcons.
Why Must the Portal Gateway Hostport be Stripped Off the Deleted Items in util_View20.js?
a:href is an ambiguous artifact. In this case, it is used to generate a batch request to move the selected item or items to the deleted items folder. For the batch request to complete successfully, the individual message URLs which are already rewritten, must have the Portal Gateway information stripped off of them in order for their locations to match in the Microsoft datastore.
Why is it Necessary to Create an Interim Variable in the mf_RemindersXML() Function of ctrl_reminder20.htc?
For the same reason as in the mf_Poll() function, we cannot add m_szFolderURL to the Gateway profile, so we must rewrite it in a JIT fashion prior to the DAV search request being initiated. If this request fails, the individual folders cannot be polled for new messages.