Microstrategy SDK - Common Information

SDK

https://community.microstrategy.com/t5/SDK/TN34656-How-to-Access-Request-Keys-and-HTTP-Header-Information/ta-p/185243

How can we persist information in every request?

We can accomplish this by creating a simple text file that specifies the name of the parameter whose name/value pair you want to persist. When MicroStrategy Web finds this parameter name/value pair in a URL, it automatically passes it in every subsequent request, ensuring that the value associated with the parameter name remain available at all time.

  1. Create a properties files, ParameterBuilder.properties: persist=localeInfo. Unless you specifically want to change the default behavior of the application, you should not use a MicroStrategy Web reserved parameter name as the value for persist.
  2. Save this properties file in plugins\pluginName\WEB-INF\classes

How can we store some information into the session:

cntSvcs.setSessionAttribute(arg0, arg1)

where cntSvcs is of type ContainerServices, and arg0 and arg1 are of type String.

How can we obtain information from the session:

cntSvcs.getSessionAttribute(arg0)

where cntSvcs is of type ContainerServices, and arg0 is of type String

What can I do with WebIServerSession?

WebIServerSession iSession = WebObjectsFactory.getInstance().getIServerSession();

This is a research question.

How can we determine the object type given an ObjectBean instance?

ObjectBean ob = sb.getTarget();
int objectType = ob.getObjectType();
if (objectType == EnumDSSXMLObjectTypes.DssXmlTypeDocumentDefinition) {
    // The thing being subscribed is a report document (dashboard)
} else if (objectType == EnumDSSXMLObjectTypes.DssXmlTypeReportDefinition) {
    // The thing being subscribed is a regular report (adhoc)
}

What can we use the ObjectBean instance for?

The thing to keep in mind is that when we use the ObjectBean instance, it represent the object within the metadata. Therefore, method such as getObjectID returns the ID of the underlying object in the metadata that this object bean represent.

How can we get the object's ID given an ObjectBean instance?

String id = ob.getObjectID();

How can we get the name of an object given an ObjectBean instance?

String objectName = ob.getObjectName();

How can we get a WebObjectInfo object from an ObjectBean instance?

WebObjectInfo woi = ob.getObjectInfo();

How can we get the parent folder bean from an ObjectBean instance?

FolderBean parentFolderBean = ob.getParentFolderBean(java.lang.String name);

Returns a FolderBean representing the parent folder of the current object. Null is returned if the current object is the root folder of a project. The name parameter is the name set on the parent FolderBean.

How can we get access to the object source from inside an event handler?

WebComponent wc = event.getSource();
WebIServerSession iSession  = ((AppContext)wc.getBeanContext()).getAppSessionManager().getActiveSession();
WebObjectSource objectSource = iSession.getFactory().getObjectSource();

How can we get access to the PageComponent object from inside an event handler?

WebComponent wc = getEventTarget(keys);
AppContext ac = (AppContext) wc.getBeanContext();
PageComponent pc = ac.getCurrentPage();

What classes do I have to import?

import com.microstrategy.utils.log.Level;
import com.microstrategy.web.app.tags.Log;
import com.microstrategy.web.beans.BeanFactory;
import com.microstrategy.web.beans.MarkupOutput;
import com.microstrategy.web.beans.RequestKeys;
import com.microstrategy.web.beans.UserBean;
import com.microstrategy.web.beans.UserGroupBean;
import com.microstrategy.web.objects.WebAccessControlEntry;
import com.microstrategy.web.objects.WebDisplayUnits;
import com.microstrategy.web.objects.WebDisplayUnit;
import com.microstrategy.web.objects.WebExpression;
import com.microstrategy.web.objects.WebFolder;
import com.microstrategy.web.objects.WebAttribute;
import com.microstrategy.web.objects.WebObjectSecurity;
import com.microstrategy.web.objects.WebAccessControlList;
import com.microstrategy.web.objects.WebIServerSession;
import com.microstrategy.web.objects.WebObjectInfo;
import com.microstrategy.web.objects.WebObjectSource;
import com.microstrategy.web.objects.WebObjectsException;
import com.microstrategy.web.objects.WebObjectsFactory;
import com.microstrategy.web.objects.WebProject;
import com.microstrategy.web.objects.WebSearch;
import com.microstrategy.web.objects.WebSubscriptionAddress;
import com.microstrategy.web.objects.admin.users.WebMDSecurityFilter;
import com.microstrategy.web.objects.admin.users.WebPrivilegeCategories;
import com.microstrategy.web.objects.admin.users.WebPrivilegeCategory;
import com.microstrategy.web.objects.admin.users.WebPrivilegeEntry;
import com.microstrategy.web.objects.admin.users.WebSimpleSecurityPluginLoginInfo;
import com.microstrategy.web.objects.admin.users.WebStandardLoginInfo;
import com.microstrategy.web.objects.admin.users.WebSubscriptionUserAddresses;
import com.microstrategy.web.objects.admin.users.WebUser;
import com.microstrategy.web.objects.admin.users.WebUserEntity;
import com.microstrategy.web.objects.admin.users.WebUserGroup;
import com.microstrategy.web.objects.admin.users.WebUserSecurityFilters;
import com.microstrategy.web.platform.ContainerServices;
import com.microstrategy.web.tasks.AbstractBaseTask;
import com.microstrategy.web.tasks.TaskException;
import com.microstrategy.web.tasks.TaskParameterMetadata;
import com.microstrategy.web.tasks.TaskRequestContext;
import com.microstrategy.webapi.EnumDSSXMLAccessEntryType;
import com.microstrategy.webapi.EnumDSSXMLAccessRightFlags;
import com.microstrategy.webapi.EnumDSSXMLAuthModes;
import com.microstrategy.webapi.EnumDSSXMLFolderNames;
import com.microstrategy.webapi.EnumDSSXMLObjectSubTypes;
import com.microstrategy.webapi.EnumDSSXMLObjectTypes;
import com.microstrategy.webapi.EnumDSSXMLSearchDomain;
import com.microstrategy.webapi.EnumDSSXMLSubscriptionDeliveryType;

What are some of the things that I should examine?

session.getFactory().getAssociatedScheduleSource();
session.getFactory().getClusterSource();
session.getFactory().getDocumentSource();
session.getFactory().getInboxSource();
session.getFactory().getLicenseSource();
session.getFactory().getMonitorSource(arg0);
session.getFactory().getObjectLockSource();
session.getFactory().getMDUpdateSource();
session.getFactory().getObjectSource();
session.getFactory().getProjectSource();
session.getFactory().getReportSource();
session.getFactory().getRWSource();
session.getFactory().getScheduleSource();
session.getFactory().getSubscriptionsSource();

How can we create an admin session?

private static WebIServerSession getAdminWebIServerSession(String server, String project, int port, String uid,String pwd, ContainerServices cntSvcs) throws WebObjectsException {
    WebIServerSession iSession = WebObjectsFactory.getInstance().getIServerSession(); 
    iSession.setServerName(server); 
    //iSession.setProjectName(project);
    iSession.setServerPort(port); 
    iSession.setLogin(uid); 
    iSession.setPassword(pwd);
    iSession.setAuthMode(EnumDSSXMLAuthModes.DssXmlAuthStandard);  
    iSession.getSessionID();
    return iSession;
}
WebIServerSession adminWebIServerSession = getAdminWebIServerSession(data.server, data.project, 0, data.admin, data.adminPassword, context.getContainerServices());

How can we obtain an admin web object source from an admin session?

WebObjectSource adminWOS = adminWebIServerSession.getFactory().getObjectSource();

How can we create a normal session?

/*
 * In MicroStrategy 8, there is only one type of session.  In MicroStrategy 9, there are two types
 * of sessions (admin and regular).  When we follow the instruction in TN31205 and TN31464, and we 
 * remove the iSession.setProjectName(project) from getAdminIServerSession, we can no longer obtain
 * the projectID from the admin IServer session.  We can go back to establishing 2 IServer sessions
 * (one regular session, and one admin session) like we did before.  We can also modify the application
 * code to store the project ID and pass the project ID to this custom task.  We can also follow
 * instruction in TN35228 (which is the approach being used here).  See MicroStrategy support case
 * ID 633095.
 */
import com.microstrategy.web.objects.WebIServerSession;

private WebIServerSession getNormalWebIServerSession(String server, String project, int port, String uid,String pwd, ContainerServices cntSvcs) throws WebObjectsException {
    WebIServerSession iSession = WebObjectsFactory.getInstance().getIServerSession(); 
    iSession.setServerName(server); 
    iSession.setProjectName(project);
    iSession.setServerPort(port); 
    iSession.setLogin(uid); 
    iSession.setPassword(pwd);
    iSession.setAuthMode(EnumDSSXMLAuthModes.DssXmlAuthStandard);  
    iSession.getSessionID();
    return iSession;
}

WebIServerSession normalWebIServerSession = getNormalWebIServerSession(data.server, data.project, 0, data.admin, data.adminPassword,context.getContainerServices());

How can we get a normal web object source object from a normal session?

WebObjectSource normalWOS = normalWebIServerSession.getFactory().getObjectSource();

What is the difference between getAdminWebIServerSession and getNormalWebIServerSession?

getNormalWebIServerSession invokes iSession.setProjectName(project) but getAdminWebIServerSession does not.

How can we obtain the ID of the "Shared Reports" folder?

import com.microstrategy.web.objects.WebIServerSession;
import com.microstrategy.web.objects.WebFolder;
import com.microstrategy.webapi.EnumDSSXMLFolderNames;
import com.microstrategy.webapi.EnumDSSXMLObjectTypes;
import com.microstrategy.web.objects.WebObjectSource;
import com.microstrategy.web.objects.WebObjectsException;

// Assume that serverSession and objSource can be created.  Look at the code inside SessionManagementSample to see
// how we can create a server session.
WebIServerSession serverSession = SessionManagementSample.getSession();
WebObjectSource objSource = serverSession.getFactory().getObjectSource();

// Obtain ID for Shared Reports Folder and populate WebFolder Setting
String sharedReportsFolderID = objSource.getFolderID(EnumDSSXMLFolderNames.DssXmlFolderNamePublicReports);

Notice that EnumDSSXMLFolderNames.DssXmlFolderNamePublicReports is a string constant, and it is being passed to the getFolderID method of the WebObjectSource class.

How can we obtain the folder object given its ID?

String sharedReportsFolderID = "...";
WebFolder folder = (WebFolder) objSource.getObject(sharedReportsFolderID, EnumDSSXMLObjectTypes.DssXmlTypeFolder);

How can we create a new folder?

WebFolder folder = (WebFolder)objSource.getNewObject(EnumDSSXMLObjectTypes.DssXmlTypeFolder, folderName);
objSource.save(folder, folder.getName());

How can we save a folder to a different location?

Instead of using the save method as above, use the saveAs method:

objSource.saveAs(folder, folder.getName(), parentFolder, true);

How can we give access to a folder for a given group or a user?

private void giveGroupAccessToClientSharedReportFolder(WebObjectSource source, RequestData data, WebUser user, WebIServerSession session, WebFolder folder) throws Exception {
    String methodName = "giveGroupAccessToClientSharedReportFolder";
    Log.logger.logp(Level.INFO,  CreateCustomJavaSecurityFilter.class.getName(), methodName, methodName + " invoked!");

    String folderName = folder.getName();
    WebObjectSecurity wos = folder.getSecurity();
    WebAccessControlList acl = wos.getACL();

    boolean mustBeAdded = true;

    for (int i=0; i<acl.size(); i++){
        WebAccessControlEntry wace = acl.get(i);

        //gets the users/group under Security for this object

        //get the rights for each user/group
        Log.logger.logp(Level.INFO,  CreateCustomJavaSecurityFilter.class.getName(), methodName, "Trustee:" + wace.getTrustee().getDisplayName());
        Log.logger.logp(Level.INFO,  CreateCustomJavaSecurityFilter.class.getName(), methodName, "Rights:" + wace.getRights());

        String trusteeName = wace.getTrustee().getDisplayName();
        if (trusteeName.equalsIgnoreCase("Everyone") || trusteeName.equalsIgnoreCase("Public / Guest")) {
            wace.setRights(0);
        } else if (trusteeName.equalsIgnoreCase(data.groupName)) {
            wace.setRights(EnumDSSXMLAccessRightFlags.DssXmlAccessRightFullControl);
            mustBeAdded = false;
        }

        //change acl to modify for all group/users
        //acl.get(i).setRights(223);
        //source.save(woi);
    }
    if (mustBeAdded) {
        WebAccessControlEntry wace = acl.add(EnumDSSXMLAccessEntryType.DssAccessEntryTypeObject);
        WebUserEntity group = (WebUserEntity) checkIfExists(source, data.groupName, EnumDSSXMLObjectSubTypes.DssXmlSubTypeUserGroup);
        wace.setTrustee(group);
        wace.setRights(EnumDSSXMLAccessRightFlags.DssXmlAccessRightFullControl);
    }
    source.save(folder);
}

The above code give access to a folder for a group. To give access to a folder for a user, the process is the same. We just have to find the user.

How can we give access to an attribute for a group or user?

The process the the same as giving access to a folder for a group or user. See TN47607

If we need to deal with something that look likes mstrWeb.5110, what may this be?

This may represent a message. To determine the string that it represents:

  1. Launch Web Customization Editor
  2. Drill down on Properties Files -> WEBINF -> classes -> resources
  3. Double click on MessageBundle_en_US.properties

How can we change a text string or do localization?

  1. Launch Web Customization Editor
  2. Drill down on Properties Files -> WEBINF -> classes -> resources
  3. Double click on MessageBundle_en_US.properties

What is the format of the MessageBundle files?

The default format is UniqueID=Text. The default format for MicroStrategy-provided values is mstrWeb.n where n is a unique sequential number. You can use a format such as scenario1.n as well.

Can I add my own entry into the message bundle file?

Yes.

  1. Launch Web Customization Editor
  2. Drill down on Properties Files -> WEBINF -> classes -> resources
  3. Double click on MessageBundle_en_US.properties
  4. Enter a new property-value pair in the text field at the bottom conforming to the syntax nameOfProperty=value
  5. Click on the Add button
  6. Click on the Save icon in the top toolbar.

How can I display my message inside a JSP page?

<web:descriptor key="scenario1.1" desc="..." ucase="true"/>

The key attribute is required. The desc and ucase attributes are optional. The purpose of the desc is for developer readability. The ucase attribute display the message in uppercase letters if it is set to true.

What is the Web Customization Editor?

It is a plugin for Eclipse provided by MicroStrategy. See the documentation for setting up your SDK environment elsewhere on this page.

How can we launch the Web Customization Editor?

  1. Launch your Eclipse
  2. Click on the Web Customization Editor Perspective. It should be on the top right hand corner of the screen.

What is the difference between WebSessionInfo and WebIServerSession?

The WebSessionInfo is probably for dealing with the session object between the browser and the MSTR Web server, and WebIServerSession is probably for dealing with the session object between the MSTR Web server with the MSTR Intelligence server.

How can we get a WebSessionInfo object from a ObjectBean object?

WebSessionInfo session = ob.getSessionInfo();

What is ContainerServices?

ContainerServices is a handy object that MicroStrategy Web made available to the SDK. Through the ContainerServices object, we have access to all the functionalities offered by the application container. This includes:

  • Ability to add / update browser cookie.
  • Access to HTTP headers
  • Access to the output stream
  • Access to posted files
  • Access the query string
  • Access to session information
  • Do redirect
  • Ability to determine the root of the application

See the SDK documentation for details.

How can we work with browser cookie?

if (webApp != null) {
    Log.logger.logp(Level.INFO, CustomSSO.class.getName(), methodName, "webApp is not null.  webApp:" + webApp + ".  Storing it into cookie name webAppCookie.");
    GenericCookie gc = cntSvcs.newCookie("webAppCookie", webApp);
    cntSvcs.addCookieToResponse(gc);
} else {
    Log.logger.logp(Level.INFO, CustomSSO.class.getName(), methodName, "webApp is not found in request keys. Trying to see if webApp can be retrieve from cookie named webAppCookie.");
    GenericCookie cookie = cntSvcs.getCookie("webAppCookie");
    if (cookie != null) {
        webApp = cookie.getValue();
        Log.logger.logp(Level.INFO, CustomSSO.class.getName(), methodName, "webAppCookie is present.  webApp:" + webApp);
    } else {
        Log.logger.logp(Level.INFO, CustomSSO.class.getName(), methodName, "webAppCookie is not present.");
    }
}

if (loginURL != null) {
    Log.logger.logp(Level.INFO, CustomSSO.class.getName(), methodName, "loginURL is not null.  loginURL:" + loginURL + ".  Storing it into cookie name loginURLCookie.");
    GenericCookie gc2 = cntSvcs.newCookie("loginURLCookie", loginURL);
    cntSvcs.addCookieToResponse(gc2);            
} else {
    GenericCookie cookie = cntSvcs.getCookie("loginURLCookie");
    if (cookie != null) {
        loginURL = cookie.getValue();
        Log.logger.logp(Level.INFO, CustomSSO.class.getName(), methodName, "loginURLCookie is present.  loginURL:" + loginURL);
    } else {
        Log.logger.logp(Level.INFO, CustomSSO.class.getName(), methodName, "loginURLCookie is not present.");
    }

}

How can we iterate through all the beans on a page?

public class ModifyEmailSubject extends AbstractAppAddOn {
    private SubscriptionEditorBean seb;
    private SubscriptionBean sb;
    private RWBean rwb;

    public String getAddOnDescription() {
        return "This add-on will add custom text into the subject field.";
    }

    public void postCollectData(PageComponent page) {
        seb = getSubscriptionEditorBean(page);
        rwb = (RWBean) page.getChildByClass(RWBean.class);

        if (seb.isOpen()) {
            try {
                sb = seb.getSubscriptionBean();
                WebSubscription ws = sb.getSubscription();
                WebSubscriptionDeliveryModeEmailProperties emailProp = (WebSubscriptionDeliveryModeEmailProperties) ws.getDeliveryMode();

                // Default subject is the report name
                String prevSubject = rwb.getObjectName();
                emailProp.setEmailSubject(" "+prevSubject);

                sb.collectData();
            } catch (WebBeanException e) {
                e.printStackTrace();
            }
        }
        return;
    }

    private SubscriptionEditorBean getSubscriptionEditorBean(WebComponent wc) {
        SubscriptionEditorBean result = null;
        // There are multiple SubscriptionEditorBeans on the page; recursively iterate through all of the page beans to retrieve the correct bean
        if (wc instanceof SubscriptionEditorBean) {
            if (wc.getName().equals("ncSendNow")) result = (SubscriptionEditorBean) wc;
        } else {
            for (int i = 0; i < wc.getChildCount(); i++) {
                result = getSubscriptionEditorBean(wc.getChild(i));
                if (result != null) break;
            }
        }
        return result;
    }
}

In the above code, getSubscriptionEditorBean is a recursive method. It call itself until it find a SubscriptionEditorBean. It seems to only find the first instance of SubscriptionEditorBean rather than all instances.

Some useful code:

WebObjectInfo woi = objectSource.getObject(ob.getObjectID(), EnumDSSXMLObjectTypes.DssXmlTypeReportDefinition);
woi.populate();

rb.populateObject(woi);
WebReportInstance wri = rb.getReportInstance();
WebReportInstance wri = reportSource.getInstanceFromSubscription(sub);

WebViewInstance wvi = rb.getViewBean().getViewInstance();
wri.setAsync(true);
wri.pollStatus();
WebReportManipulation wrm = wri.getReportManipulator();
WebTemplate wt =  wvi.getTemplate();
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License