/** * Copyright © 2002 The JA-SIG Collaborative. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the JA-SIG Collaborative * (http://www.jasig.org/)." * * THIS SOFTWARE IS PROVIDED BY THE JA-SIG COLLABORATIVE "AS IS" AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JA-SIG COLLABORATIVE OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * */ package org.jasig.portal.channels.iccdemo; import javax.naming.Context; import javax.naming.NamingException; import javax.naming.NotContextException; import org.jasig.portal.ChannelStaticData; import org.jasig.portal.ICCRegistry; import org.jasig.portal.PortalException; import org.jasig.portal.channels.BaseChannel; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jasig.portal.utils.DocumentFactory; import org.jasig.portal.utils.XSLT; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.ContentHandler; /* * This is a modified version of the CInlineFrame channel that uses inter-channel communications. * * @author Peter Kharchenko * @author Susan Bramhall * @version $Revision: 1.9.2.1 $ */ public class CViewer extends BaseChannel { private static final Log log = LogFactory.getLog(CViewer.class); private static final String sslLocation = "CInlineFrame/CInlineFrame.ssl"; private static final String historyFname="/portal/iccdemo/history"; private String currentURL = ""; public void setStaticData(ChannelStaticData sd) throws PortalException { super.setStaticData(sd); // bind viewer url object to the jndi context // other channels will access this object to switch the url // find chan-obj context Context globalObjContext = null; try { globalObjContext = (Context)staticData.getJNDIContext().lookup("/channel-obj"); } catch (NotContextException nce) { log.error( "CHistory.getUserXML(): Could not find subcontext /channel-obj in JNDI"); } catch (NamingException e) { log.error("Failed lookup of /channel-obj", e); } // bind new ViewerURL object try { globalObjContext.bind(staticData.getChannelSubscribeId(),new ViewerURL(this)); } catch (NotContextException nce) { log.error( "CHistory.getUserXML(): Could not bind channel object for channel id="+staticData.getChannelSubscribeId()); } catch (NamingException e) { log.error("Failed bind", e); } // regsiter history channel /* * Remove History channel dependency (for course channel) * * registerHistory(); */ } /** * A utility method to register history channel as both listener * and instructor. */ private void registerHistory() { ICCRegistry r=staticData.getICCRegistry(); String historyId=getChannelId(historyFname); if(historyId!=null) { // register history as a listener r.addListenerChannel(historyId); // register hsitory as an event source as well r.addInstructorChannel(historyId); } } /** * Change URL that's being shown * * @param newURL a String value */ void changeURL(String newURL) { this.currentURL=newURL; // report to the history channel /* * Remove CHistory dependency * * addHistoryURL(newURL); */ } /** * An internal method to report new URL to the history's channel registry * * @param url a String value */ private void addHistoryURL(String url) { String historyId=getChannelId(historyFname); if(historyId!=null) { HistoryRecord hr=(HistoryRecord) getBoundObject(historyId); if(hr!=null) { hr.addHistoryRecord(url); } } } public void renderXML (ContentHandler out) throws PortalException { // get url from the jndi context (that object can be updated by both URL selector and history channels) String frameHeight = "600"; Document doc = DocumentFactory.getNewDocument(); // Create XML doc Element iframeE = doc.createElement("iframe"); /* * Remove History channel dependency for course channel * * // create warnings if the history channel can not be found * String historyId=getChannelId(historyFname); * if(historyId==null) { * Element warningEl=doc.createElement("warning"); * warningEl.appendChild(doc.createTextNode("Unable to find history channel (fname="+historyFname+"). Please subscribe to a history channel")); * iframeE.appendChild(warningEl); * } else { * Object bo=getBoundObject(historyId); * if(bo==null) { * Element warningEl=doc.createElement("warning"); * warningEl.appendChild(doc.createTextNode("History channel found, but no object was found bound in history's jndi context. Perhaps history should be moved to the same tab.")); * iframeE.appendChild(warningEl); * } * } */ Element urlE = doc.createElement("url"); urlE.appendChild(doc.createTextNode(currentURL)); iframeE.appendChild(urlE); Element heightE = doc.createElement("height"); heightE.appendChild(doc.createTextNode(frameHeight)); iframeE.appendChild(heightE); doc.appendChild(iframeE); XSLT xslt = XSLT.getTransformer(this, runtimeData.getLocales()); xslt.setXML(doc); xslt.setXSL(sslLocation, getStylesheetTitle(runtimeData.getBrowserInfo().getUserAgent()), runtimeData.getBrowserInfo()); xslt.setTarget(out); xslt.transform(); } /** * Uses the user agent string to determine which stylesheet title to use. * We wouldn't need this method if stylesheet sets could distinguish between browser versions * @param userAgent the user agent string * @return ssTitle the stylesheet title */ private String getStylesheetTitle (String userAgent) { String ssTitle = "noIFrameSupport"; if ((userAgent.indexOf("MSIE 3") >= 0) || (userAgent.indexOf("MSIE 4") >= 0) || (userAgent.indexOf("MSIE 5") >= 0) || (userAgent.indexOf("MSIE 6") >= 0) || (userAgent.indexOf("Mozilla/5") >= 0 || (userAgent.indexOf("Opera/6") >= 0))) { ssTitle = "IFrameSupport"; } return ssTitle; } /** * A utility method for obtaining a channelSubscribeId given a channel fname * * @param fname a String value * @return channel's subscribe id, or null if no channel with given fname was found */ private String getChannelId(String fname) { String id=null; Context globalIDContext = null; try { // Get the context that holds the global IDs for this user globalIDContext = (Context)staticData.getJNDIContext().lookup("/channel-ids"); } catch (NotContextException nce) { log.error( "CURLSelector.getUserXML(): Could not find subcontext /channel-ids in JNDI"); } catch (NamingException e) { log.error("Failed lookup /channel-ids", e); } try { id=(String)globalIDContext.lookup(fname); } catch (NotContextException nce) { log.error( "CURLSelector.getUserXML(): Could not find channel ID for fname="+fname); } catch (NamingException e) { log.error("Failed lookup " + fname, e); } return id; } /** * A utility method to determine an object bound to the "chan-obj" branch * for a particular channel id. * * @param channelSubscribeId a String value of the channel who's object we're looking for * @return an Object value bound to that jndi location (or null if channel didn't bind anything) */ private Object getBoundObject(String channelSubscribeId) { Object o=null; Context globalObjContext = null; try { globalObjContext = (Context)staticData.getJNDIContext().lookup("/channel-obj"); } catch (NotContextException nce) { log.error( "CURLSelector.getUserXML(): Could not find subcontext /channel-obj in JNDI"); } catch (NamingException e) { log.error("Failed lookup /channel-obj", e); } try { o=globalObjContext.lookup(channelSubscribeId); } catch (NotContextException nce) { log.error( "CURLSelector.getUserXML(): Could not find channel bound object for channel id="+channelSubscribeId); } catch (NamingException e) { log.error("Failed lookup " + channelSubscribeId, e); } return o; } }