修改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>