001: /* Copyright 2001 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.DLMUserPreferences;
007:
008: import java.io.StringWriter;
009: import java.util.Enumeration;
010: import java.util.Hashtable;
011: import java.util.ResourceBundle;
012:
013: import org.apache.commons.logging.Log;
014: import org.apache.commons.logging.LogFactory;
015: import org.jasig.portal.ChannelRuntimeData;
016: import org.jasig.portal.GeneralRenderingException;
017: import org.jasig.portal.IPrivilegedChannel;
018: import org.jasig.portal.IUserPreferencesManager;
019: import org.jasig.portal.PortalControlStructures;
020: import org.jasig.portal.PortalException;
021: import org.jasig.portal.ResourceMissingException;
022: import org.jasig.portal.StructureStylesheetDescription;
023: import org.jasig.portal.StructureStylesheetUserPreferences;
024: import org.jasig.portal.StylesheetSet;
025: import org.jasig.portal.ThemeStylesheetDescription;
026: import org.jasig.portal.ThemeStylesheetUserPreferences;
027: import org.jasig.portal.UserPreferences;
028: import org.jasig.portal.UserProfile;
029: import org.jasig.portal.layout.node.IUserLayoutChannelDescription;
030: import org.jasig.portal.layout.IUserLayout;
031: import org.jasig.portal.layout.IUserLayoutManager;
032: import org.jasig.portal.layout.IUserLayoutStore;
033: import org.jasig.portal.layout.UserLayoutStoreFactory;
034: import org.jasig.portal.layout.node.IUserLayoutNodeDescription;
035: import org.jasig.portal.layout.UserLayoutManagerFactory;
036: import org.jasig.portal.utils.DocumentFactory;
037: import org.jasig.portal.utils.XSLT;
038: import org.w3c.dom.Document;
039: import org.w3c.dom.Element;
040: import org.xml.sax.ContentHandler;
041:
042: import org.apache.xml.serialize.OutputFormat;
043: import org.apache.xml.serialize.XMLSerializer;
044:
045: /** <p>Manages User Layout and user stylesheet preferences </p>
046: * This is a general UserPreference component. A structure/theme
047: * stylesheet is expected to replace this component with its own
048: * class to make layout/stylesheet preference management more
049: * intuitive.
050: * @author Ken Weiner, kweiner@interactivebusiness.com
051: * @author Peter Kharchenko, peterk@interactivebusiness.com
052: * @version $Revision: 36729 $
053: */
054: class GPreferencesState extends BaseState {
055: private static final Log log = LogFactory
056: .getLog(GPreferencesState.class);
057: private UserProfile profile;
058: protected ChannelRuntimeData runtimeData;
059: private UserPreferences up = null;
060: private IUserLayoutManager ulm = null;
061: ThemeStylesheetDescription tsd = null;
062: StructureStylesheetDescription ssd = null;
063: protected IUserLayoutStore ulsdb = UserLayoutStoreFactory
064: .getUserLayoutStoreImpl();
065: // these state variables are kept for the use by the internalStates
066:
067: // just a way to refer to the layout element since it doesn't have an ID attribute
068: private static final String layoutID = IUserLayout.ROOT_NODE_NAME;
069: private String folderID = layoutID;
070: private boolean modified = false; // becomes true after user makes changes to layout
071:
072: private static final String bundleLocation = "/org/jasig/portal/channels/GPreferencesState/GPreferencesState";
073:
074: /**
075: * Check if the user layout or preferences have been modified.
076: *
077: * @return a <code>boolean</code> value
078: */
079: protected boolean isModified() {
080: return modified;
081: }
082:
083: /**
084: * Set modification state
085: *
086: * @param mod a <code>boolean</code> value
087: */
088: protected void setModified(boolean mod) {
089: this .modified = mod;
090: }
091:
092: /**
093: * Set current folderId.
094: *
095: * @param id a <code>String</code> value
096: */
097: protected void setFolderID(String id) {
098: this .folderID = id;
099: if (folderID == null)
100: folderID = layoutID;
101: }
102:
103: /**
104: * Obtain current folderId
105: *
106: * @return a <code>String</code> value
107: */
108: protected String getFolderID() {
109: if (folderID == null)
110: folderID = layoutID;
111: return this .folderID;
112: }
113:
114: protected String getLayoutRootID() {
115: return layoutID;
116: }
117:
118: public GPreferencesState() {
119: super ();
120: this .internalState = new GBrowseState(this );
121: ulsdb = UserLayoutStoreFactory.getUserLayoutStoreImpl();
122: }
123:
124: /**
125: * Creates a new <code>GPreferencesState</code> for a given context.
126: *
127: * @param context a <code>CUserPreferences</code> value
128: */
129: public GPreferencesState(CUserPreferences context) {
130: super (context);
131: this .internalState = new GBrowseState(this );
132: }
133:
134: public GPreferencesState(CUserPreferences context, UserProfile p) {
135: this .profile = p;
136: // initialize in a browse state
137: this .internalState = new GBrowseState(this );
138: }
139:
140: protected IUserLayoutManager getUserLayoutManager()
141: throws PortalException {
142: if (this .ulm == null) {
143: IUserPreferencesManager upm = context
144: .getUserPreferencesManager();
145: // If the we are editing the current user layout, get a copy of the current user layout,
146: // otherwise get it from the database or other persistant storage
147: if (modifyingCurrentUserLayout()) {
148: // get it from the preferences manager
149: this .ulm = upm.getUserLayoutManager();
150: } else {
151: // construct a new one
152: this .ulm = UserLayoutManagerFactory
153: .getUserLayoutManager(upm.getPerson(), context
154: .getCurrentUserPreferences()
155: .getProfile());
156: }
157: }
158: return this .ulm;
159: }
160:
161: private boolean modifyingCurrentUserLayout() throws PortalException {
162: // check if we're editing the same layout (note: this relies on the layout Ids to be meaningful, which
163: // is not entirely true with the current "template user layout" feature. Hopefully this will go away soon.
164: // return (context.getUserPreferencesManager().getCurrentProfile().getProfileId()==context.getEditedUserProfile().getProfileId() && context.getUserPreferencesManager().getCurrentProfile().isSystemProfile()==context.getEditedUserProfile().isSystemProfile());
165: return (context.getUserPreferencesManager().getCurrentProfile()
166: .getLayoutId() == context.getEditedUserProfile()
167: .getLayoutId());
168: }
169:
170: protected IUserPreferencesManager getUserPreferencesManager() {
171: return context.getUserPreferencesManager();
172: }
173:
174: protected UserPreferences getUserPreferences()
175: throws ResourceMissingException, PortalException {
176: if (up == null) {
177: // load UserPreferences from the DB
178: try {
179: up = ulsdb.getUserPreferences(context
180: .getUserPreferencesManager().getPerson(), this
181: .getProfile());
182: up.synchronizeWithUserLayoutXML(this
183: .getUserLayoutManager().getUserLayoutDOM());
184: } catch (Exception e) {
185: throw new PortalException(e);
186: }
187: }
188: return up;
189: }
190:
191: protected ThemeStylesheetDescription getThemeStylesheetDescription()
192: throws PortalException {
193: if (tsd == null) {
194: ThemeStylesheetUserPreferences ssup = up
195: .getThemeStylesheetUserPreferences();
196: try {
197: tsd = ulsdb.getThemeStylesheetDescription(ssup
198: .getStylesheetId());
199: } catch (Exception e) {
200: throw new PortalException(e);
201: }
202: }
203: return tsd;
204: }
205:
206: protected StructureStylesheetDescription getStructureStylesheetDescription()
207: throws ResourceMissingException, PortalException {
208: if (ssd == null) {
209: StructureStylesheetUserPreferences fsup = this
210: .getUserPreferences()
211: .getStructureStylesheetUserPreferences();
212: try {
213: ssd = ulsdb.getStructureStylesheetDescription(fsup
214: .getStylesheetId());
215: } catch (Exception e) {
216: throw new PortalException(e);
217: }
218: }
219: return ssd;
220: }
221:
222: public void setPortalControlStructures(PortalControlStructures pcs)
223: throws PortalException {
224: if (this .internalState != null) {
225: this .internalState.setPortalControlStructures(pcs);
226: }
227: }
228:
229: protected StylesheetSet getStylesheetSet() {
230: return context.getStylesheetSet();
231: }
232:
233: protected UserProfile getProfile() {
234: if (profile == null)
235: profile = context.getUserPreferencesManager()
236: .getCurrentProfile();
237: return profile;
238: }
239:
240: public void setRuntimeData(ChannelRuntimeData rd)
241: throws PortalException {
242: this .runtimeData = rd;
243: String action = runtimeData.getParameter("action");
244: if (action != null) {
245: if (action.equals("submitEditChoice")) {
246: String manageTarget = runtimeData
247: .getParameter("userPreferencesAction");
248: if (manageTarget.equals("layout")) {
249: this .folderID = this .getLayoutRootID();
250: // browse mode
251: GBrowseState bstate = new GBrowseState(this );
252: bstate.setRuntimeData(rd);
253: this .internalState = bstate;
254: } else if (manageTarget.equals("gpref")) {
255: // invoke gpref mode
256: GGlobalPrefsState pstate = new GGlobalPrefsState(
257: this );
258: pstate.setRuntimeData(rd);
259: this .internalState = pstate;
260: }
261: }
262: }
263:
264: if (this .internalState != null) {
265: this .internalState.setRuntimeData(rd);
266: }
267: }
268:
269: public void renderXML(ContentHandler out) throws PortalException {
270: if (this .internalState != null) {
271: this .internalState.renderXML(out);
272: } else {
273: log
274: .error("CUserPreferences.GPreferencesState::renderXML() : no internal state !");
275: }
276: }
277:
278: protected class GEditLayoutItemState extends BaseState {
279: protected GPreferencesState context;
280: private String editElementID;
281:
282: public GEditLayoutItemState(GPreferencesState context) {
283: this .context = context;
284: }
285:
286: public void setRuntimeData(ChannelRuntimeData rd)
287: throws PortalException {
288: String action = runtimeData.getParameter("action");
289: if (action != null) {
290: if (action.equals("editElement")) {
291: editElementID = runtimeData
292: .getParameter("folderID");
293: } else if (action.equals("submitEditValues")) {
294: String submit = runtimeData.getParameter("submit");
295: if (submit.equals("Cancel")) {
296: // return to the browse state
297: IPrivilegedChannel bstate = new GBrowseState(
298: context);
299: bstate.setRuntimeData(rd);
300: context.setState(bstate);
301: } else if (submit.equals("Save")) {
302: prepareSaveEditedItem();
303: }
304: }
305: }
306: }
307:
308: private void prepareSaveEditedItem() throws PortalException {
309: // update node name
310: IUserLayoutNodeDescription node = getUserLayoutManager()
311: .getNode(editElementID);
312: node.setName(runtimeData.getParameter("name"));
313: getUserLayoutManager().updateNode(node);
314:
315: // reset the name
316: if (node instanceof IUserLayoutChannelDescription) {
317: // target is a channel
318: StructureStylesheetUserPreferences ssup = context
319: .getUserPreferences()
320: .getStructureStylesheetUserPreferences();
321: for (Enumeration ce = ssup.getChannelAttributeNames(); ce
322: .hasMoreElements();) {
323: String atName = (String) ce.nextElement();
324: String atValue = runtimeData.getParameter(atName);
325: if (atValue.equals(context
326: .getStructureStylesheetDescription()
327: .getChannelAttributeDefaultValue(atName))) {
328: atValue = null;
329: }
330:
331: ssup.setChannelAttributeValue(editElementID,
332: atName, atValue);
333: }
334: ThemeStylesheetUserPreferences tsup = context
335: .getUserPreferences()
336: .getThemeStylesheetUserPreferences();
337: for (Enumeration ca = tsup.getChannelAttributeNames(); ca
338: .hasMoreElements();) {
339: String atName = (String) ca.nextElement();
340: String atValue = runtimeData.getParameter(atName);
341: if (atValue.equals(context
342: .getThemeStylesheetDescription()
343: .getChannelAttributeDefaultValue(atName))) {
344: atValue = null;
345: }
346: tsup.setChannelAttributeValue(editElementID,
347: atName, atValue);
348: }
349: } else {
350: // target is a folder
351: StructureStylesheetUserPreferences ssup = context
352: .getUserPreferences()
353: .getStructureStylesheetUserPreferences();
354: for (Enumeration fe = ssup.getFolderAttributeNames(); fe
355: .hasMoreElements();) {
356: String atName = (String) fe.nextElement();
357: String atValue = runtimeData.getParameter(atName);
358: if (atValue.equals(context
359: .getStructureStylesheetDescription()
360: .getFolderAttributeDefaultValue(atName))) {
361: atValue = null;
362: }
363: ssup.setFolderAttributeValue(editElementID, atName,
364: atValue);
365: }
366: }
367: context.setModified(true);
368: // get back to browse mode
369: IPrivilegedChannel bstate = new GBrowseState(context);
370: bstate.setRuntimeData(runtimeData);
371: context.setState(bstate);
372: }
373:
374: public void renderXML(ContentHandler out)
375: throws PortalException {
376: IUserLayoutNodeDescription node = getUserLayoutManager()
377: .getNode(editElementID);
378: String elType = "folder";
379: if (node instanceof IUserLayoutChannelDescription) {
380: elType = "channel";
381: }
382:
383: // construct the descriptive XML
384: Document doc = DocumentFactory.getNewDocument();
385: Element edEl = doc.createElement("editelement");
386: Element typeEl = doc.createElement("type");
387: if (elType.equals("folder")) {
388: typeEl.appendChild(doc.createTextNode("folder"));
389: } else {
390: typeEl.appendChild(doc.createTextNode("channel"));
391: }
392:
393: edEl.appendChild(typeEl);
394: Element nameEl = doc.createElement("name");
395: nameEl.appendChild(doc.createTextNode(node.getName()));
396: edEl.appendChild(nameEl);
397: // determine element type
398: if (elType.equals("folder")) {
399: // target is a folder
400: StructureStylesheetUserPreferences ssup = context
401: .getUserPreferences()
402: .getStructureStylesheetUserPreferences();
403: Element saEl = doc.createElement("structureattributes");
404: for (Enumeration fe = ssup.getFolderAttributeNames(); fe
405: .hasMoreElements();) {
406: Element atEl = doc.createElement("attribute");
407: Element atNameEl = doc.createElement("name");
408: String atName = (String) fe.nextElement();
409: atNameEl.appendChild(doc.createTextNode(atName));
410: atEl.appendChild(atNameEl);
411: Element valueEl = doc.createElement("value");
412: String value = ssup.getFolderAttributeValue(
413: editElementID, atName);
414: if (value == null) {
415: // set the default value
416: value = context
417: .getStructureStylesheetDescription()
418: .getFolderAttributeDefaultValue(atName);
419: }
420: valueEl.appendChild(doc.createTextNode(value));
421: atEl.appendChild(valueEl);
422: Element descrEl = doc.createElement("description");
423: descrEl
424: .appendChild(doc
425: .createTextNode(context
426: .getStructureStylesheetDescription()
427: .getFolderAttributeWordDescription(
428: atName)));
429: atEl.appendChild(descrEl);
430: saEl.appendChild(atEl);
431: }
432: edEl.appendChild(saEl);
433: } else if (elType.equals("channel")) {
434: // target is a channel
435: StructureStylesheetUserPreferences ssup = context
436: .getUserPreferences()
437: .getStructureStylesheetUserPreferences();
438: Element saEl = doc.createElement("structureattributes");
439: for (Enumeration ce = ssup.getChannelAttributeNames(); ce
440: .hasMoreElements();) {
441: Element atEl = doc.createElement("attribute");
442: Element atNameEl = doc.createElement("name");
443: String atName = (String) ce.nextElement();
444: atNameEl.appendChild(doc.createTextNode(atName));
445: atEl.appendChild(atNameEl);
446: Element valueEl = doc.createElement("value");
447: String value = ssup.getChannelAttributeValue(
448: editElementID, atName);
449: if (value == null) {
450: value = context
451: .getStructureStylesheetDescription()
452: .getChannelAttributeDefaultValue(atName);
453: }
454: valueEl.appendChild(doc.createTextNode(value));
455: atEl.appendChild(valueEl);
456: Element descrEl = doc.createElement("description");
457: descrEl
458: .appendChild(doc
459: .createTextNode(context
460: .getStructureStylesheetDescription()
461: .getChannelAttributeWordDescription(
462: atName)));
463: atEl.appendChild(descrEl);
464: saEl.appendChild(atEl);
465: }
466: edEl.appendChild(saEl);
467: ThemeStylesheetUserPreferences tsup = context
468: .getUserPreferences()
469: .getThemeStylesheetUserPreferences();
470: Element taEl = doc.createElement("themeattributes");
471: for (Enumeration ce = tsup.getChannelAttributeNames(); ce
472: .hasMoreElements();) {
473: Element atEl = doc.createElement("attribute");
474: Element atNameEl = doc.createElement("name");
475: String atName = (String) ce.nextElement();
476: atNameEl.appendChild(doc.createTextNode(atName));
477: atEl.appendChild(atNameEl);
478: Element valueEl = doc.createElement("value");
479: String value = tsup.getChannelAttributeValue(
480: editElementID, atName);
481: if (value == null) {
482: value = context
483: .getThemeStylesheetDescription()
484: .getChannelAttributeDefaultValue(atName);
485: }
486: valueEl.appendChild(doc.createTextNode(value));
487: atEl.appendChild(valueEl);
488: Element descrEl = doc.createElement("description");
489: descrEl
490: .appendChild(doc
491: .createTextNode(context
492: .getThemeStylesheetDescription()
493: .getChannelAttributeWordDescription(
494: atName)));
495: atEl.appendChild(descrEl);
496: taEl.appendChild(atEl);
497: }
498: edEl.appendChild(taEl);
499: }
500: doc.appendChild(edEl);
501: // debug printout of the prepared xml
502: try {
503: StringWriter outString = new StringWriter();
504: /* TODO: This should be reviewed at some point to see if we can use the
505: * DOM3 LS capability and hence a standard way of doing this rather
506: * than using an internal implementation class.
507: */
508: OutputFormat format = new OutputFormat();
509: format.setOmitXMLDeclaration(true);
510: format.setIndenting(true);
511: XMLSerializer xsl = new XMLSerializer(outString, format);
512: xsl.serialize(doc);
513: log.debug(outString.toString());
514: } catch (Exception e) {
515: log.debug(e, e);
516: }
517: StylesheetSet set = context.getStylesheetSet();
518: if (set == null) {
519: throw new GeneralRenderingException(
520: "Unable to determine the stylesheet list");
521: }
522: String xslURI = set.getStylesheetURI("editItem",
523: runtimeData.getBrowserInfo());
524: if (xslURI != null) {
525:
526: ResourceBundle l18n = ResourceBundle.getBundle(
527: bundleLocation, runtimeData.getLocales()[0]);
528: XSLT xslt = XSLT.getTransformer(this );
529: xslt.setResourceBundle(l18n);
530:
531: xslt.setXML(doc);
532: xslt.setXSL(this .getClass().getResource(xslURI)
533: .toString());
534: xslt.setTarget(out);
535: xslt.setStylesheetParameter("baseActionURL",
536: runtimeData.getBaseActionURL());
537: xslt.transform();
538: } else {
539: throw new ResourceMissingException("", "stylesheet",
540: "Unable to find stylesheet to display content for this media");
541: }
542: }
543: }
544:
545: protected class GGlobalPrefsState extends BaseState {
546: ChannelRuntimeData runtimeData;
547: protected GPreferencesState context;
548:
549: public GGlobalPrefsState(GPreferencesState context) {
550: this .context = context;
551: }
552:
553: public void setRuntimeData(ChannelRuntimeData rd)
554: throws PortalException {
555: this .runtimeData = rd;
556: // internal state handling
557: String action = runtimeData.getParameter("action");
558: if (action != null) {
559: if (action.equals("submitEditValues")) {
560: String submit = runtimeData.getParameter("submit");
561: if (submit == null || submit.equals("Save")) {
562: prepareSaveEditGPrefs();
563: } else if (submit.equals("Cancel")) {
564: IPrivilegedChannel bstate = new GBrowseState(
565: context);
566: bstate.setRuntimeData(runtimeData);
567: context.setState(bstate);
568: }
569: }
570: }
571: }
572:
573: public void renderXML(ContentHandler out)
574: throws PortalException {
575: // construct gpref XML
576: Document doc = DocumentFactory.getNewDocument();
577: Element edEl = doc.createElement("gpref");
578: StructureStylesheetUserPreferences ssup = context
579: .getUserPreferences()
580: .getStructureStylesheetUserPreferences();
581: Element spEl = doc.createElement("structureparameters");
582: for (Enumeration e = context
583: .getStructureStylesheetDescription()
584: .getStylesheetParameterNames(); e.hasMoreElements();) {
585: Element atEl = doc.createElement("parameter");
586: Element atNameEl = doc.createElement("name");
587: String atName = (String) e.nextElement();
588: atNameEl.appendChild(doc.createTextNode(atName));
589: atEl.appendChild(atNameEl);
590: Element valueEl = doc.createElement("value");
591: String value = ssup.getParameterValue(atName);
592: if (value == null) {
593: // set the default value
594: value = context.getStructureStylesheetDescription()
595: .getStylesheetParameterDefaultValue(atName);
596: }
597: valueEl.appendChild(doc.createTextNode(value));
598: atEl.appendChild(valueEl);
599: Element descrEl = doc.createElement("description");
600: descrEl
601: .appendChild(doc.createTextNode(context
602: .getStructureStylesheetDescription()
603: .getStylesheetParameterWordDescription(
604: atName)));
605: atEl.appendChild(descrEl);
606: spEl.appendChild(atEl);
607: }
608: edEl.appendChild(spEl);
609: ThemeStylesheetUserPreferences tsup = context
610: .getUserPreferences()
611: .getThemeStylesheetUserPreferences();
612: Element tpEl = doc.createElement("themeparameters");
613: for (Enumeration e = context
614: .getThemeStylesheetDescription()
615: .getStylesheetParameterNames(); e.hasMoreElements();) {
616: Element atEl = doc.createElement("parameter");
617: Element atNameEl = doc.createElement("name");
618: String atName = (String) e.nextElement();
619: atNameEl.appendChild(doc.createTextNode(atName));
620: atEl.appendChild(atNameEl);
621: Element valueEl = doc.createElement("value");
622: String value = tsup.getParameterValue(atName);
623: if (value == null) {
624: // set the default value
625: value = context.getThemeStylesheetDescription()
626: .getStylesheetParameterDefaultValue(atName);
627: }
628: valueEl.appendChild(doc.createTextNode(value));
629: atEl.appendChild(valueEl);
630: Element descrEl = doc.createElement("description");
631: descrEl
632: .appendChild(doc.createTextNode(context
633: .getThemeStylesheetDescription()
634: .getStylesheetParameterWordDescription(
635: atName)));
636: atEl.appendChild(descrEl);
637: tpEl.appendChild(atEl);
638: }
639: edEl.appendChild(tpEl);
640: doc.appendChild(edEl);
641: // debug printout of the prepared xml
642: try {
643: StringWriter outString = new StringWriter();
644: /* TODO: This should be reviewed at some point to see if we can use the
645: * DOM3 LS capability and hence a standard way of doing this rather
646: * than using an internal implementation class.
647: */
648: OutputFormat format = new OutputFormat();
649: format.setOmitXMLDeclaration(true);
650: format.setIndenting(true);
651: XMLSerializer serializer = new XMLSerializer(outString,
652: format);
653: serializer.serialize(doc);
654: if (log.isDebugEnabled())
655: log.debug(outString.toString());
656: } catch (Exception e) {
657: log.debug(e, e);
658: }
659: StylesheetSet set = context.getStylesheetSet();
660: if (set == null) {
661: throw new GeneralRenderingException(
662: "Unable to determine the stylesheet list");
663: }
664: String xslURI = set.getStylesheetURI("editGPrefs",
665: runtimeData.getBrowserInfo());
666: if (xslURI != null) {
667:
668: ResourceBundle l18n = ResourceBundle.getBundle(
669: bundleLocation, runtimeData.getLocales()[0]);
670: XSLT xslt = XSLT.getTransformer(this );
671: xslt.setResourceBundle(l18n);
672:
673: xslt.setXML(doc);
674: xslt.setXSL(this .getClass().getResource(xslURI)
675: .toString());
676: xslt.setTarget(out);
677: xslt.setStylesheetParameter("baseActionURL",
678: runtimeData.getBaseActionURL());
679: xslt.transform();
680: } else {
681: throw new ResourceMissingException("", "stylesheet",
682: "Unable to find stylesheet to display content for this media");
683: }
684: }
685:
686: private void prepareSaveEditGPrefs() throws PortalException {
687: StructureStylesheetUserPreferences ssup = context
688: .getUserPreferences()
689: .getStructureStylesheetUserPreferences();
690: for (Enumeration e = context
691: .getStructureStylesheetDescription()
692: .getStylesheetParameterNames(); e.hasMoreElements();) {
693: String parName = (String) e.nextElement();
694: String value = runtimeData.getParameter(parName);
695: if (value == null) {
696: ssup
697: .putParameterValue(
698: parName,
699: context
700: .getStructureStylesheetDescription()
701: .getStylesheetParameterDefaultValue(
702: parName));
703: } else {
704: ssup.putParameterValue(parName, value);
705: // log.debug("CUserPreferences.GGlobalPrefsState::prepareSaveEditGPrefs() : setting sparameter "+parName+"=\""+value+"\".");
706: }
707: }
708: ThemeStylesheetUserPreferences tsup = context
709: .getUserPreferences()
710: .getThemeStylesheetUserPreferences();
711: for (Enumeration e = context
712: .getThemeStylesheetDescription()
713: .getStylesheetParameterNames(); e.hasMoreElements();) {
714: String parName = (String) e.nextElement();
715: String value = runtimeData.getParameter(parName);
716: if (value == null) {
717: tsup
718: .putParameterValue(
719: parName,
720: context
721: .getThemeStylesheetDescription()
722: .getStylesheetParameterDefaultValue(
723: parName));
724: } else {
725: tsup.putParameterValue(parName, value);
726: // log.debug("CUserPreferences.GGlobalPrefsState::prepareSaveEditGPrefs() : setting tparameter "+parName+"=\""+value+"\".");
727: }
728: }
729: context.setModified(true);
730: IPrivilegedChannel bstate = new GBrowseState(context);
731: bstate.setRuntimeData(runtimeData);
732: context.setState(bstate);
733: }
734: }
735:
736: protected class GBrowseState extends BaseState {
737: ChannelRuntimeData runtimeData;
738: protected GPreferencesState context;
739:
740: public GBrowseState(GPreferencesState context) {
741: this .context = context;
742: }
743:
744: public void setRuntimeData(ChannelRuntimeData rd)
745: throws PortalException {
746: this .runtimeData = rd;
747: // internal state handling
748: String action = runtimeData.getParameter("action");
749: if (action != null) {
750: if (action.equals("browse")) {
751: String runtimeFolderID = runtimeData
752: .getParameter("folderID");
753: if (runtimeFolderID != null) {
754: context.setFolderID(runtimeFolderID);
755: }
756: } else if (action.equals("move")) {
757: IPrivilegedChannel mts = new GMoveToState(context);
758: mts.setRuntimeData(rd);
759: context.setState(mts);
760: } else if (action.equals("reorder"))
761: prepareReorder();
762: else if (action.equals("saveChanges")) {
763: prepareSaveChanges();
764: } else if (action.equals("editElement")) {
765: IPrivilegedChannel eli = new GEditLayoutItemState(
766: context);
767: eli.setRuntimeData(rd);
768: context.setState(eli);
769: }
770: }
771: }
772:
773: public void renderXML(ContentHandler out)
774: throws PortalException {
775: StylesheetSet set = context.getStylesheetSet();
776: if (set == null) {
777: throw new GeneralRenderingException(
778: "Unable to determine the stylesheet list");
779: }
780: String xslURI = null;
781: xslURI = set.getStylesheetURI("browse", runtimeData
782: .getBrowserInfo());
783: Hashtable params = new Hashtable();
784: params.put("folderID", context.getFolderID());
785: params.put("modified", new Boolean(context.isModified()));
786: params.put("baseActionURL", runtimeData.getBaseActionURL());
787: params.put("profileName", context.getProfile()
788: .getProfileName());
789: if (context.getProfile().isSystemProfile()) {
790: params.put("profileType", "system");
791: } else {
792: params.put("profileType", "user");
793: }
794: if (xslURI != null) {
795: XSLT xslt = XSLT.getTransformer(this , runtimeData
796: .getLocales());
797: xslt.setXML(context.getUserLayoutManager()
798: .getUserLayoutDOM());
799: xslt.setXSL(this .getClass().getResource(xslURI)
800: .toString());
801: xslt.setTarget(out);
802: xslt.setStylesheetParameters(params);
803: xslt.transform();
804: } else {
805: throw new ResourceMissingException("", "stylesheet",
806: "Unable to find stylesheet to display content for this media");
807: }
808: }
809:
810: private void prepareSaveChanges() throws PortalException {
811: context.setFolderID(context.getLayoutRootID());
812: context.setModified(false);
813: // relate changes back to the UserPreferencesManager if the profile that's being
814: // edited is the current profile.
815: // changes in userLayoutXML are always related back to the UserPreferencesManager.
816: // (unless profile-specific layouts will be introduced)
817: if (context.getUserPreferencesManager().getCurrentProfile() == context
818: .getProfile()) {
819: context.getUserPreferencesManager()
820: .setNewUserLayoutAndUserPreferences(
821: context.getUserLayoutManager(),
822: context.getUserPreferences());
823: } else {
824: // do a database save on the preferences
825: try {
826: // persist layout
827: context.getUserLayoutManager().saveUserLayout();
828: ulsdb.putUserPreferences(context
829: .getUserPreferencesManager().getPerson(),
830: context.getUserPreferences());
831: } catch (Exception e) {
832: throw new PortalException(e);
833: }
834: }
835: }
836:
837: private void prepareReorder() throws PortalException {
838: String folderID = runtimeData.getParameter("elementID"); // the folder or channel ID
839: String direction = runtimeData.getParameter("dir"); // "up" or "down"
840:
841: IUserLayoutManager lm = context.getUserLayoutManager();
842: if (direction.equals("up")) {
843: String prevSiblingId = lm
844: .getPreviousSiblingId(folderID);
845: if (prevSiblingId != null) {
846: lm.moveNode(folderID, lm.getParentId(folderID),
847: prevSiblingId);
848: }
849: // for (prev = element.getPreviousSibling(); prev != null && prev.getNodeType() != Node.ELEMENT_NODE && (!prev.getNodeName().equals("channel") || !prev.getNodeName().equals("folder")); prev = prev.getPreviousSibling());
850: } else if (direction.equals("down")) {
851: String nextSiblingId = lm.getNextSiblingId(folderID);
852: if (nextSiblingId != null) {
853: lm.moveNode(folderID, lm.getParentId(folderID),
854: nextSiblingId);
855: }
856: // for(next = element.getNextSibling(); next != null && next.getNodeType() != Node.ELEMENT_NODE && (!next.getNodeName().equals("channel") || !next.getNodeName().equals("folder")); next = next.getNextSibling());
857: }
858: context.setModified(true);
859: }
860: }
861:
862: protected class GMoveToState extends BaseState {
863: private String[] moveIDs = null; // contains the IDs of channels/folders to be moved
864: protected ChannelRuntimeData runtimeData;
865: protected GPreferencesState context;
866:
867: public GMoveToState(GPreferencesState context) {
868: this .context = context;
869: }
870:
871: public void setRuntimeData(ChannelRuntimeData rd)
872: throws PortalException {
873: this .runtimeData = rd;
874: String action = runtimeData.getParameter("action");
875: if (action != null) {
876: if (action.equals("cancel")) {
877: // prepareCancel ();
878: } else if (action.equals("move"))
879: prepareMove();
880: else if (action.equals("moveTo"))
881: prepareMoveTo();
882: }
883: }
884:
885: public void renderXML(ContentHandler out)
886: throws PortalException {
887: StylesheetSet set = context.getStylesheetSet();
888: if (set == null)
889: throw new GeneralRenderingException(
890: "Unable to determine the stylesheet list");
891: String xslURI = set.getStylesheetURI("moveTo", runtimeData
892: .getBrowserInfo());
893: if (xslURI != null) {
894: XSLT xslt = XSLT.getTransformer(this , runtimeData
895: .getLocales());
896: xslt.setXML(context.getUserLayoutManager()
897: .getUserLayoutDOM());
898: xslt.setXSL(this .getClass().getResource(xslURI)
899: .toString());
900: xslt.setTarget(out);
901: xslt.setStylesheetParameter("baseActionURL",
902: runtimeData.getBaseActionURL());
903: xslt.transform();
904: } else
905: throw new ResourceMissingException("", "stylesheet",
906: "Unable to find stylesheet to display content for this media");
907: }
908:
909: private void prepareMove() {
910: // getParameterValues() should be a method in ChannelRuntimeData.
911: // For now, I'll use the request object -- ask Peter about this!
912: moveIDs = runtimeData.getParameterValues("move");
913: }
914:
915: private void prepareMoveTo() throws PortalException {
916: String destinationID = runtimeData
917: .getParameter("destination");
918: for (int i = 0; i < moveIDs.length; i++) {
919: getUserLayoutManager().moveNode(moveIDs[i],
920: destinationID, null);
921: }
922: context.setModified(true);
923: IPrivilegedChannel bstate = new GBrowseState(context);
924: bstate.setRuntimeData(runtimeData);
925: context.setState(bstate);
926: }
927: }
928: }
|