/* * © Copyright IBM Corp. 2011 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package com.ibm.xsp.extlib.renderkit.html_extended.sametime; import java.io.IOException; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import com.ibm.commons.util.NotImplementedException; import com.ibm.commons.util.StringUtil; import com.ibm.commons.util.io.json.JsonException; import com.ibm.commons.util.io.json.JsonGenerator; import com.ibm.commons.util.io.json.JsonJavaFactory; import com.ibm.commons.util.io.json.JsonJavaObject; import com.ibm.commons.util.io.json.JsonObject; import com.ibm.sbt.services.client.ClientServicesException; import com.ibm.sbt.services.endpoints.BasicEndpoint; import com.ibm.sbt.services.endpoints.Endpoint; import com.ibm.sbt.services.endpoints.EndpointFactory; import com.ibm.sbt.services.endpoints.SSOEndpoint; import com.ibm.xsp.FacesExceptionEx; import com.ibm.xsp.ajax.AjaxUtil; import com.ibm.xsp.component.UIViewRootEx2; import com.ibm.xsp.designer.context.XSPContext; import com.ibm.xsp.extlib.component.sametime.UISametimeClient; import com.ibm.xsp.extlib.renderkit.html_extended.FacesRendererEx; import com.ibm.xsp.extlib.resources.ExtLibResources; import com.ibm.xsp.extlib.sbt.resources.SBTResources; import com.ibm.xsp.resource.ScriptResource; import com.ibm.xsp.resource.StyleSheetResource; import com.ibm.xsp.util.FacesUtil; import com.ibm.xsp.util.JavaScriptUtil; /** * @author Philippe Riand */ public class SametimeClientRenderer extends FacesRendererEx { @Override public void encodeBegin(FacesContext context, UIComponent component) throws IOException { // If we are in partial refresh mode, we assume that they are already loaded if(AjaxUtil.isAjaxPartialRefresh(context)) { return; } UISametimeClient stClient = (UISametimeClient)component; // Ensure that the dojo theme is loaded UIViewRootEx2 rootEx = (UIViewRootEx2)context.getViewRoot(); rootEx.setDojoTheme(true); // Mark the ST client as enabled UISametimeClient.enableClient(rootEx, true); // Find the Sametime Endpoint String endpointName = stClient.getEndpoint(); if(StringUtil.isEmpty(endpointName)) { endpointName = EndpointFactory.SERVER_SAMETIME; } Endpoint stServer = EndpointFactory.getEndpointUnchecked(endpointName); if(stServer==null) { //Platform.getInstance().log("Sametime server URL is undefined."); return; } // Get the url of the Lotus Sametime proxy server String linkurl = stServer.getUrl(); if(StringUtil.isEmpty(linkurl)) { //Platform.getInstance().log("Sametime server URL is undefined."); return; } if(linkurl.endsWith("/")) { linkurl = linkurl.substring(0,linkurl.length()-1); } // Write the ST proxy writeProxyConfig(context, rootEx, stClient, stServer, linkurl); // Write the client script file references writeClientScriptFile(context, rootEx, stClient, stServer, linkurl); // Write the login writeLogin(context, rootEx, stClient, stServer); writeSametimeDojoEvent(context, rootEx); } protected void writeProxyConfig(FacesContext context, UIViewRootEx2 rootEx, UISametimeClient stClient, Endpoint stServer, String linkurl) throws IOException { // Generate the proxy configuration try { // Create the proxy object and the corresponding script JsonObject proxyConfig = createProxyConfig(context, stClient, stServer, linkurl); StringBuilder b = new StringBuilder(256); // Sametime FIXME: djConfig! b.append("var djConfig = { parseOnLoad: true, isDebug: false };\n" ); b.append("var stproxyConfig="); JsonGenerator.toJson(JsonJavaFactory.instance,b,proxyConfig,true); b.append(";\n"); String onInitProxy = stClient.getInitProxyScript(); if(StringUtil.isNotEmpty(onInitProxy)) { b.append(onInitProxy); b.append("\n"); } ScriptResource configJS = new ScriptResource(); configJS.setClientSide(true); configJS.setContents(b.toString()); rootEx.addEncodeResource(context,configJS); } catch(JsonException ex) { throw new FacesExceptionEx(ex); } } protected void writeSametimeDojoEvent(FacesContext context, UIViewRootEx2 rootEx) throws IOException { StringBuilder b = new StringBuilder(256); b.append("require([\"dojo/ready\",\n"); b.append("\"dijit/MenuItem\"],\n"); b.append("function(ready, MenuItem) {\n"); b.append("if(!MenuItem.prototype._onClick) {\n"); b.append("MenuItem.prototype._onClick = function(evt) {\n"); b.append("this.getParent().onItemClick(this, evt);\n"); b.append("event.stop(evt);\n"); b.append("};\n"); b.append("}\n"); b.append("ready(function() {\n"); b.append("stproxy.addOnLoad(stproxy.login.loginAsAnon);\n"); b.append("});\n"); b.append("}\n"); b.append(");\n"); rootEx.addScript(b.toString()); } protected JsonObject createProxyConfig(FacesContext context, UISametimeClient stClient, Endpoint stServer, String linkurl) throws IOException { // Get the proxy object in memory JsonObject proxyConfig = new JsonJavaObject(); proxyConfig.putJsonProperty("server", stServer.getUrl()); boolean autoTunnel = stClient.isAutoTunnelURI(); if(autoTunnel) { //http://xxxx/xsp/.ibmxspres/.extlib/sbt/sametime/tunnel.html // Note that the URL must be absolute String htmlResource = FacesContext.getCurrentInstance().getExternalContext().encodeResourceURL(SBTResources.SAMETIME_TUNNEL_HTML); String tunnelURI = FacesUtil.makeUrlAbsolute(FacesContext.getCurrentInstance(), htmlResource); proxyConfig.putJsonProperty("tunnelURI", tunnelURI); } boolean connectClient = stClient.isConnectClient(); if(connectClient) { proxyConfig.putJsonProperty("isConnectClient", connectClient); } return proxyConfig; } protected void writeClientScriptFile(FacesContext context, UIViewRootEx2 rootEx, UISametimeClient stClient, Endpoint stServer, String linkurl) throws IOException { // Generate a client script resource String script = stClient.getClientScriptFile(); if(StringUtil.isNotEmpty(script)) { boolean baseComp = false; if(script.equals(UISametimeClient.SCRIPT_BASECOMP)) { baseComp = true; } else if(script.equals(UISametimeClient.SCRIPT_LIVENAME)) { baseComp = true; } else if(script.equals(UISametimeClient.SCRIPT_WIDGETS)) { baseComp = true; } if(baseComp) { StringBuilder baseCompUrl = new StringBuilder(128); baseCompUrl.append(linkurl); baseCompUrl.append("/stbaseapi/baseComps.js"); baseCompUrl.append("?noHub="); baseCompUrl.append(stClient.isNoHub()); baseCompUrl.append("&lang="); String lang = stClient.getLang(); if(StringUtil.isEmpty(lang)) { lang = XSPContext.getXSPContext(context).getLocaleString(); } baseCompUrl.append(lang); // The bascomp URL ScriptResource baseCompJS = new ScriptResource(baseCompUrl.toString(),true); rootEx.addEncodeResource(context,baseCompJS); // And the corresponding CSS StyleSheetResource baseCss = new StyleSheetResource(linkurl + "/stwebclient/dojo.blue/sametime/themes/WebClientAllNoTundra.css"); rootEx.addEncodeResource(context,baseCss); } int preload = 0; if(script.equals(UISametimeClient.SCRIPT_LIVENAME)) { preload = 1; ScriptResource livenameJS= new ScriptResource(linkurl + "/stwebclient/livenameLight.js",true); rootEx.addEncodeResource(context,livenameJS); } else if(script.equals(UISametimeClient.SCRIPT_WIDGETS)) { preload = 2; baseComp = true; ScriptResource widgetsJS= new ScriptResource(linkurl + "/stwebclient/widgetsLight.js",true); rootEx.addEncodeResource(context,widgetsJS); } // Add some dojo resources to optimize the use of the JS aggregator if(preload>0) { rootEx.addEncodeResource(context,ExtLibResources.dojoItemFileWriteStore); rootEx.addEncodeResource(context,ExtLibResources.dojoDndMoveable); rootEx.addEncodeResource(context,ExtLibResources.dijitMenu); if(preload>=2) { rootEx.addEncodeResource(context,ExtLibResources.dojoString); rootEx.addEncodeResource(context,ExtLibResources.dojoCookie); rootEx.addEncodeResource(context,ExtLibResources.dojoIoScript); rootEx.addEncodeResource(context,ExtLibResources.dijitToolbar); rootEx.addEncodeResource(context,ExtLibResources.dijitEditor); rootEx.addEncodeResource(context,ExtLibResources.dijitTree); rootEx.addEncodeResource(context,ExtLibResources.dijitLayoutContentPane); rootEx.addEncodeResource(context,ExtLibResources.dijitLayoutBorderContainer); rootEx.addEncodeResource(context,ExtLibResources.dijitFormButton); rootEx.addEncodeResource(context,ExtLibResources.dijitFormComboBox); rootEx.addEncodeResource(context,ExtLibResources.dijitFormCheckBox); rootEx.addEncodeResource(context,ExtLibResources.dijitFormTextBox); rootEx.addEncodeResource(context,ExtLibResources.dijitTree); } } } } protected void writeLogin(FacesContext context, UIViewRootEx2 rootEx, UISametimeClient stClient, Endpoint stServer) throws IOException { boolean autoLogin = stClient.isAutoLogin(); if(autoLogin) { try { if(stServer instanceof BasicEndpoint) { writeAutoLoginBasic(context, rootEx, stClient, (BasicEndpoint)stServer); } else if(stServer instanceof SSOEndpoint) { writeAutoLoginToken(context, rootEx, stClient, (SSOEndpoint)stServer); } } catch(ClientServicesException ex) { throw new FacesExceptionEx(ex); } } } protected void writeAutoLoginBasic(FacesContext context, UIViewRootEx2 rootEx, UISametimeClient stClient, BasicEndpoint stServer) throws IOException, ClientServicesException { // check if stAutoLogin is true boolean autoLogin = stClient.isAutoLogin(); if(autoLogin) { if(stServer.isAuthenticated()) { String user = stServer.getUserIdentity(); String pwd = stServer.getPassword(); String status = stClient.getLoginStatus(); if(StringUtil.isEmpty(status)) { status = "I'm available"; } StringBuilder b = new StringBuilder(256); b.append("dojo.addOnLoad(function(){\n"); b.append("if(stproxy){stproxy.login.loginByPassword('"); JavaScriptUtil.appendJavaScriptString(b, user); b.append("','"); JavaScriptUtil.appendJavaScriptString(b, pwd); b.append("',stproxy.status.AVAILABLE,'"); JavaScriptUtil.appendJavaScriptString(b, status); b.append("',null,null)}\n"); b.append("});\n"); //b.append("dojo.addOnUnload(function(){if(stproxy){stproxy.login.logout(stproxy.session.USERID)}});\n"); rootEx.addScript(b.toString()); } } } protected void writeAutoLoginToken(FacesContext context, UIViewRootEx2 rootEx, UISametimeClient stClient, SSOEndpoint stServer) throws IOException { throw new NotImplementedException(); } // // EXPERIMENTAL CODE - DO NOT REMOVE FOR NOW! // // protected void addDynamicScript(StringBuilder b, String url) { //// b.append("document.write(\"<script src='xxx'></script>\");\n"); // b.append("document.write(\"\\x3Cscript type='text\\/javascript' src='"); // JavaScriptUtil.appendJavaScriptString(b, url); // b.append("'>\\x3C/script>\");\n"); // } // // protected void addDynamicScript_(StringBuilder b, String url) { // b.append("var tx=dojo._getText('"); // JavaScriptUtil.appendJavaScriptString(b, url); // b.append("');\n"); // b.append("var sc=document.createElement('script');\n"); // b.append("sc.setAttribute('type','text/javascript');\n"); // b.append("sc.text=tx;"); // JavaScriptUtil.appendJavaScriptString(b, url); // b.append("');\n"); // b.append("dojo.doc.getElementsByTagName('head')[0].appendChild(sc);\n"); // //// b.append("var sc=document.createElement('script');\n"); //// b.append("sc.setAttribute('type','text/javascript');\n"); //// b.append("sc.setAttribute('src', '"); //// JavaScriptUtil.appendJavaScriptString(b, url); //// b.append("');\n"); //// b.append("dojo.doc.getElementsByTagName('head')[0].appendChild(sc);\n"); // } }