修改BOE的源代码,避免用opendocument打开bo的objects时弹出登录窗口。
修改/Business Objects/Tomcat/webapps/businessobjects/enterprise115/desktoplaunch/opendoc下的openDocument.jsp。
<%@ page language="java" contentType="text/html;charset=UTF-8" import="java.net.*, java.util.*, java.io.*, org.apache.xalan.xslt.*, org.w3c.dom.*"%> <%@ page import="com.crystaldecisions.sdk.occa.security.ILogonTokenMgr, com.crystaldecisions.sdk.framework.*, com.crystaldecisions.sdk.exception.SDKException" %> <% IEnterpriseSession enterpriseSession = null; ISessionMgr sessionMgr; sessionMgr = CrystalEnterprise.getSessionMgr(); /// //Set logon information here: enterpriseSession = sessionMgr.logon("administrator", "", "bobj-willisxie", "secEnterprise"); /// ILogonTokenMgr iLManager = enterpriseSession.getLogonTokenMgr() ; String sToken = iLManager.getDefaultToken(); %> <% String context = ".."; boolean bFindCharset = true; //false: no guessing is done with charset for the incoming query string, use the one defined by sCharset variable //true: will try to read an optionnal parameter &charset= to determine charset encoding String sForceCharset = "UTF-8"; //charset by default, change this to support legacy OpenDocument URLs not url-encoded with UTF-8 //empty string "" would mean to use the default charset on this platform String sCharset = new String(sForceCharset); if (bFindCharset) { //to allow futur encoding switch, we parse manually the query string, looking for &charset=<charset> in it String sQueryString = "&" + request.getQueryString(); int ic = sQueryString.indexOf("&charset="); if (ic > -1) { //if the param exists it MUST have a valid charset name value, otherwise the behavior is not certain... sQueryString = sQueryString.substring(ic + 9); ic = sQueryString.indexOf("&"); //next param if (ic > -1) sQueryString = sQueryString.substring(0, ic); sCharset = sQueryString; } } if (sCharset == null) sCharset = sForceCharset; //A wrapper to handle servlets prio to 2.3 which do not have setCharacterEncoding() method //request = WIRequestWrapper.setCharacterEncoding(request, "UTF-8"); request.setCharacterEncoding("UTF-8"); response.setDateHeader("expires", 0); response.setContentType("text/html;charset=UTF-8"); %> <%@ include file="tools/utils.inc" %> <% //openDocument.jsp //see spec bluecanal / //Description : //Properties : / //get parameters /* NB: we need to support the different legacy versions of this parameters sDocName = sDoc, sDocName documentID = iDocID sDocType = sTyp, sType, sDocType AND W = wqy, R = rep, B = bqy (case insensitive?) documentRepoType = RepoType, sRepoType, sRepo AND corporate, personal, inbox, 0, 1, 2 report = Report page = Page refresh = Refresh */ /* Here is the exhaustive list of supported query string parameter as defined in latest spec (CB0) * * sRepoType (legacy: RepoType) * sRepo (specific CB0) * sPath (specific CB0) * sDocName (legacy: sDoc) * sAlternateDocName (secific CB0) * sType (legacy: sTyp, legacy values: "W"qy, "R"ep, "B"qy) * sIDType (specific CB0, can be CUID, GUID, RUID, ParentID, InfoObjectID (default)) * iDocID * sReportName (legacy: sReport ?) * sPartContext (specific CB0) * sReportPart (specific CB0) * sReportMode * sInstance (specific CB0) * lsM*, lsR*, lsS* and lsC* * sRefresh (legacy: Refresh, sForceRefresh) * NAII * sOutputFormat * sViewer * sWindow * sMode * Page (only legacy ?) * sKind (specific CB1) * sf * buttonrefresh * buttonexport * buttonprint * */ /* //From this list we define an array containing all authorized parameters. //We removed the implicit parameters passed to IV (docname, id, repotype, doctype) //and the parameter already handled by this page's logic (ls* for prompts and sRefresh) String [] stAutorizedParams = { // "sRepoType", "RepoType", "sRepo", "sPath", // "sDocName", "sDoc", "sAlternateDocName", // "sType", "sTyp", // "sIDType", // now the ID type for crystal is stored inside the id // "iDocID", "sReportName", "sReport", "sPartContext", "sReportPart", "sReportMode", "sInstance", // "lsM*", "lsR*", "lsS*", "lsC*", // "sRefresh", "Refresh", "sForceRefresh", "NAII", "sOutputFormat", "sViewer", "sWindow", // is handled here but passed to viewer anyway (in case of the viewer wants to know it is opened in a window) "sMode", // "sEntry", // for future usage // "sKind", "Page", "sf", "buttonrefresh", "buttonexport", "buttonprint" }; */ String [] stHandledParams = { "sRepoType", "RepoType", "sDocName", "sDoc", "sType", "sTyp", "sIDType", /* now the ID type for crystal is stored inside the id */ "iDocID", "lsM*", "lsR*", "lsS*", "lsC*", "sRefresh", "Refresh", "sForceRefresh", "sEntry", /* for future usage */ "sKind", "token" }; //get the corresponding hashtable for faster lookup (+lowercase keys) Hashtable htHandledParams = new Hashtable(stHandledParams.length); for (int i = 0 ; i < stHandledParams.length ; i++) { htHandledParams.put(stHandledParams[i].toLowerCase(), "Y"); } //Get Doc Name String sDocName = request.getParameter("sDoc"); if(sDocName == null) sDocName = request.getParameter("sDocName"); if(sDocName == null) sDocName = "untitled"; //special CB0, Crystal uses different ID types. Read this value here String sIDType = request.getParameter("sIDType"); if (sIDType == null) sIDType = ""; //get the ID: mandatory for WID docs but FC and legacy will open on 0 String sDocID = request.getParameter("iDocID"); if (sDocID == null) sDocID = "0"; int iDocID = 0; if (sIDType.compareToIgnoreCase("CUID")!=0 && sIDType.compareToIgnoreCase("GUID")!=0 && sIDType.compareToIgnoreCase("RUID")!=0 && sIDType.compareToIgnoreCase("ParentID")!=0 && strIsNumeric(sDocID)) { //this is not a crystal special ID type, but a normal numeric ID (BO or InfoObjectID) iDocID = Integer.parseInt(sDocID); sDocID = "" + iDocID; } //get the docType String sDocType = request.getParameter("sType"); if(sDocType == null) sDocType = request.getParameter("sTyp"); if(sDocType == null) sDocType = ""; //should there be a default type of doc? if(sDocType.equals("W")) sDocType = "wqy";//default to legacy doc if(sDocType.equals("R")) sDocType = "rep"; if(sDocType.equals("B")) sDocType = "bqy"; //Doc domain is not really supported as we never pass this parameter to any URL String documentDomain = request.getParameter("sRepo"); if(documentDomain == null) documentDomain = request.getParameter("sRepoName"); if(documentDomain == null) documentDomain = "Document"; //get the repo, the default is corporate and inbox and personal are not really used String documentRepoType = request.getParameter("RepoType"); if(documentRepoType == null) documentRepoType = request.getParameter("sRepoType"); //if(documentRepoType == null) documentRepoType = request.getParameter("sRepo"); if(documentRepoType == null) documentRepoType = "0"; //as they are //String sReport = request.getParameter("Report"); if(sReport == null) sReport = ""; //String sPage = request.getParameter("Page"); if(sPage == null) sPage = ""; //refresh boolean bRefresh = false; String sRefresh = request.getParameter("Refresh"); if(sRefresh == null) sRefresh = request.getParameter("sRefresh"); if(sRefresh == null) sRefresh = request.getParameter("sForceRefresh"); if(sRefresh != null) bRefresh = (sRefresh.equals("Y") || sRefresh.equals("yes")); //not sure if the repo is C,M,I or corporate etc if(documentRepoType.equals("corporate") || documentRepoType.equals("Corporate") || documentRepoType.equals("C") || documentRepoType.equals("0")) documentRepoType = "0"; else if(documentRepoType.equals("personal") || documentRepoType.equals("Personal") || documentRepoType.equals("M") || documentRepoType.equals("2")) documentRepoType = "2"; //we use the sIDType param to know what kind of ID is the resource //the documentRepoType will depend on that: //CUID, GUID, RUID or ParentID => documentRepoType = "10" //others (unspecified or InfoObjectID) => documentRepoType = "0", assimiled to a BOBJ corporate resource if ( sIDType.compareToIgnoreCase("CUID")==0 || sIDType.compareToIgnoreCase("GUID")==0 || sIDType.compareToIgnoreCase("RUID")==0 || sIDType.compareToIgnoreCase("ParentID")==0) { documentRepoType = "10"; //special faked repotype for this type of resource sDocID = sIDType + "," + sDocID; //a composite ID to remind ID type: <sIDType>,<sDocID>. Will be parsed by crystal viewers } else documentRepoType = "1"; String sDocToken = ""; //null presumably String sKind = request.getParameter("sKind"); if(sKind == null) sKind = ""; String token = request.getParameter("token"); if(token == null) token = sToken; //gather and format prompts here for docs //Received: lsM[name]=a&lsM[name]=b //Formatted to: lsM[name]=a;b;c //prompt types include: lsS, lsM, lsC, lsCBR, lsD //related to prompts is NAII //boolean hasNAII = false; String prompts = ""; String sOtherParams = ""; java.util.Enumeration e = request.getParameterNames();//hashtable of non duplicated parameters + values while(e.hasMoreElements()) { String element = (String)e.nextElement(); String[] params = request.getParameterValues(element);//gets an array of parameter values if ((element.indexOf("lsS")==0) || (element.indexOf("lsM")==0) || (element.indexOf("lsC")==0)) {// loop and convert to ; seperated list if (prompts.length() > 0) prompts += "&"; //add & for correct url if(sDocType.equals("wid")) { //wid use a ; seperated list prompts += URLEncodeUTF8(element) + "="; //convert to ; seperated list for (int i = 0; i < params.length; i++) { //Must encode ; character to get the whole QueryString encoded prompts += (i > 0 ? URLEncodeUTF8(";") : "") + URLEncodeUTF8(params[i]); } } else { for (int i = 0; i < params.length; i++) //rep use a normal lsMcity=paris&lsMcity=... { prompts += (i > 0 ? "&" : "") + URLEncodeUTF8(element) + "=" + URLEncodeUTF8(params[i]); } } } /* else if (element.indexOf("NAII") > -1) { hasNAII = true; //related to prompts only, has no value } */ else if (element.indexOf("lsR")==0) { //added for CB0, range prompt (eg: &lsRCity=[Austin..Chicago]) prompts += (prompts.length() > 0 ? "&" : "") + URLEncodeUTF8(element) + "=" + URLEncodeUTF8(request.getParameter(element)); } else if (htHandledParams.get(element.toLowerCase()) == null) { //don't pass already handled params /* element.compareToIgnoreCase("sDocName")!=0 && element.compareToIgnoreCase("iDocID")!=0 && element.compareToIgnoreCase("sType")!=0 && element.compareToIgnoreCase("sRepoType")!=0 && element.compareToIgnoreCase("sRefresh")!=0 && element.compareToIgnoreCase("refresh")!=0) { //just ignore these parameters, they are especially treated elsewhere. //for other unrecognized params, let's forward them */ sOtherParams += (sOtherParams.length() > 0 ? "&" : "") + URLEncodeUTF8(element) + "=" + URLEncodeUTF8(request.getParameter(element)); } } //build the uid in the infoview style: //= <name>,<id>,<repotype>,<doctype>,<SDK token> where , = C_SEP //the seperator used is no longer defined in utils.jsp BUT should be consistent with what is there String sDocUID = sDocName + C_SEP + sDocID + C_SEP + documentRepoType + C_SEP + sDocType + C_SEP + sDocToken + C_SEP + sKind; //cmdP1 = the docuid String sRespURL = "documentXML.jsp?cmdP1=" + URLEncodeUTF8(sDocUID) + "&token=" + URLEncodeUTF8(token); //cmdP2 has the prompts and other parameters String cmdP2 = prompts /* + (hasNAII ? "&NAII=" : "") */; //URL chunk for prompts and NAII if (!sOtherParams.equals("") && !cmdP2.equals("")) cmdP2 += "&"; cmdP2 += sOtherParams; //NB: a new type of URL redirection can now be specified using askPromptView for cmd if (prompts.length() > 0 && !"param".equalsIgnoreCase(request.getParameter("sInstance"))) { sRespURL += "&cmd=askPromptView&cmdBlock=all&cmdP2=" + URLEncodeUTF8(cmdP2); } else { if (!bRefresh) { //always refresh if there are prompts so don't pass the parameter above ... sRespURL += "&cmd=askView&cmdBlock=all&cmdP2=" + URLEncodeUTF8(cmdP2); //need cmdP2 for other parameters } else { //wid and rep/wqy documents use different parameters for refresh wo we add both for security sRespURL += "&cmd=askView&cmdBlock=all&cmdP2=" + URLEncodeUTF8((cmdP2.equals("") ? "" : (cmdP2 + "&")) + "sRefresh=yes&refresh=Y"); } } //saves the real document URL into HTTP session, in case we have to login session.putValue("extRedirectionURL",sRespURL); %> <HTML> <HEAD> <SCRIPT language=javascript1.3> function getQueryParamValue(strQueryString, strParamName) { var strRet = ""; if("undefined" != typeof(strQueryString) && strQueryString != null) { var arrQueryParam = strQueryString.split('&'); for (var i=0;i<arrQueryParam.length;i++) { var strName = arrQueryParam[i]; var strValue = ""; var iPos = arrQueryParam[i].indexOf('='); if (iPos>=0) { strName = arrQueryParam[i].substring(0, iPos); strValue = arrQueryParam[i].substring(iPos + 1); } if (strParamName == strName) { strRet = strValue; break; } } } return strRet; } function MM_openBrWindow(theURL, winName, features, bUnique) { var _winName = winName; if (!bUnique) { var dtemp = new Date(); _winName = _winName + dtemp.getTime(); } pop = window.open(theURL, _winName, features); pop.opener = self; } function findParent() { <% String sWindow = request.getParameter("sWindow"); if (sWindow == null) sWindow = "Same"; boolean bNewWin = false; if (!sWindow.equals("Same")) { bNewWin = true; //if sWindow != new then the provided string is the identifier of the new window } if (bNewWin) { %> MM_openBrWindow('<%=sRespURL %>', '<%=sWindow %>', '', <%=(sWindow.equals("New") ? "false" : "true") %>); //toolbar=yes,location=yes,status=yes,resizable=yes,width=' + width + ',height=' + height, false); history.back(); <% } else { %> /* var found = false; var frameToFind = "XML.jsp"; var obj = window; try { while (!found && typeof(obj.parent) != "undefined" && obj.parent != obj) { //escape clause please var loc = "" + obj.parent.document.location; if (loc.indexOf(frameToFind) < 0) { obj = obj.parent; } else { found = true; } } } catch(e) { //cross domain issue ? assume that this URL is like an external one found = false; } //if test needed if (found) { //open in parent ie documentXML or myInfoviewXML frame level obj = obj.parent; if (("" + obj.document.location.href).indexOf("documentXML.jsp") > 0) { //we are in documentXML frameset, let's stack the current documentXML URL (including possibly new token) //to allow backward navigation (close) history //we ask the action header bar the real UID of the (previously) opened doc if (typeof(obj.parent.push) != "undefined" && typeof(obj.getDocUID) != "undefined") { //the stack should be defined in webiHome.jsp //calculate the URL, knowing the current docUID, and asking viewer for the last storage token var curDocUID = obj.getDocUID(); var sURL = "documentXML.jsp?ctxLayout_last=fromSession&cmdBlock=all&cmd=askView&cmdP1=" + URLEncodeUTF8(curDocUID); //here is the real URL to come back to the currently opened document obj.parent.push(sURL, obj.timeStamp); //push this URL into the stack, and stamp it to help manage browser's back/forward } } if (typeof(obj.asyncOpenDocument) != "undefined") { var bIE = (document.all ? true : false); var sViewerURL = obj.frames[1].location.href; var sViewType = getQueryParamValue(sViewerURL, "ViewType") ; obj.asyncOpenDocument('<%=sRespURL%>'); //asynchronous launch of URL if (!bIE || sViewType != "P") { //Don't do back if the document is wid or rep and viewed on PDF on IE //FR 103137, apparently acroread on IE is already doing this... history.back(); } } else obj.document.location.href = '<%=sRespURL%>'; } else { //this should handle the external URL case ... //document.location.href = '<%=context + "/scripts/login/topStart.html"%>'; document.location.replace('<%=context + "/scripts/login/topStart.html"%>'); } */ var mywin = window; while (mywin != mywin.parent && mywin.parent && (mywin.name == 'ceframe' || mywin.name == 'documentFrame000hb' || mywin.name == 'Report' || mywin.name == 'Reportbloc')) { mywin = mywin.parent; } mywin.document.location.replace('<%=sRespURL%>'); <% } %> } </SCRIPT> <PRE> </PRE>