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.layout.node;
007:
008: import java.util.Collection;
009: import java.util.Collections;
010: import java.util.Enumeration;
011: import java.util.Hashtable;
012: import java.util.Map;
013:
014: import org.apache.commons.logging.Log;
015: import org.apache.commons.logging.LogFactory;
016: import org.jasig.portal.ChannelDefinition;
017: import org.jasig.portal.ChannelParameter;
018: import org.jasig.portal.ChannelRegistryStoreFactory;
019: import org.jasig.portal.IChannelRegistryStore;
020: import org.jasig.portal.PortalException;
021: import org.jasig.portal.channels.portlet.IPortletAdaptor;
022: import org.w3c.dom.Document;
023: import org.w3c.dom.Element;
024: import org.w3c.dom.Node;
025:
026: /**
027: * A class managing information contained in a user layout channel node.
028: *
029: * @author Peter Kharchenko {@link <a href="mailto:pkharchenko@interactivebusiness.com"">pkharchenko@interactivebusiness.com"</a>}
030: * @version 1.0
031: */
032: public class UserLayoutChannelDescription extends
033: UserLayoutNodeDescription implements
034: IUserLayoutChannelDescription {
035:
036: private static final Log log = LogFactory
037: .getLog(UserLayoutChannelDescription.class);
038:
039: Hashtable parameters;
040: Hashtable override;
041:
042: String title = null;
043: String description = null;
044: String className = null;
045: String channelPublishId = null;
046: String channelTypeId = null;
047: String functionalName = null;
048: long timeout = -1;
049: boolean editable = false;
050: boolean hasHelp = false;
051: boolean hasAbout = false;
052: boolean isSecure = false;
053:
054: public UserLayoutChannelDescription() {
055: super ();
056: parameters = new Hashtable();
057: override = new Hashtable();
058: }
059:
060: public UserLayoutChannelDescription(IUserLayoutChannelDescription d) {
061: this ();
062: this .title = d.getTitle();
063: this .description = d.getDescription();
064: this .className = d.getClassName();
065: this .channelPublishId = d.getChannelPublishId();
066: this .channelTypeId = d.getChannelTypeId();
067: this .functionalName = d.getFunctionalName();
068: this .timeout = d.getTimeout();
069: this .editable = d.isEditable();
070: this .hasHelp = d.hasHelp();
071: this .hasAbout = d.hasAbout();
072:
073: for (Enumeration enum1 = d.getParameterNames(); enum1
074: .hasMoreElements();) {
075: String pName = (String) enum1.nextElement();
076: this .setParameterValue(pName, d.getParameterValue(pName));
077: this .setParameterOverride(pName, d
078: .getParameterOverrideValue(pName));
079: }
080: }
081:
082: /**
083: * Reconstruct channel information from an xml <code>Element</code>
084: *
085: * @param xmlNode a user layout channel <code>Element</code> value
086: * @exception PortalException if xml is malformed
087: */
088: public UserLayoutChannelDescription(Element xmlNode)
089: throws PortalException {
090: super (xmlNode);
091: parameters = new Hashtable();
092: override = new Hashtable();
093:
094: if (!xmlNode.getNodeName().equals("channel")) {
095: throw new PortalException(
096: "Given XML Element is not a channel!");
097: }
098:
099: // channel-specific attributes
100: this .setTitle(xmlNode.getAttribute("title"));
101: this .setDescription(xmlNode.getAttribute("description"));
102: this .setClassName(xmlNode.getAttribute("class"));
103: this .setChannelPublishId(xmlNode.getAttribute("chanID"));
104: this .setChannelTypeId(xmlNode.getAttribute("typeID"));
105: this .setFunctionalName(xmlNode.getAttribute("fname"));
106: this
107: .setTimeout(Long.parseLong(xmlNode
108: .getAttribute("timeout")));
109: this .setEditable(Boolean.valueOf(
110: xmlNode.getAttribute("editable")).booleanValue());
111: this .setHasHelp(Boolean
112: .valueOf(xmlNode.getAttribute("hasHelp"))
113: .booleanValue());
114: this .setHasAbout(Boolean.valueOf(
115: xmlNode.getAttribute("hasAbout")).booleanValue());
116: this
117: .setIsSecure(Boolean.valueOf(
118: xmlNode.getAttribute("secure")).booleanValue());
119:
120: // process parameter elements
121: for (Node n = xmlNode.getFirstChild(); n != null; n = n
122: .getNextSibling()) {
123: if (n.getNodeType() == Node.ELEMENT_NODE) {
124: Element e = (Element) n;
125: if (e.getNodeName().equals("parameter")) {
126: // get parameter name and value
127: String pName = e.getAttribute("name");
128: String pValue = e.getAttribute("value");
129:
130: Boolean canOverride = new Boolean(false);
131: String str_override = e.getAttribute("override");
132: if (str_override != null
133: && str_override.equals("yes")) {
134: canOverride = new Boolean(true);
135: }
136:
137: if (pName != null && pValue != null) {
138: this .setParameterValue(pName, pValue);
139: this .setParameterOverride(pName, canOverride
140: .booleanValue());
141: }
142: }
143: }
144: }
145: }
146:
147: /**
148: * Determine if the channel supports "about" action.
149: * @return value of hasAbout.
150: */
151: public boolean hasAbout() {
152: return hasAbout;
153: }
154:
155: /**
156: * Specify whether the channel supports "about" action.
157: * @param v Value to assign to hasAbout.
158: */
159: public void setHasAbout(boolean v) {
160: this .hasAbout = v;
161: }
162:
163: /**
164: * Determine if the channel supports "help" action.
165: * @return value of hasHelp.
166: */
167: public boolean hasHelp() {
168: return hasHelp;
169: }
170:
171: /**
172: * Specify whether the channel supports "help" action.
173: * @param v Value to assign to hasHelp.
174: */
175: public void setHasHelp(boolean v) {
176: this .hasHelp = v;
177: }
178:
179: /**
180: * Determine if the channel is editable.
181: * @return value of editable.
182: */
183: public boolean isEditable() {
184: return editable;
185: }
186:
187: /**
188: * Specify whether the channel is editable.
189: * @param v Value to assign to editable.
190: */
191: public void setEditable(boolean v) {
192: this .editable = v;
193: }
194:
195: /**
196: * Get the value of channel timeout in milliseconds.
197: * @return value of timeout.
198: */
199: public long getTimeout() {
200: return timeout;
201: }
202:
203: /**
204: * Set the value of channel timeout in milliseconds.
205: * @param v Value to assign to timeout.
206: */
207: public void setTimeout(long v) {
208: this .timeout = v;
209: }
210:
211: /**
212: * Get the value of secure setting.
213: * @return value of secure.
214: */
215: public boolean isSecure() {
216: return isSecure;
217: }
218:
219: /**
220: * Set the value of channel secure setting.
221: * @param secure Value to assign to secure
222: */
223: public void setIsSecure(boolean secure) {
224: this .isSecure = secure;
225: }
226:
227: /**
228: * Get the channel type for portlet / not portlet
229: * @return the channel type for portlet / not portlet
230: */
231: public boolean isPortlet() {
232: /*
233: * We believe we are a portlet if the channel class implements
234: * IPortletAdaptor.
235: */
236:
237: if (this .className != null) {
238: try {
239: Class channelClass = Class.forName(this .className);
240: return IPortletAdaptor.class
241: .isAssignableFrom(channelClass);
242: } catch (Throwable e) {
243: log.error("Unable to load class for name ["
244: + this .className
245: + "] and so do not know whether is a portlet.",
246: e);
247: }
248: }
249:
250: return false;
251: }
252:
253: /**
254: * Get the value of functionalName.
255: * @return value of functionalName.
256: */
257: public String getFunctionalName() {
258: return functionalName;
259: }
260:
261: /**
262: * Set the value of functionalName.
263: * @param v Value to assign to functionalName.
264: */
265: public void setFunctionalName(String v) {
266: this .functionalName = v;
267: }
268:
269: /**
270: * Get the value of channelSubscribeId.
271: * @return value of channelSubscribeId.
272: */
273: public String getChannelSubscribeId() {
274: return super .getId();
275: }
276:
277: /**
278: * Set the value of channelSubscribeId.
279: * @param v Value to assign to channelSubscribeId.
280: */
281: public void setChannelSubscribeId(String v) {
282: super .setId(v);
283: }
284:
285: /**
286: * Get the value of channelTypeId.
287: * @return value of channelTypeId.
288: */
289: public String getChannelTypeId() {
290: return channelTypeId;
291: }
292:
293: /**
294: * Set the value of channelTypeId.
295: * @param v Value to assign to channelTypeId.
296: */
297: public void setChannelTypeId(String v) {
298: this .channelTypeId = v;
299: }
300:
301: /**
302: * Get the value of channelPublishId for this channel.
303: * @return value of channelPublishId.
304: */
305: public String getChannelPublishId() {
306: return channelPublishId;
307: }
308:
309: /**
310: * Set the value of channelPublishId for this channel.
311: * @param v Value to assign to channelPublishId.
312: */
313: public void setChannelPublishId(String v) {
314: this .channelPublishId = v;
315: }
316:
317: /**
318: * Get the value of className implementing this channel.
319: * @return value of className.
320: */
321: public String getClassName() {
322: return className;
323: }
324:
325: /**
326: * Set the value of className implementing this channel.
327: * @param v Value to assign to className.
328: */
329: public void setClassName(String v) {
330: this .className = v;
331: }
332:
333: /**
334: * Get the value of title.
335: * @return value of title.
336: */
337: public String getTitle() {
338: return title;
339: }
340:
341: /**
342: * Set the value of title.
343: * @param v Value to assign to title.
344: */
345: public void setTitle(String v) {
346: this .title = v;
347: }
348:
349: /**
350: * Get the value of description.
351: * @return value of description.
352: */
353: public String getDescription() {
354: return description;
355: }
356:
357: /**
358: * Set the value of description.
359: * @param v Value to assign to description.
360: */
361: public void setDescription(String v) {
362: this .description = v;
363: }
364:
365: // channel parameter methods
366:
367: /**
368: * Set a channel parameter value.
369: *
370: * @param parameterValue a <code>String</code> value
371: * @param parameterName a <code>String</code> value
372: * @return a <code>String</code> value that was set.
373: */
374: public String setParameterValue(String parameterName,
375: String parameterValue) {
376: // don't try to store a null value
377: if (parameterValue == null)
378: return null;
379: return (String) parameters.put(parameterName, parameterValue);
380: }
381:
382: /**
383: * Reset a channel parameter value. Since parameter changes by channels
384: * can be persisted if override is allowed this method enables resetting to
385: * the original value or, if the parameter is ad-hoc meaning that the
386: * channel definition does not provide a value for this parameter, then the
387: * parameter value is removed.
388: *
389: * @param parameterName a <code>String</code> value
390: */
391: public void resetParameter(String parameterName)
392: throws PortalException {
393: /*
394: * Since original channel definition parameter values that were
395: * overridden are not maintained at this level we must consult the
396: * channel definition to determine the original value and restore it
397: * or discover that this is an ad-hoc parameter and can be removed.
398: */
399: try {
400: IChannelRegistryStore crs = ChannelRegistryStoreFactory
401: .getChannelRegistryStoreImpl();
402: int pubId = Integer.parseInt(getChannelPublishId());
403: ChannelDefinition def = crs.getChannelDefinition(pubId);
404: ChannelParameter parm = def.getParameter(parameterName);
405:
406: if (parm == null) // ad-hoc parm so delete
407: {
408: parameters.remove(parameterName);
409: override.remove(parameterName);
410: } else if (parm.getOverride())
411: parameters.put(parameterName, parm.getValue());
412: } catch (Exception e) {
413: throw new PortalException("Unable to reset parameter ["
414: + parameterName + "] for channel [" + getTitle()
415: + "].", e);
416: }
417: }
418:
419: /**
420: * Obtain a channel parameter value.
421: *
422: * @param parameterName a <code>String</code> value
423: * @return a <code>String</code> value
424: */
425: public String getParameterValue(String parameterName) {
426: return (String) parameters.get(parameterName);
427: }
428:
429: /**
430: * Obtain a channel parameter override value.
431: *
432: * @param parameterName a <code>String</code> value
433: * @return a <code>boolean</code> value
434: */
435: public boolean getParameterOverrideValue(String parameterName) {
436: Boolean boolValue = (Boolean) override.get(parameterName);
437: if (boolValue != null)
438: return boolValue.booleanValue();
439: return true;
440: }
441:
442: /**
443: * Obtain values of all existing channel parameters.
444: *
445: * @return a <code>Collection</code> of <code>String</code> parameter values.
446: */
447: public Collection getParameterValues() {
448: return parameters.values();
449: }
450:
451: /**
452: * Determines the number of existing channel parameters.
453: *
454: * @return an <code>int</code> value
455: */
456: public int numberOfParameters() {
457: return parameters.size();
458: }
459:
460: /**
461: * Clears all of the channel parameters.
462: *
463: */
464: public void clearParameters() {
465: parameters.clear();
466: override.clear();
467: }
468:
469: /**
470: * Determine if a given parameter can be overriden by the user.
471: * (defaults to true)
472: * @param parameterName a <code>String</code> value
473: * @return a <code>boolean</code> value
474: */
475: public boolean canOverrideParameter(String parameterName) {
476: return getParameterOverrideValue(parameterName);
477: }
478:
479: /**
480: * Set parameter override flag.
481: *
482: * @param parameterName a <code>String</code> value
483: * @param canOverride a <code>boolean</code> flag.
484: */
485: public void setParameterOverride(String parameterName,
486: boolean canOverride) {
487: if (parameters.get(parameterName) != null) {
488: this .override.put(parameterName, new Boolean(canOverride));
489: }
490: }
491:
492: /**
493: * Remove a channel parameter.
494: *
495: * @param parameterName a <code>String</code> parameter name.
496: * @return an old parameter value.
497: */
498: public String remove(String parameterName) {
499: override.remove(parameterName);
500: return (String) parameters.remove(parameterName);
501: }
502:
503: /**
504: * Obtain a set of channel parameter names.
505: *
506: * @return a <code>Set</code> of <code>String</code> parameter names.
507: */
508: public Enumeration getParameterNames() {
509: return parameters.keys();
510: }
511:
512: /**
513: * Returns an entire mapping of parameters.
514: *
515: * @return a <code>Map</code> of parameter names on parameter values.
516: */
517: public Map getParameterMap() {
518: return Collections.unmodifiableMap(parameters);
519: }
520:
521: /**
522: * Determine if the channel has any parameters.
523: *
524: * @return a <code>boolean</code> value
525: */
526: public boolean hasParameters() {
527: return !parameters.isEmpty();
528: }
529:
530: /**
531: * Determines if a certain parameter name is present.
532: *
533: * @param parameterName a <code>String</code> parameter name.
534: * @return a <code>boolean</code> value
535: */
536: public boolean containsParameter(String parameterName) {
537: return parameters.containsKey(parameterName);
538: }
539:
540: /**
541: * Creates a <code>org.w3c.dom.Element</code> representation of the current channel.
542: *
543: * @param root a <code>Document</code> for which the <code>Element</code> should be created.
544: * @return a <code>Node</code> value
545: */
546: public Element getXML(Document root) {
547: Element node = root.createElement("channel");
548: this .addNodeAttributes(node);
549: this .addParameterChildren(node, root);
550: return node;
551: }
552:
553: public void addParameterChildren(Element node, Document root) {
554: for (Enumeration enum1 = this .getParameterNames(); enum1
555: .hasMoreElements();) {
556: Element pElement = root.createElement("parameter");
557: String pName = (String) enum1.nextElement();
558: pElement.setAttribute("name", pName);
559: pElement.setAttribute("value", getParameterValue(pName));
560: pElement.setAttribute("override",
561: getParameterOverrideValue(pName) ? "yes" : "no");
562: node.appendChild(pElement);
563: }
564: }
565:
566: public void addNodeAttributes(Element node) {
567: super .addNodeAttributes(node);
568: node.setAttribute("title", this .getTitle());
569: node.setAttribute("description", this .getDescription());
570: node.setAttribute("class", this .getClassName());
571: node.setAttribute("chanID", this .getChannelPublishId());
572: node.setAttribute("typeID", this .getChannelTypeId());
573: node.setAttribute("fname", this .getFunctionalName());
574: node.setAttribute("timeout", Long.toString(this .getTimeout()));
575: node.setAttribute("editable", (new Boolean(this .isEditable()))
576: .toString());
577: node.setAttribute("hasHelp", (new Boolean(this .hasHelp()))
578: .toString());
579: node.setAttribute("hasAbout", (new Boolean(this .hasAbout()))
580: .toString());
581: node.setAttribute("secure", (new Boolean(this .isSecure()))
582: .toString());
583: node.setAttribute("isPortlet", Boolean
584: .valueOf(this .isPortlet()).toString());
585: }
586:
587: /**
588: * Returns a type of the node, could be FOLDER or CHANNEL integer constant.
589: *
590: * @return a type
591: */
592: public int getType() {
593: return CHANNEL;
594: }
595:
596: public String toString() {
597: return "[" + channelPublishId + "," + title + "]";
598: }
599:
600: }
|