001: /* Copyright 2002 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:
006: package org.jasig.portal.channels;
007:
008: import org.jasig.portal.ChannelCacheKey;
009: import org.jasig.portal.Constants;
010: import org.jasig.portal.ICacheable;
011: import org.jasig.portal.PortalException;
012: import org.jasig.portal.channels.adminnav.AdminNavChannel;
013: import org.jasig.portal.i18n.LocaleManager;
014: import org.jasig.portal.layout.dlm.DistributedLayoutManager;
015: import org.apache.commons.logging.Log;
016: import org.apache.commons.logging.LogFactory;
017: import org.jasig.portal.properties.PropertiesManager;
018: import org.jasig.portal.utils.DocumentFactory;
019: import org.jasig.portal.utils.ResourceLoader;
020: import org.jasig.portal.utils.XSLT;
021: import org.w3c.dom.Document;
022: import org.w3c.dom.Element;
023: import org.xml.sax.ContentHandler;
024:
025: /**
026: * This channel provides content for a page header. It is indended
027: * to be included in a layout folder of type "header". Most stylesheets
028: * will render the content of such header channels consistently on every
029: * page.
030: * @author Peter Kharchenko, pkharchenko@interactivebusiness.com
031: * @author Ken Weiner, kweiner@unicon.net
032: * @author Bernie Durfee, bdurfee@interactivebusiness.com
033: * @version $Revision: 36001 $
034: */
035: public class CHeader extends BaseChannel implements ICacheable {
036: private static final Log log = LogFactory.getLog(CHeader.class);
037: private static final String sslLocation = "CHeader/CHeader.ssl";
038:
039: /**
040: * Checks user permissions to see if the user is authorized to access any
041: * channels available from the admin area.
042: * @return true if user has access to any registered administration channels
043: */
044: private boolean canUserAccessAdminNavigation() {
045: boolean canPublish = false;
046: try {
047: // Let the admin navigation channel determine since it knows what
048: // channels are available
049: canPublish = AdminNavChannel.canAccess(staticData
050: .getAuthorizationPrincipal());
051: } catch (Exception e) {
052: log.error(
053: "Exception determining whether user can access administrative"
054: + " channels, defaulting to false.", e);
055: // Deny the user access if anything went wrong
056: }
057: return canPublish;
058: }
059:
060: /**
061: * Gets the current date/time with specified format
062: * @param format the format string
063: * @return a formatted date and time string
064: */
065: public static String getDate(String format) {
066: try {
067: // Format the current time.
068: java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat(
069: format);
070: java.util.Date currentTime = new java.util.Date();
071: return formatter.format(currentTime);
072: } catch (Exception e) {
073: log.error("Exception getting current date.", e);
074: }
075:
076: return " ";
077: }
078:
079: /**
080: * Returns the DOM object associated with the user
081: * @return DOM object associated with the user
082: */
083: private Document getUserXML() {
084: // Get the fullname of the current user
085: String fullName = (String) staticData.getPerson().getFullName();
086: if (fullName == null)
087: fullName = "";
088: // Get a new DOM instance
089: Document doc = DocumentFactory.getNewDocument();
090: // Create <header> element
091: Element headerEl = doc.createElement("header");
092: // Create <full-name> element under <header>
093: Element fullNameEl = doc.createElement("full-name");
094: fullNameEl.appendChild(doc.createTextNode(fullName));
095: headerEl.appendChild(fullNameEl);
096: // Create <timestamp-long> element under <header>
097: Element timeStampLongEl = doc.createElement("timestamp-long");
098: timeStampLongEl
099: .appendChild(doc
100: .createTextNode(getDate("EEEE, MMM d, yyyy 'at' hh:mm a")));
101: headerEl.appendChild(timeStampLongEl);
102: // Create <timestamp-short> element under <header>
103: Element timeStampShortEl = doc.createElement("timestamp-short");
104: timeStampShortEl.appendChild(doc
105: .createTextNode(getDate("M.d.y h:mm a")));
106: headerEl.appendChild(timeStampShortEl);
107: // Don't render the publish, subscribe, user preferences links if it's the guest user
108: if (staticData.getPerson().getSecurityContext()
109: .isAuthenticated()) {
110: if (canUserAccessAdminNavigation()) {
111: // Create <chan-mgr-chanid> element under <header>
112: Element chanMgrChanidEl = doc
113: .createElement("chan-mgr-chanid");
114: chanMgrChanidEl
115: .appendChild(doc
116: .createTextNode(Constants.NAVIGATION_CHAN_FNAME));
117: headerEl.appendChild(chanMgrChanidEl);
118: }
119:
120: // Create <preferences-chanid> element under <header>
121: Element preferencesChanidEl = doc
122: .createElement("preferences-chanid");
123:
124: // make fname of prefs be appropriate for simple layouts versus DLM
125: String layoutMgmFac = PropertiesManager
126: .getProperty(
127: "org.jasig.portal.layout.UserLayoutManagerFactory.coreImplementation",
128: "default");
129: if (layoutMgmFac.equals(DistributedLayoutManager.class
130: .getName()))
131: preferencesChanidEl.appendChild(doc
132: .createTextNode("portal/userpreferences/dlm"));
133: else
134: preferencesChanidEl
135: .appendChild(doc
136: .createTextNode("portal/userpreferences/general"));
137: headerEl.appendChild(preferencesChanidEl);
138: }
139: doc.appendChild(headerEl);
140: return doc;
141: }
142:
143: /**
144: * ICacheable method - generates cache key
145: * @return key the cache key
146: */
147: public ChannelCacheKey generateKey() {
148: ChannelCacheKey k = new ChannelCacheKey();
149: StringBuffer sbKey = new StringBuffer(1024);
150:
151: sbKey.append("org.jasig.portal.CHeader: ");
152:
153: if (staticData.getPerson().isGuest()) {
154: // guest users are cached system-wide.
155: k.setKeyScope(ChannelCacheKey.SYSTEM_KEY_SCOPE);
156: sbKey.append("userId:").append(
157: staticData.getPerson().getID()).append(", ");
158: } else {
159: // otherwise cache is instance-specific
160: k.setKeyScope(ChannelCacheKey.INSTANCE_KEY_SCOPE);
161: }
162: sbKey.append("locales:").append(
163: LocaleManager.stringValueOf(runtimeData.getLocales()));
164: sbKey.append("authenticated:").append(
165: staticData.getPerson().getSecurityContext()
166: .isAuthenticated()).append(", ");
167: sbKey.append("baseActionURL:").append(
168: runtimeData.getBaseActionURL()).append(", ");
169: sbKey.append("hasAdminAccess:").append(
170: String.valueOf(canUserAccessAdminNavigation())).append(
171: ", ");
172: sbKey.append("stylesheetURI:");
173: try {
174: String sslUri = ResourceLoader.getResourceAsURLString(this
175: .getClass(), sslLocation);
176: sbKey.append(XSLT.getStylesheetURI(sslUri, runtimeData
177: .getBrowserInfo()));
178: } catch (Exception e) {
179: sbKey.append("not defined");
180: }
181: k.setKey(sbKey.toString());
182: k.setKeyValidity(new Long(System.currentTimeMillis()));
183: return k;
184: }
185:
186: /**
187: * ICacheable method - checks validity of cache
188: * @param validity the validity object
189: * @return cacheValid <code>true</code> if cache is still valid, otherwise <code>false</code>
190: */
191: public boolean isCacheValid(Object validity) {
192: boolean cacheValid = false;
193: if (validity instanceof Long) {
194: Long oldtime = (Long) validity;
195: if (!staticData.getPerson().getSecurityContext()
196: .isAuthenticated()) {
197: // cache entries for unauthenticated users don't expire
198: cacheValid = true;
199: } else if (System.currentTimeMillis() - oldtime.longValue() < 1 * 60 * 1000) {
200: cacheValid = true;
201: }
202: }
203: return cacheValid;
204: }
205:
206: /**
207: * Render method.
208: * @param out the content handler
209: * @exception PortalException
210: */
211: public void renderXML(ContentHandler out) throws PortalException {
212: // Perform the transformation
213: XSLT xslt = XSLT.getTransformer(this , runtimeData.getLocales());
214: xslt.setXML(getUserXML());
215: xslt.setXSL(sslLocation, runtimeData.getBrowserInfo());
216: xslt.setTarget(out);
217: xslt.setStylesheetParameter("baseActionURL", runtimeData
218: .getBaseActionURL());
219: if (staticData.getPerson().getSecurityContext()
220: .isAuthenticated()) {
221: xslt.setStylesheetParameter("authenticated", "true");
222: }
223: xslt.transform();
224: }
225: }
|