Sample 32960: How to Build a Portlet That Displays an OLAP Table View
Overview
This sample shows how to create a portlet project that uses an OLAPTableViewComposite in order to provide a live view of an OLAP table within a Portal page. The sample creates an editable portlet that includes a selector that enables a user to choose either an OLAP information map or an OLAP data exploration as a data source.
The portlet uses the VisualDataExplorer as a helper class in order to instantiate the model. Although this portlet enables you to open a data exploration, the portlet retrieves only the OLAP query that is stored in the default bookmark of the data exploration. The portlet always displays an OLAP table even if the data exploration includes a graph instead. If needed, the code could be extended in a similar manner in order to display graphs.
Notes
This portlet uses the SAS Java component classes, which require an SAS® AppDev Studio license in order to use in a custom application. If you only license SAS® Information Delivery Portal, you can add a license for SAS AppDev Studio in order to use this sample.
This sample demonstrates how to add an OLAP table to a Portal page. If the portlet displays an OLAP query that takes a long time to process, the Portal page will be slow to render. If you experience performance problems with a view of the data, then test the information map or data exploration within the Portal Visual Data Explorer. If the performance is similar there, then you might need to tune the OLAP cube in order to improve performance.
The sample is based on a SAS Java Project that uses the SAS Information Delivery Portal JSP Portlet template that is available in SAS AppDev Studio. The Full Code tab in this sample contains instructions on modifying the template project.
Additional Documentation
- For a list of samples for common tasks, see SAS Note 32218.
- The SAS AppDev Studio Developer's Site contains detailed information that will assist you when developing Web applications with SAS AppDev Studio, including an API reference and the custom tag reference for the sas tagset.
These sample files and code examples are provided by SAS Institute
Inc. "as is" without warranty of any kind, either express or implied, including
but not limited to the implied warranties of merchantability and fitness for a
particular purpose. Recipients acknowledge and agree that SAS Institute shall
not be liable for any damages whatsoever arising out of their use of this material.
In addition, SAS Institute will provide no support for the materials contained herein.
Instructions
- Build a new SAS Java Project in SAS AppDev Studio named olapTablePortlet using the SAS Information Delivery Portal JSP Portlet template. Use the default settings in the template definition. We will replace the generated files with the code below.
- Replace the portlet.xml file with the portlet.xml code located below.
- Create a new package in the src directory named com.sas.ts.example.portlet.olaptableview. Create the following new Java classes, using the code below: BaseAction.java, CancelAction.java, DisplayAction.java, EditorAction.java, ErrorHandler.java, Initializer.java, OkAction.java, and SessionBindingListener.java
- Add a file named Resources.properties to the package directory using the code below
- Delete the index.jsp file from the content directory in the project.
- Create new JSP pages named Error.jsp, Viewer.jsp, and Editor.jsp in the content directory using the code below.
- Once completed, the project structure should look like this in the Eclipse package editor window.
- Package the par file and deploy it to the Portal to test.
Code for portlet.xml
<!DOCTYPE portlets SYSTEM "http://www.sas.com/idp/portlet.dtd">
<portlets>
<local-portlet name="olapTablePortlet" title="olapTablePortlet" icon="images/icon.gif" editorType="portlet" showEditProperties="true" >
<localized-resources locales="en"/>
<deployment scope="user" autoDeploy="false" userCanCreateMore="true">
</deployment>
<initializer-type>com.sas.ts.example.portlet.olaptableview.Initializer</initializer-type>
<init-param>
<param-name>error-page</param-name>
<param-value>Error.jsp</param-value>
</init-param>
<init-param>
<param-name>display-page</param-name>
<param-value>Viewer.jsp</param-value>
</init-param>
<init-param>
<param-name>edit-page</param-name>
<param-value>Editor.jsp</param-value>
</init-param>
<init-param>
<param-name>default-folder</param-name>
<param-value>SBIP://Foundation/BIP Tree(Folder)</param-value>
</init-param>
<error-handler>
<type>com.sas.ts.example.portlet.olaptableview.ErrorHandler</type>
</error-handler>
<portlet-path>/sas/portlets</portlet-path>
<portlet-actions>
<portlet-action name="display" default="true" >
<type>com.sas.ts.example.portlet.olaptableview.DisplayAction</type>
</portlet-action>
<portlet-action name="editor" editor="true" >
<type>com.sas.ts.example.portlet.olaptableview.EditorAction</type>
</portlet-action>
<portlet-action name="ok" default="false" >
<type>com.sas.ts.example.portlet.olaptableview.OkAction</type>
</portlet-action>
<portlet-action name="cancel" default="false" >
<type>com.sas.ts.example.portlet.olaptableview.CancelAction</type>
</portlet-action>
</portlet-actions>
</local-portlet>
</portlets>
|
Code for BaseAction.java
package com.sas.ts.example.portlet.olaptableview;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sas.portal.Logger;
import com.sas.portal.container.deployment.PortletActionInfoInterface;
import com.sas.portal.portlet.NavigationUtil;
import com.sas.portal.portlet.PortletActionInterface;
import com.sas.portal.portlet.PortletContext;
public abstract class BaseAction implements PortletActionInterface
{
private final String _loggingContext = this.getClass().getName();
private PortletActionInfoInterface _actionInfo = null;
public String service(HttpServletRequest request,
HttpServletResponse response,
PortletContext context) throws Exception
{
response.setContentType("text/html;charset=UTF-8");
// prepare the localized resources for use by the jsp.
// Resources.properties file should reside in package directory by default
try {
NavigationUtil.prepareLocalizedResources(Initializer.RESOURCE_FILE, request, context);
}
catch (java.io.IOException ioe) {
Logger.error(ioe.getMessage(), _loggingContext, ioe);
ioe.printStackTrace();
}
errorCheck(context);
return null;
}
public final void setInfo(PortletActionInfoInterface info)
{
_actionInfo = info;
}
public final PortletActionInfoInterface getInfo()
{
return _actionInfo;
}
protected static final void errorCheck(PortletContext context) throws Exception
{
Exception e = (Exception)context.getAttribute(Initializer.PORTLET_EXCEPTION_KEY);
if (e != null) { throw e; }
}
}
|
Code for CancelAction.java
package com.sas.ts.example.portlet.olaptableview;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sas.portal.Logger;
import com.sas.portal.portlet.PortletContext;
public final class CancelAction extends BaseAction {
private final String _loggingContext = this.getClass().getName();
public String service(HttpServletRequest request,
HttpServletResponse response, PortletContext context)
throws Exception {
super.service(request, response, context);
Logger.debug("PortletContext: " + context.getId(), _loggingContext);
// remove the temporary map name parameter used by the Edit action
context.removeAttribute(Initializer.NEW_MAP_NAME_KEY);
return context.resolveURLForActionName("display");
}
}
|
Code for DisplayAction.java
package com.sas.ts.example.portlet.olaptableview;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.sas.actionprovider.HttpActionProvider;
import com.sas.iquery.metadata.business.DataSelection;
import com.sas.portal.Logger;
import com.sas.portal.portlet.PortletContext;
import com.sas.services.session.SessionContextInterface;
import com.sas.servlet.tbeans.dataexplorer.html.VisualDataExplorer;
import com.sas.servlet.tbeans.html.AppliedFilters;
import com.sas.servlet.tbeans.olaptableview.html.OLAPTableViewComposite;
import com.sas.storage.iquery.BusinessQueryToOLAPDataSetAdapter;
import com.sas.web.keys.CommonKeys;
public final class DisplayAction extends BaseAction {
private final String _loggingContext = this.getClass().getName();
public String service(HttpServletRequest request,
HttpServletResponse response, PortletContext context)
throws Exception {
super.service(request, response, context);
Logger.debug("PortletContext: " + context.getId()
+ " - Begin DisplayAction ", _loggingContext);
errorCheck(context);
String ACTION_PROVIDER = (String) context
.getAttribute(Initializer.OLAP_ACTION_PROVIDER_KEY);
String displayActionURL = com.sas.portal.portlet.NavigationUtil
.buildBaseURL(context, request, "display");
HttpSession session = context.getHttpSession();
// Setup the ActionProvider
HttpActionProvider actionProvider = null;
synchronized (session) {
if (session != null) {
actionProvider = (HttpActionProvider) session
.getAttribute(ACTION_PROVIDER);
}
// if ActionProvider is null, create one and put it on the session
if (actionProvider == null) {
actionProvider = new HttpActionProvider();
actionProvider.setLocale(request.getLocale());
actionProvider.setControllerURL(displayActionURL);
actionProvider.setName(ACTION_PROVIDER);
// store object in its scope
if (session != null)
session.setAttribute(ACTION_PROVIDER, actionProvider);
}
// else execute the ActionProvider command
else {
actionProvider.executeCommand(request, response, response
.getWriter());
}
}
synchronized (session) {
// Setup the Business Query model adapter
BusinessQueryToOLAPDataSetAdapter adapter = null;
if (session != null) {
adapter = (BusinessQueryToOLAPDataSetAdapter) context
.getAttribute(Initializer.OLAP_MODEL_KEY);
}
if (adapter == null) {
try {
SessionContextInterface sessionContext = (SessionContextInterface) session
.getAttribute(CommonKeys.SESSION_CONTEXT);
String mapName = (String) context
.getAttribute(Initializer.MAP_NAME_KEY);
Logger.debug("PortletContext: " + context.getId()
+ " Map Name: " + mapName, _loggingContext);
if (mapName == null || mapName.trim().equals("")) {
context.setAttribute(Initializer.NO_DATA_WARNING,
"true");
} else {
VisualDataExplorer vde = new VisualDataExplorer(
sessionContext, mapName);
if (!vde.isOLAP()) {
context.setAttribute(
Initializer.NON_OLAP_DATA_WARNING, "true");
vde.cleanUp();
} else {
DataSelection dataSelection = (DataSelection) vde
.getDataModel();
adapter = new BusinessQueryToOLAPDataSetAdapter();
adapter.setModel(dataSelection);
context.setAttribute(Initializer.OLAP_MODEL_KEY,
adapter);
AppliedFilters appliedFilters = new AppliedFilters();
appliedFilters.setModel(dataSelection);
appliedFilters.setNoFilterTextDisplayed(false);
context.setAttribute( Initializer.OLAP_FILTERS_KEY, appliedFilters);
OLAPTableViewComposite olapTableView = new OLAPTableViewComposite();
olapTableView.setModel(adapter);
olapTableView.setActionProvider(actionProvider);
context.setAttribute(Initializer.OLAP_TABLE_KEY,
olapTableView);
String sessionBinderKey = (String) context
.getAttribute(Initializer.SESSION_BINDER_KEY);
SessionBindingListener sessionBinder = (SessionBindingListener) session
.getAttribute(sessionBinderKey);
sessionBinder.addOLAPAdapter(adapter);
}
}
} catch (Exception e) {
Logger.error("PortletContext: " + context.getId()
+ " Error creating olap table or models "
+ e.getMessage(), _loggingContext);
context.setAttribute(Initializer.PORTLET_EXCEPTION_KEY, e);
throw e;
}
}
}
return (String) context.getAttribute(Initializer.DISPLAY_PAGE_KEY);
}
}
|
Code for EditorAction.java
package com.sas.ts.example.portlet.olaptableview;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.sas.actionprovider.HttpAction;
import com.sas.actionprovider.HttpActionProvider;
import com.sas.actionprovider.support.ActionProviderSupportTypes;
import com.sas.actionprovider.support.remotefileselector2.HttpRemoteFileSelectorTableViewSupport;
import com.sas.portal.Logger;
import com.sas.portal.portlet.NavigationUtil;
import com.sas.portal.portlet.PortletContext;
import com.sas.services.information.RepositoryInterface;
import com.sas.services.session.SessionContextInterface;
import com.sas.servlet.tbeans.remotefileselector2.RemoteFileSelectorKeysInterface;
import com.sas.servlet.tbeans.remotefileselector2.html.InformationServicesSearch;
import com.sas.servlet.tbeans.remotefileselector2.html.InformationServicesSelector;
import com.sas.swing.models.remotefileselector2.informationservices.BaseInformationServicesModel;
import com.sas.swing.models.remotefileselector2.informationservices.InformationServicesNavigationModel;
import com.sas.web.keys.CommonKeys;
public final class EditorAction extends BaseAction
{
private final String _loggingContext = this.getClass().getName();
public String service(HttpServletRequest request,
HttpServletResponse response,
PortletContext context) throws Exception
{
super.service(request, response, context);
Logger.debug("EditorAction - Context: " + context.getId(), _loggingContext);
//create the URLs for the OK and Cancel buttons.
String EDIT_OK_URL = NavigationUtil.buildBaseURL(context, request, "ok");
context.setAttribute(Initializer.EDIT_OK_URL_KEY, EDIT_OK_URL);
String EDIT_CANCEL_URL = NavigationUtil.buildBaseURL(context, request, "cancel");
context.setAttribute(Initializer.EDIT_CANCEL_URL_KEY, EDIT_CANCEL_URL);
String EDIT_URL = com.sas.portal.portlet.NavigationUtil
.buildBaseURL(context, request, "editor");
String EDIT_ACTION_PROVIDER = (String)context.getAttribute(Initializer.EDIT_ACTION_PROVIDER_KEY);
HttpSession session = context.getHttpSession();
HttpActionProvider editActionProvider = null;
synchronized (session) {
if (session != null){
editActionProvider = (HttpActionProvider)session.getAttribute(EDIT_ACTION_PROVIDER);
}
//if ActionProvider is null, create one and put it on the session
if (editActionProvider == null) {
editActionProvider = new HttpActionProvider();
editActionProvider.setLocale(request.getLocale());
editActionProvider.setControllerURL(EDIT_URL);
editActionProvider.setName(EDIT_ACTION_PROVIDER);
// store object in its scope
if (session != null)
session.setAttribute(EDIT_ACTION_PROVIDER, editActionProvider);
}
//else execute the ActionProvider command
else{
editActionProvider.executeCommand(request, response, response.getWriter());
}
}
synchronized (session) {
//Setup the InformationServicesSelector
InformationServicesSelector sas_informationSelector = null;
if (session != null){
sas_informationSelector = (InformationServicesSelector)context.getAttribute(Initializer.EDIT_INFO_SELECTOR_KEY);
}
if (sas_informationSelector == null){
try{
SessionContextInterface sessionContext = (SessionContextInterface) session
.getAttribute(CommonKeys.SESSION_CONTEXT);
//Get the repositories
List repos = sessionContext.getUserContext().getRepositories();
RepositoryInterface reposInt = (RepositoryInterface)repos.get(0);
String defaultFolder = (String)context.getAttribute(Initializer.DEFAULT_REPOSITORY_FOLDER_KEY);
sas_informationSelector = new InformationServicesSelector(reposInt, defaultFolder, null);
sas_informationSelector.setActionProvider(editActionProvider);
List filterList = new ArrayList();
filterList.add("InformationMap");
filterList.add("DataExploration");
((InformationServicesNavigationModel)sas_informationSelector.getModel()).setFilterValues(filterList);
((BaseInformationServicesModel)((InformationServicesSearch)sas_informationSelector.getComponent(
RemoteFileSelectorKeysInterface.RFS_SEARCH)).getModel()).setFilterValues(filterList);
HttpAction action = (HttpAction)editActionProvider.getDefaultAction(
ActionProviderSupportTypes.REMOTE_FILE_SELECTOR2_COMPOSITE_SUPPORT,
HttpRemoteFileSelectorTableViewSupport.DATA_CELL_AREA,
HttpRemoteFileSelectorTableViewSupport.SELECT_FILE_ACTION);
action.setURLBase(EDIT_URL);
context.setAttribute(Initializer.EDIT_INFO_SELECTOR_KEY, sas_informationSelector);
}catch( Exception e ){
e.printStackTrace();
context.setAttribute(Initializer.PORTLET_EXCEPTION_KEY, e);
}
}
}
String newMapParam = request.getParameter(Initializer.NEW_MAP_PARAM);
if( null != newMapParam ){
Logger.debug("PortletContext: " + context.getId()
+ " Selected map value: " + newMapParam, _loggingContext);
context.setAttribute(Initializer.NEW_MAP_NAME_KEY, newMapParam );
}
else{
// Retrieve existing selection
String mapParam = (String)context.getAttribute(Initializer.MAP_NAME_KEY);
context.setAttribute(Initializer.NEW_MAP_NAME_KEY, mapParam );
}
// the following call resets the mode back to display for the next call
context.resetMode();
return (String)context.getAttribute(Initializer.EDIT_PAGE_KEY);
}
}
|
Code for ErrorHandler.java
package com.sas.ts.example.portlet.olaptableview;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sas.portal.Logger;
import com.sas.portal.portlet.ErrorHandlerInterface;
import com.sas.portal.portlet.NavigationUtil;
import com.sas.portal.portlet.PortletContext;
public class ErrorHandler implements ErrorHandlerInterface {
private final String _loggingContext = this.getClass().getName();
public String service(HttpServletRequest request,
HttpServletResponse response, PortletContext context,
Exception thrownException) {
Logger.debug("ErrorHandler called", _loggingContext);
// prepare the localized resources for use by the jsp.
try {
NavigationUtil.prepareLocalizedResources(Initializer.RESOURCE_FILE,
request, context);
} catch (java.io.IOException ioe) {
Logger.error(ioe.getMessage(), _loggingContext, ioe);
ioe.printStackTrace();
}
Logger.debug(thrownException.getMessage(), _loggingContext,
thrownException);
String msg = thrownException.getMessage();
msg = msg == null ? "" : msg;
// make msg available for display on error jsp.
context.setAttribute("Exception_message", msg);
thrownException.printStackTrace();
// remove exception from context
context.removeAttribute(Initializer.PORTLET_EXCEPTION_KEY);
return (String) context.getAttribute("error-page");
}
}
|
Code for Initializer.java
package com.sas.ts.example.portlet.olaptableview;
import java.text.MessageFormat;
import java.util.Properties;
import java.util.ResourceBundle;
import javax.servlet.http.HttpSession;
import com.sas.portal.Logger;
import com.sas.portal.portlet.PortletContext;
import com.sas.portal.portlet.PortletInitializerInterface;
import com.sas.portal.portlet.configuration.Attribute;
import com.sas.portal.portlet.configuration.Configuration;
import com.sas.portal.portlet.configuration.ConfigurationFactory;
import com.sas.services.session.SessionContextInterface;
import com.sas.web.keys.CommonKeys;
public class Initializer implements PortletInitializerInterface
{
private final String _loggingContext = this.getClass().getName();
public static final String LOGGER_KEY = "LOGGER";
public static final String RESOURCE_FILE = "com.sas.ts.example.portlet.olaptableview.Resources";
public static final String DISPLAY_PAGE_KEY = "display-page";
public static final String ERROR_PAGE_KEY = "error-page";
public static final String EDIT_PAGE_KEY = "edit-page";
public static final String DEFAULT_FOLDER_KEY = "default-folder";
public static final String EDIT_CANCEL_URL_KEY = "EDIT_CANCEL_URL";
public static final String EDIT_OK_URL_KEY = "EDIT_OK_URL";
public static final String PORTLET_EXCEPTION_KEY = "PORTLET_EXCEPTION";
public static final String MAP_NAME_KEY = "MAP_NAME";
public static final String NEW_MAP_NAME_KEY = "NEW_MAP_NAME";
public static final String OLAP_MODEL_KEY = "MODEL_ID";
public static final String OLAP_TABLE_KEY = "TABLE_ID";
public static final String OLAP_FILTERS_KEY = "APPLIED_FILTERS_ID";
public static final String OLAP_ACTION_PROVIDER_KEY = "OLAP_ACTION_PROVIDER_ID";
public static final String EDIT_ACTION_PROVIDER_KEY = "EDIT_ACTION_PROVIDER_ID";
public static final String EDIT_INFO_SELECTOR_KEY = "EDIT_INFO_SELECTOR_ID";
public static final String SESSION_BINDER_KEY = "SESSION_BINDER_ID";
public static final String DEFAULT_REPOSITORY_FOLDER_KEY = "REPOS_FOLDER";
public static final String NO_DATA_WARNING = "NO_DATA_SELECTED";
public static final String NON_OLAP_DATA_WARNING = "NON_OLAP_DATA_SELECTED";
public static final String NEW_MAP_PARAM="fullyQualifiedLocation";
public void initialize(Properties initProperties, PortletContext context)
{
try {
Configuration config = ConfigurationFactory.getConfiguration(context);
Attribute attr;
// retrive attributes from Configuration, and set them on Portlet context
attr = config.getAttribute(Initializer.MAP_NAME_KEY);
String mapName = (attr == null) ? "" : attr.getValue();
context.setAttribute(Initializer.MAP_NAME_KEY, mapName);
String defaultFolder = initProperties.getProperty(DEFAULT_FOLDER_KEY);
if( !mapName.equals("")){
defaultFolder = mapName.substring(0, mapName.lastIndexOf("/"))+"(Folder)";
Logger.debug("PortletContext: " + context.getId()+ " - Default folder: " + defaultFolder, _loggingContext);
}
context.setAttribute(DEFAULT_REPOSITORY_FOLDER_KEY, defaultFolder);
context.setAttribute(ERROR_PAGE_KEY, initProperties.getProperty(ERROR_PAGE_KEY));
context.setAttribute(DISPLAY_PAGE_KEY, initProperties.getProperty(DISPLAY_PAGE_KEY));
context.setAttribute(EDIT_PAGE_KEY, initProperties.getProperty(EDIT_PAGE_KEY));
// These attributes will be added to the session, so make their key unique
context.setAttribute(OLAP_ACTION_PROVIDER_KEY, OLAP_ACTION_PROVIDER_KEY + context.getId());
context.setAttribute(EDIT_ACTION_PROVIDER_KEY, EDIT_ACTION_PROVIDER_KEY + context.getId());
String sessionBinderKey = Initializer.SESSION_BINDER_KEY + context.getId();
context.setAttribute(Initializer.SESSION_BINDER_KEY,sessionBinderKey );
HttpSession session = context.getHttpSession();
SessionContextInterface sessionContext = (SessionContextInterface) session
.getAttribute(CommonKeys.SESSION_CONTEXT);
SessionBindingListener sessionBinder = (SessionBindingListener) session
.getAttribute(sessionBinderKey);
if (sessionBinder == null) {
sessionBinder = new SessionBindingListener(
sessionContext, context.getId());
session.setAttribute(sessionBinderKey, sessionBinder);
}
} catch (Exception e) {
e.printStackTrace();
context.setAttribute(Initializer.PORTLET_EXCEPTION_KEY, e);
}
}
protected Exception newException(String resource)
{
ResourceBundle rb = ResourceBundle.getBundle(Initializer.RESOURCE_FILE);
return new Exception(rb.getString(resource));
}
protected Exception newException(String resource, String arg1)
{
ResourceBundle rb = ResourceBundle.getBundle(Initializer.RESOURCE_FILE);
return new Exception(MessageFormat.format(rb.getString(resource), new Object[] {arg1}));
}
}
|
Code for OkAction.java
package com.sas.ts.example.portlet.olaptableview;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.sas.portal.Logger;
import com.sas.portal.portlet.PortletContext;
import com.sas.portal.portlet.configuration.Configuration;
import com.sas.portal.portlet.configuration.ConfigurationFactory;
public final class OkAction extends BaseAction {
private final String _loggingContext = this.getClass().getName();
public String service(HttpServletRequest request,
HttpServletResponse response, PortletContext context)
throws Exception {
super.service(request, response, context);
Logger.debug("Context: " + context.getId(), _loggingContext);
HttpSession session = context.getHttpSession();
String mapParam = (String) context
.getAttribute(Initializer.NEW_MAP_NAME_KEY);
if (null != mapParam) {
Logger.debug("PortletContext: " + context.getId()
+ " New map value: " + mapParam, _loggingContext);
context.setAttribute(Initializer.MAP_NAME_KEY, mapParam);
context.removeAttribute(Initializer.NEW_MAP_NAME_KEY);
if (session != null) {
String sessionBinderKey = (String) context
.getAttribute(Initializer.SESSION_BINDER_KEY);
SessionBindingListener sessionBinder = (SessionBindingListener) session
.getAttribute(sessionBinderKey);
sessionBinder.closeOLAPAdapter();
context.removeAttribute(Initializer.OLAP_MODEL_KEY);
context.removeAttribute(Initializer.OLAP_TABLE_KEY);
context.removeAttribute(Initializer.OLAP_FILTERS_KEY);
}
// persist the parameters to metadata
Configuration config = ConfigurationFactory
.getConfiguration(context);
config.setAttribute(Initializer.MAP_NAME_KEY, mapParam);
ConfigurationFactory.storeConfiguration(context, config);
}
// run the display action to display the portlet
return context.resolveURLForActionName("display");
}
}
|
Code for SessionBindingListener.java
package com.sas.ts.example.portlet.olaptableview;
import java.rmi.RemoteException;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import com.sas.iquery.dataretrieval.QueryConnector;
import com.sas.portal.Logger;
import com.sas.services.session.SessionContextInterface;
import com.sas.servlet.tbeans.dataexplorer.html.VisualDataExplorer;
import com.sas.storage.iquery.BusinessQueryToOLAPDataSetAdapter;
import com.sas.storage.olap.OLAPException;
public class SessionBindingListener implements HttpSessionBindingListener
{
private final String _loggingContext = this.getClass().getName();
private BusinessQueryToOLAPDataSetAdapter adapter = null;
private SessionContextInterface sessionContext;
private Object sessionLock;
private String contextID;
public SessionBindingListener( SessionContextInterface sessionContext, String contextID ) throws IllegalStateException, RemoteException{
this.contextID = contextID;
this.sessionContext = sessionContext;
sessionLock = this.sessionContext.lock(Initializer.LOGGER_KEY);
}
public void valueBound(HttpSessionBindingEvent event)
{
// No action needed.
}
public void valueUnbound(HttpSessionBindingEvent event)
{
closeOLAPAdapter();
closeOlapResources();
}
public void addOLAPAdapter( BusinessQueryToOLAPDataSetAdapter adapter ){
this.adapter = adapter;
}
public void closeOLAPAdapter( ){
if( null != adapter ){
try{
adapter.close();
Logger.debug("PortletContext: " + contextID + " - Closing OLAP Adapter", _loggingContext);
}catch( OLAPException oe ){
oe.printStackTrace();
}
}
adapter = null;
}
private void closeOlapResources(){
Logger.debug("PortletContext: " + contextID + " - Closing olap resources", _loggingContext);
QueryConnector connector = new QueryConnector();
try {
connector.closeResources(sessionContext,
QueryConnector.CloseOptions.ALL_CONNECTION_OPTIONS);
}catch( Exception e){
Logger.warn("PortletContext: " + contextID + " - Error Closing olap resources", _loggingContext);
e.printStackTrace();
}
try {
sessionContext.unlock(sessionLock);
sessionContext.destroy();
} catch (Exception e) {
// ignore session locked exceptions
}
sessionContext = null;
sessionLock = null;
}
}
|
Code for Resources.properties
# Localized Messages for the Portlet
viewer.olap.warning.nodata.txt=No data is selected. Please edit the portlet and select an olap information map or data exploration
viewer.olap.warning.nonolap.txt=The selected data is not olap. Please edit the portlet and select an olap information map or data exploration
viewer.dataerror.msg.txt=An error has occurred with the selected data: \"{0}\" <br> Please select a new data source
editor.action.message.txt=Choose an olap data exploration, or an olap information map:
editor.action.selectedmessage.txt=Currently selected:
editor.action.cancel.txt=Cancel
editor.action.ok.txt=Save
errorhandler.msg.txt=An error has occurred: \"{0}\"
|
Code for Editor.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
import="com.sas.portal.portlet.PortletContext,
com.sas.portal.portlet.PortletConstants,
com.sas.servlet.tbeans.remotefileselector2.html.InformationServicesSelector"
%>
<%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt"%>
<%
PortletContext context = (PortletContext) request
.getAttribute(PortletConstants.CURRENT_PORTLET_CONTEXT);
%>
<table class="dataEntryBG" border="0" cellpadding="0" cellspacing="0"
width="100%">
<tr>
<td> </td>
</tr>
<tr>
<td nowrap><fmt:message key="editor.action.message.txt" /></td>
</tr>
<tr>
<td> </td>
</tr>
<tr>
<td>
<table class="infoMessageBox" cellspacing="0" cellpadding="3">
<tr>
<td align="left" nowrap><fmt:message
key="editor.action.selectedmessage.txt" /> <%=context.getAttribute("NEW_MAP_NAME")%>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td> </td>
</tr>
<tr>
<td>
<%
InformationServicesSelector infoSelector = (InformationServicesSelector) context
.getAttribute("EDIT_INFO_SELECTOR_ID");
infoSelector.setRequest(request);
infoSelector.setResponse(response);
infoSelector.write(out);
%>
</td>
</tr>
<tr>
<td> </td>
</tr>
<tr>
<td> </td>
</tr>
<form name="editForm" method="post"
action="<%=context.getAttribute("EDIT_OK_URL") %>">
<tr class="buttonBar">
<td> <input class="button" type="submit"
value="<fmt:message key="editor.action.ok.txt"/>" name="submit">
<input class="button" type="submit"
value="<fmt:message key="editor.action.cancel.txt"/>" name="cancel"
onClick="cancelForm()"></td>
</tr>
</table>
</form>
<script language="JavaScript">
function cancelForm(){
editForm = document.getElementById("editForm" );
editForm.action="<%= context.getAttribute("EDIT_CANCEL_URL") %>";
return true;
}
</script>
|
Code for Error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
import="com.sas.portal.portlet.PortletContext,
com.sas.portal.portlet.PortletConstants"
%>
<%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt"%>
<%
PortletContext context = (PortletContext) request
.getAttribute(PortletConstants.CURRENT_PORTLET_CONTEXT);
%>
<table class="errorMessageBox" cellspacing="0" cellpadding="3"
width="100%">
<tr>
<td align="left" width="100%"><fmt:message
key="errorhandler.msg.txt">
<fmt:param><%=context.getAttribute("Exception_message")%></fmt:param>
</fmt:message></td>
</tr>
</table>
|
Code for Viewer.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
import="com.sas.portal.portlet.PortletContext,
com.sas.portal.portlet.PortletConstants,
com.sas.servlet.tbeans.olaptableview.html.OLAPTableViewComposite,
com.sas.servlet.tbeans.html.AppliedFilters"%>
<%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt"%>
<%@ taglib uri="http://www.sas.com/taglib/sas" prefix="sas"%>
<style>
<!--override the Portal syle for the table view menu bar -->
.menuItemContainer{
background-color: #FFFFFF;
}
</style>
<%
PortletContext context = (PortletContext) request
.getAttribute(PortletConstants.CURRENT_PORTLET_CONTEXT);
if (null != context.getAttribute("NO_DATA_SELECTED")) {
context.removeAttribute("NO_DATA_SELECTED");
%>
<fmt:message key="viewer.olap.warning.nodata.txt" />
<%
} else if (null != context.getAttribute("NON_OLAP_DATA_SELECTED")) {
context.removeAttribute("NON_OLAP_DATA_SELECTED");
%>
<fmt:message key="viewer.olap.warning.nonolap.txt" />
<%
} else {
//String table = (String)context.getAttribute("TABLE_ID");
try {
OLAPTableViewComposite olapTable = (OLAPTableViewComposite) context
.getAttribute("TABLE_ID");
olapTable.setRequest(request);
olapTable.setResponse(response);
AppliedFilters appliedFilters = (AppliedFilters) context
.getAttribute("APPLIED_FILTERS_ID");
// If filters are applied, write them out
if (!appliedFilters.getAppliedFilters(
appliedFilters.getModel()).equals("")) {
appliedFilters.write(out);
}
olapTable.write(out);
} catch (Exception e) {
e.printStackTrace();
%>
<table class="errorMessageBox" cellspacing="0" cellpadding="3"
width="100%">
<tr>
<td align="left" width="100%"><fmt:message
key="viewer.dataerror.msg.txt">
<fmt:param><%=e.getMessage()%></fmt:param>
</fmt:message></td>
</tr>
</table>
<%
}
}
%>
|
These sample files and code examples are provided by SAS Institute
Inc. "as is" without warranty of any kind, either express or implied, including
but not limited to the implied warranties of merchantability and fitness for a
particular purpose. Recipients acknowledge and agree that SAS Institute shall
not be liable for any damages whatsoever arising out of their use of this material.
In addition, SAS Institute will provide no support for the materials contained herein.
Portlet displaying an olap information map

Edit action of the portlet

Portlet after drilling and expanding

Portlet after clicking on menu bar

Portlet with filters applied

This sample demonstrates how to build a portlet that uses an OLAPTableViewComposite and enables the user to apply actions such as drill, expand, and filter in a portlet.
| Date Modified: | 2008-09-08 16:47:08 |
| Date Created: | 2008-08-13 12:58:14 |
Operating System and Release Information
| SAS System | SAS AppDev Studio | Microsoft® Windows® for x64 | 3.3 | | 9.1 TS1M3 SP4 | |
| Microsoft Windows 2000 Advanced Server | 3.3 | | 9.1 TS1M3 SP4 | |
| Microsoft Windows 2000 Datacenter Server | 3.3 | | 9.1 TS1M3 SP4 | |
| Microsoft Windows 2000 Server | 3.3 | | 9.1 TS1M3 SP4 | |
| Microsoft Windows 2000 Professional | 3.3 | | 9.1 TS1M3 SP4 | |
| Microsoft Windows NT Workstation | 3.3 | | 9.1 TS1M3 SP4 | |
| Microsoft Windows Server 2003 Datacenter Edition | 3.3 | | 9.1 TS1M3 SP4 | |
| Microsoft Windows Server 2003 Enterprise Edition | 3.3 | | 9.1 TS1M3 SP4 | |
| Microsoft Windows Server 2003 Standard Edition | 3.3 | | 9.1 TS1M3 SP4 | |
| Microsoft Windows XP Professional | 3.3 | | 9.1 TS1M3 SP4 | |
| Windows Vista | 3.3 | | 9.1 TS1M3 SP4 | |
| SAS System | SAS Information Delivery Portal | Microsoft® Windows® for x64 | 2.0 | | 9.1 TS1M3 SP4 | |
| Microsoft Windows 2000 Advanced Server | 2.0 | | 9.1 TS1M3 SP4 | |
| Microsoft Windows 2000 Datacenter Server | 2.0 | | 9.1 TS1M3 SP4 | |
| Microsoft Windows 2000 Server | 2.0 | | 9.1 TS1M3 SP4 | |
| Microsoft Windows 2000 Professional | 2.0 | | 9.1 TS1M3 SP4 | |
| Microsoft Windows NT Workstation | 2.0 | | 9.1 TS1M3 SP4 | |
| Microsoft Windows Server 2003 Datacenter Edition | 2.0 | | 9.1 TS1M3 SP4 | |
| Microsoft Windows Server 2003 Enterprise Edition | 2.0 | | 9.1 TS1M3 SP4 | |
| Microsoft Windows Server 2003 Standard Edition | 2.0 | | 9.1 TS1M3 SP4 | |
| Microsoft Windows XP Professional | 2.0 | | 9.1 TS1M3 SP4 | |
| Windows Vista | 2.0 | | 9.1 TS1M3 SP4 | |
| 64-bit Enabled AIX | 2.0 | | 9.1 TS1M3 SP4 | |
| 64-bit Enabled Solaris | 2.0 | | 9.1 TS1M3 SP4 | |
| HP-UX IPF | 2.0 | | 9.1 TS1M3 SP4 | |