001: /* Copyright 2005 The JA-SIG Collaborative. All rights reserved.
002: * See license distributed with this file and
003: * available online at http://www.uportal.org/license.html
004: */
005: package org.jasig.portal.channels.adminnav;
006:
007: import org.apache.commons.logging.Log;
008: import org.apache.commons.logging.LogFactory;
009: import org.jasig.portal.ChannelCacheKey;
010: import org.jasig.portal.ChannelRuntimeData;
011: import org.jasig.portal.ChannelStaticData;
012: import org.jasig.portal.ICacheable;
013: import org.jasig.portal.PortalException;
014: import org.jasig.portal.channels.BaseChannel;
015: import org.jasig.portal.properties.PropertiesManager;
016: import org.jasig.portal.security.IAuthorizationPrincipal;
017: import org.xml.sax.ContentHandler;
018:
019: /**
020: * This channel is a wrapper around an implementation that provides urls (links)
021: * to other channels. Typically, this is by functional name so that when
022: * selected those channels are rendered in focus mode. Links are added
023: * dynamically by calling the addLink() method which is delegated to the
024: * plugged-in implementation.
025: *
026: * CHeader channel presents the "Channel Admin" link which brings this channel
027: * into focused mode when selected. CHeader delegates to canAccess() to
028: * determine if there is any content within this channel that is accessible to
029: * the current user. If so then it will render the ChannelAdmin link. Similarly,
030: * when the implementation renders it should only present those links to
031: * channels for which the current user has authorization.
032: *
033: * Localization of link labels is supported through instances of ILabelResolver
034: * passed in at link registration time.
035: *
036: * A channel can provide links to this channel by calling their
037: * ChannelRuntimeData.getFnameActionURL() passing the functional name of this
038: * channel "admin.navigation.links".
039: *
040: * @author Keith Stacks, kstacks@sungardsct.com
041: * @author Mark Boyd, mboyd@sungardsct.com
042: */
043: public class AdminNavChannel extends BaseChannel implements ICacheable {
044: // Used for informational, error, and debug logging
045: private static Log LOG = null;
046:
047: // Internal model of channel.
048: private static INavigationModel model = null;
049:
050: private static final String IMPL_CLASS = "org.jasig.portal.channels.adminnav.AdminNavigation.implementation";
051:
052: private static Throwable INSTANTIATION_PROBLEM = null;
053: /********** Static initializer to load declared implementation *********/
054:
055: static {
056: // must instantiate log here if we want to use it in the initializer
057: LOG = LogFactory.getLog(AdminNavChannel.class);
058:
059: try {
060: String implClass = PropertiesManager
061: .getProperty(IMPL_CLASS);
062: Class cls = Class.forName(implClass);
063: model = (INavigationModel) cls.newInstance();
064: } catch (Throwable t) {
065: INSTANTIATION_PROBLEM = t;
066: LOG.error(
067: "Unable to load implementation of administrative "
068: + "navigational links.", t);
069: }
070: }
071:
072: /********* Channel Methods ***********/
073:
074: /**
075: * Checks to see if the rendering document needs to be updated for the
076: * user's locale.
077: */
078: public void setRuntimeData(ChannelRuntimeData rd)
079: throws PortalException {
080: if (model != null)
081: model.setRuntimeData(rd);
082: }
083:
084: /**
085: * Render the links.
086: *
087: * @param out stream that handles output
088: */
089: public void renderXML(ContentHandler out) throws PortalException {
090: if (model != null)
091: model.renderXML(out);
092: }
093:
094: /********* Worker methods *************/
095:
096: /**
097: * Delegates to the plugged-in model to answer if the user represented by
098: * the passed-in authorization principal has access to this channel. If any
099: * of the information available in the implementation should be accessible
100: * to the user then the model should return true.
101: */
102: public static boolean canAccess(IAuthorizationPrincipal ap) {
103: if (model != null)
104: return model.canAccess(ap);
105: else
106: return false;
107: }
108:
109: /**
110: * Returns an object that can be used to add links at runtime to the
111: * underlying administrative navigational links model.
112: */
113: public static ILinkRegistrar getLinkRegistrar() {
114: return model;
115: }
116:
117: /**
118: * Delegates to the plugged-in implementation to generate a key as part of
119: * its implementation of the ICacheable interface.
120: *
121: * @see org.jasig.portal.ICacheable#generateKey()
122: */
123: public ChannelCacheKey generateKey() {
124: if (model != null)
125: return model.generateKey();
126: else
127: return null;
128: }
129:
130: /**
131: * Delegates to the plugged-in implementation to determine using the
132: * passed-in validity object if cached output can be reused as part of
133: * its implementation of the ICacheable interface.
134: *
135: * @see org.jasig.portal.ICacheable#isCacheValid(java.lang.Object)
136: */
137: public boolean isCacheValid(Object validity) {
138: if (model != null)
139: return model.isCacheValid(validity);
140: return false;
141: }
142:
143: /**
144: * Passes the passed-in channel static configuration information to the
145: * plugged-in model.
146: */
147: public void setStaticData(ChannelStaticData sd)
148: throws PortalException {
149: if (model != null)
150: model.setStaticData(sd);
151: else
152: throw new PortalException(
153: "No implementation available due to "
154: + "the following problem.",
155: INSTANTIATION_PROBLEM);
156: }
157: }
|