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.UserPreferences;
007:
008: import java.io.IOException;
009: import java.io.StringWriter;
010: import java.util.Enumeration;
011: import java.util.Hashtable;
012: import java.util.Properties;
013:
014: import org.jasig.portal.ChannelRuntimeData;
015: import org.jasig.portal.GeneralRenderingException;
016: import org.jasig.portal.PortalException;
017: import org.jasig.portal.PortalSessionManager;
018: import org.jasig.portal.ResourceMissingException;
019: import org.jasig.portal.StylesheetSet;
020: import org.jasig.portal.ThemeStylesheetDescription;
021: import org.jasig.portal.UserProfile;
022: import org.jasig.portal.layout.IUserLayoutStore;
023: import org.jasig.portal.layout.UserLayoutStoreFactory;
024: import org.jasig.portal.properties.PropertiesManager;
025: import org.jasig.portal.security.IPerson;
026: import org.apache.commons.logging.Log;
027: import org.apache.commons.logging.LogFactory;
028: import org.jasig.portal.utils.DocumentFactory;
029: import org.jasig.portal.utils.XSLT;
030: import org.w3c.dom.Document;
031: import org.w3c.dom.Element;
032: import org.xml.sax.ContentHandler;
033:
034: import org.apache.xml.serialize.OutputFormat;
035: import org.apache.xml.serialize.XMLSerializer;
036:
037: /**
038: * <p>CUserPreferences state for managing profiles</p>
039: * @author Peter Kharchenko, peterk@interactivebusiness.com
040: * @version $Revision: 36729 $
041: */
042: class ManageProfilesState extends BaseState {
043: private static final Log log = LogFactory
044: .getLog(ManageProfilesState.class);
045:
046: /**
047: * Default value for ALLOW_USER_PROFILES.
048: * This value will be used when the relevant property cannot be accessed.
049: */
050: private static final boolean DEFAULT_ALLOW_USER_PROFILES = true;
051:
052: /**
053: * Default value for ALLOW_SYSTEM_BROWSER_MAPPING.
054: * This value will be used when the relevant property cannot be accessed.
055: */
056: private static final boolean DEFAULT_ALLOW_SYSTEM_BROWSER_MAPPING = true;
057:
058: /**
059: * Default value for ALLOW_NEW_PROFILE_USER_BUTTON.
060: * This value will be used when the relevant property cannot be accessed.
061: */
062: private static final boolean DEFAULT_ALLOW_NEW_PROFILE_BUTTON = true;
063:
064: protected Hashtable userProfileList;
065: protected Hashtable systemProfileList;
066: protected Hashtable userExpandStates;
067: protected Hashtable systemExpandStates;
068: protected ChannelRuntimeData runtimeData;
069: IUserLayoutStore ulsdb;
070:
071: static final boolean ALLOW_USER_PROFILES = PropertiesManager
072: .getPropertyAsBoolean(
073: "org.jasig.portal.channels.UserPreferences.ManageProfilesState.allowUserProfiles",
074: DEFAULT_ALLOW_USER_PROFILES);
075: static final boolean ALLOW_SYSTEM_BROWSER_MAPPING = PropertiesManager
076: .getPropertyAsBoolean(
077: "org.jasig.portal.channels.UserPreferences.ManageProfilesState.allowSystemProfileBrowserMapping",
078: DEFAULT_ALLOW_SYSTEM_BROWSER_MAPPING);
079: static final boolean ALLOW_NEW_PROFILE_BUTTON = PropertiesManager
080: .getPropertyAsBoolean(
081: "org.jasig.portal.channels.UserPreferences.ManageProfilesState.allowNewProfileCreation",
082: DEFAULT_ALLOW_NEW_PROFILE_BUTTON);
083:
084: public ManageProfilesState(CUserPreferences context) {
085: super (context);
086: userExpandStates = new Hashtable();
087: systemExpandStates = new Hashtable();
088: }
089:
090: protected Hashtable getUserProfileList() throws PortalException {
091: if (userProfileList == null) {
092: try {
093: userProfileList = this .getUserLayoutStore()
094: .getUserProfileList(
095: context.getUserPreferencesManager()
096: .getPerson());
097: } catch (Exception e) {
098: throw new PortalException(e);
099: }
100: }
101: return userProfileList;
102: }
103:
104: protected Hashtable getSystemProfileList() throws PortalException {
105: if (systemProfileList == null) {
106: try {
107: systemProfileList = this .getUserLayoutStore()
108: .getSystemProfileList();
109: } catch (Exception e) {
110: throw new PortalException(e);
111: }
112: }
113: return systemProfileList;
114: }
115:
116: public void setRuntimeData(ChannelRuntimeData rd)
117: throws PortalException {
118: this .runtimeData = rd;
119: // local action processing
120: String action = runtimeData.getParameter("action");
121: if (action != null) {
122: String profileId = runtimeData.getParameter("profileId");
123: boolean systemProfile = false;
124: if (profileId != null) {
125: String profileType = runtimeData
126: .getParameter("profileType");
127: if (profileType != null && profileType.equals("system"))
128: systemProfile = true;
129: if (action.equals("edit")) {
130: // initialize internal edit state
131: CEditProfile epstate = new CEditProfile(this );
132: // clear cached profile list tables
133: userProfileList = systemProfileList = null;
134: epstate.setRuntimeData(rd);
135: internalState = epstate;
136: } else if (action.equals("copy")) {
137: // retrieve a profile from the database
138: UserProfile p = null;
139: if (systemProfile) {
140: p = (UserProfile) systemProfileList
141: .get(new Integer(profileId));
142: } else {
143: p = (UserProfile) userProfileList
144: .get(new Integer(profileId));
145: }
146:
147: if (p != null) {
148: // create a new layout
149: try {
150: p = this
151: .getUserLayoutStore()
152: .addUserProfile(
153: context
154: .getUserPreferencesManager()
155: .getPerson(), p);
156: } catch (Exception e) {
157: throw new PortalException(e);
158: }
159: // reset user profile listing
160: userProfileList = null;
161: }
162: } else if (action.equals("delete")) {
163: // delete a profile
164: if (systemProfile) {
165: // need to check permissions here
166: // context.getUserPreferencesStore().deleteSystemProfile(Integer.parseInt(profileId));
167: // systemProfileList=null;
168: } else {
169: try {
170: this
171: .getUserLayoutStore()
172: .deleteUserProfile(
173: context
174: .getUserPreferencesManager()
175: .getPerson(),
176: Integer.parseInt(profileId));
177: } catch (Exception e) {
178: throw new PortalException(e);
179: }
180:
181: userProfileList = null;
182: }
183: } else if (action.equals("map")) {
184: try {
185: this
186: .getUserLayoutStore()
187: .setUserBrowserMapping(
188: context
189: .getUserPreferencesManager()
190: .getPerson(),
191: this .runtimeData
192: .getBrowserInfo()
193: .getUserAgent(),
194: Integer.parseInt(profileId));
195: } catch (Exception e) {
196: throw new PortalException(e);
197: }
198: // let userPreferencesManager know that the current profile has changed : everything must be reloaded
199: } else if (action.equals("changeView")) {
200: String view = runtimeData.getParameter("view");
201: boolean expand = false;
202: if (view.equals("expanded"))
203: expand = true;
204: if (systemProfile) {
205: systemExpandStates.put(profileId, new Boolean(
206: expand));
207: } else {
208: userExpandStates.put(profileId, new Boolean(
209: expand));
210: }
211: }
212: }
213:
214: if (action.equals("newProfile")) {
215: // get a copy of a current layout to copy the values from
216: UserProfile cp = context.getCurrentUserPreferences()
217: .getProfile();
218: if (cp != null) {
219: // create a new profile
220: UserProfile p = new UserProfile(0, "new profile",
221: "please edit the profile",
222: cp.getLayoutId(), cp
223: .getStructureStylesheetId(), cp
224: .getThemeStylesheetId());
225: try {
226: p = this .getUserLayoutStore().addUserProfile(
227: context.getUserPreferencesManager()
228: .getPerson(), p);
229: } catch (Exception e) {
230: throw new PortalException(e);
231: }
232:
233: // reset user profile listing
234: userProfileList = null;
235: }
236: } else if (action.equals("condenseAll")) {
237: String profileType = runtimeData
238: .getParameter("profileType");
239: if (profileType != null && profileType.equals("system")) {
240: // system profiles
241: systemExpandStates.clear();
242: } else {
243: // user profiles
244: userExpandStates.clear();
245: }
246: } else if (action.equals("expandAll")) {
247: String profileType = runtimeData
248: .getParameter("profileType");
249: if (profileType != null && profileType.equals("system")) {
250: // system profiles
251: systemExpandStates.clear();
252: Boolean expState = new Boolean(true);
253: for (Enumeration upe = this .getSystemProfileList()
254: .elements(); upe.hasMoreElements();) {
255: UserProfile p = (UserProfile) upe.nextElement();
256: systemExpandStates.put(Integer.toString(p
257: .getProfileId()), expState);
258: }
259: } else {
260: // user profiles
261: userExpandStates.clear();
262: Boolean expState = new Boolean(true);
263: for (Enumeration upe = this .getUserProfileList()
264: .elements(); upe.hasMoreElements();) {
265: UserProfile p = (UserProfile) upe.nextElement();
266: userExpandStates.put(Integer.toString(p
267: .getProfileId()), expState);
268: }
269: }
270: }
271: }
272: if (internalState != null)
273: internalState.setRuntimeData(rd);
274: }
275:
276: private IPerson getPerson() {
277: return context.getUserPreferencesManager().getPerson();
278: }
279:
280: private StylesheetSet getStylesheetSet() {
281: return context.getStylesheetSet();
282: }
283:
284: private IUserLayoutStore getUserLayoutStore()
285: throws PortalException {
286: // Should obtain implementation in a different way!!
287: if (ulsdb == null) {
288: ulsdb = UserLayoutStoreFactory.getUserLayoutStoreImpl();
289: }
290: if (ulsdb == null) {
291: throw new ResourceMissingException(
292: "",
293: "User Layout database",
294: "Unable to obtain the list of user profiles, since the user preference database is currently down");
295: }
296: return ulsdb;
297: }
298:
299: public void renderXML(ContentHandler out) throws PortalException {
300: // check if internal state exists, and if not, proceed with the
301: // default screen rendering (profile list screen)
302: if (internalState != null) {
303: internalState.renderXML(out);
304: } else {
305: Document doc = DocumentFactory.getNewDocument();
306: Element edEl = doc.createElement("profiles");
307: doc.appendChild(edEl);
308: if (ALLOW_USER_PROFILES) {
309: // fill out user-defined profiles
310: Element uEl = doc.createElement("user");
311: Hashtable upList = this .getUserProfileList();
312:
313: for (Enumeration upe = this .getUserProfileList()
314: .elements(); upe.hasMoreElements();) {
315: UserProfile p = (UserProfile) upe.nextElement();
316: Element pEl = doc.createElement("profile");
317: Boolean expState = (Boolean) userExpandStates
318: .get(Integer.toString(p.getProfileId()));
319: if (expState != null && expState.booleanValue()) {
320: pEl.setAttribute("view", "expanded");
321: } else {
322: pEl.setAttribute("view", "condensed");
323: }
324: pEl.setAttribute("id", Integer.toString(p
325: .getProfileId()));
326: pEl.setAttribute("name", p.getProfileName());
327: Element dEl = doc.createElement("description");
328: dEl.appendChild(doc.createTextNode(p
329: .getProfileDescription()));
330: pEl.appendChild(dEl);
331: uEl.appendChild(pEl);
332: }
333: edEl.appendChild(uEl);
334: }
335: // fill out system-defined profiles
336: Element sEl = doc.createElement("system");
337: for (Enumeration spe = this .getSystemProfileList()
338: .elements(); spe.hasMoreElements();) {
339: UserProfile p = (UserProfile) spe.nextElement();
340: Element pEl = doc.createElement("profile");
341:
342: Boolean expState = (Boolean) systemExpandStates
343: .get(Integer.toString(p.getProfileId()));
344: if (expState != null && expState.booleanValue()) {
345: pEl.setAttribute("view", "expanded");
346: } else {
347: pEl.setAttribute("view", "condensed");
348: }
349: pEl.setAttribute("id", Integer.toString(p
350: .getProfileId()));
351: pEl.setAttribute("name", p.getProfileName());
352: Element dEl = doc.createElement("description");
353: dEl.appendChild(doc.createTextNode(p
354: .getProfileDescription()));
355: pEl.appendChild(dEl);
356: sEl.appendChild(pEl);
357: }
358: edEl.appendChild(sEl);
359: /* try {
360: log.debug(org.jasig.portal.utils.XML.serializeNode(doc));
361: } catch (Exception e) {
362: log.error(e, e);
363: }
364: */
365: // debug printout of the document sent to the XSLT
366: /*
367: StringWriter dbwr1 = new StringWriter();
368: org.apache.xml.serialize.OutputFormat outputFormat = new org.apache.xml.serialize.OutputFormat();
369: outputFormat.setIndenting(true);
370: org.apache.xml.serialize.XMLSerializer dbser1 = new org.apache.xml.serialize.XMLSerializer(dbwr1, outputFormat);
371: try {
372: dbser1.serialize(doc);
373: log.debug("ManageProfilesState::renderXML() : XML incoming to the XSLT :\n\n" + dbwr1.toString() + "\n\n");
374: } catch (Exception e) {
375: log.debug("ManageProfilesState::renderXML() : problems serializing incoming XML");
376: }
377: */
378:
379: // find the stylesheet and transform
380: StylesheetSet set = context.getStylesheetSet();
381: if (set == null)
382: throw new GeneralRenderingException(
383: "Unable to determine the stylesheet list");
384: String xslURI = set.getStylesheetURI("profileList",
385: runtimeData.getBrowserInfo());
386: UserProfile currentProfile = context
387: .getCurrentUserPreferences().getProfile();
388: Hashtable params = new Hashtable();
389:
390: params.put("allowNewProfile", new Boolean(
391: ALLOW_NEW_PROFILE_BUTTON));
392: params.put("allowSystemProfileMapping", new Boolean(
393: ALLOW_SYSTEM_BROWSER_MAPPING));
394:
395: params.put("baseActionURL", runtimeData.getBaseActionURL());
396: params.put("profileId", Integer.toString(currentProfile
397: .getProfileId()));
398: if (currentProfile.isSystemProfile()) {
399: params.put("profileType", "system");
400: } else {
401: params.put("profileType", "user");
402: }
403:
404: if (xslURI != null) {
405: XSLT xslt = XSLT.getTransformer(this , runtimeData
406: .getLocales());
407: xslt.setXML(doc);
408: xslt.setXSL(this .getClass().getResource(xslURI)
409: .toString());
410: xslt.setTarget(out);
411: xslt.setStylesheetParameters(params);
412: xslt.transform();
413: } else {
414: throw new ResourceMissingException("", "stylesheet",
415: "Unable to find stylesheet to display content for this media");
416: }
417: }
418: }
419:
420: /*
421: * This state corresponds to an "edit profile" screen.
422: */
423: protected class CEditProfile extends BaseState {
424: ChannelRuntimeData runtimeData;
425: protected ManageProfilesState context;
426: protected String currentMimeType;
427: protected UserProfile profile; // profile currently being edited
428: protected boolean modified = false;
429: // location of the properties file relative to the portal base dir.
430: protected static final String mimeImagesPropsFile = "media/org/jasig/portal/channels/CUserPreferences/mimeImages.properties";
431: protected Properties mimeImagesProps = new Properties();
432:
433: public CEditProfile(ManageProfilesState context) {
434: // load the mimetype image properties file
435: java.io.InputStream in = null;
436: try {
437: in = PortalSessionManager
438: .getResourceAsStream(mimeImagesPropsFile);
439: mimeImagesProps.load(in);
440: } catch (Exception e) {
441: log
442: .error("UserPreferences:ManagerProfileState:CEditProfile::CEditProfile() : unable to load mime type images properties file located at "
443: + mimeImagesPropsFile);
444: } finally {
445: try {
446: if (in != null)
447: in.close();
448: } catch (IOException ioe) {
449: log
450: .error("ManageProfilesState:CEditProfile::unable to close InputStream "
451: + ioe);
452: }
453: }
454: this .context = context;
455: }
456:
457: public void setRuntimeData(ChannelRuntimeData rd)
458: throws PortalException {
459: this .runtimeData = rd;
460: // internal state handling
461: String action = runtimeData.getParameter("action");
462: if (action != null) {
463: if (action.equals("edit")) {
464: // this is an action from the initial profile listing screen
465: // At this point we're supposed to pick up which profile is to be
466: // edited.
467: Integer profileId = null;
468: try {
469: profileId = new Integer(runtimeData
470: .getParameter("profileId"));
471: } catch (NumberFormatException nfe) {
472: }
473: boolean systemProfile = false;
474: if (profileId == null) {
475: // return back to the base state if the profile hasn't been specified
476: context.setState(null);
477: } else {
478: String profileType = runtimeData
479: .getParameter("profileType");
480: if (profileType == null) {
481: // return to the profile listing
482: context.setState(null);
483: } else {
484: if (profileType.equals("system"))
485: systemProfile = true;
486: // find the UserProfile
487: try {
488: if (systemProfile) {
489: profile = context
490: .getUserLayoutStore()
491: .getSystemProfileById(
492: profileId
493: .intValue());
494: } else {
495: profile = context
496: .getUserLayoutStore()
497: .getUserProfileById(
498: context.getPerson(),
499: profileId
500: .intValue());
501: }
502: } catch (Exception e) {
503: throw new PortalException(e);
504: }
505:
506: if (profile == null) {
507: // failed to find the specified profile, return to the base state
508: context.setState(null);
509: }
510: }
511: }
512: } else if (action.equals("completeEdit")) {
513: if (runtimeData.getParameter("submitCancel") != null) {
514: // cancel button has been hit
515: context.setState(null);
516: } else if (runtimeData.getParameter("submitSave") != null) {
517: // save changes
518: profile.setProfileName(runtimeData
519: .getParameter("profileName"));
520: profile.setProfileDescription(runtimeData
521: .getParameter("profileDescription"));
522: // determine new theme stylesheet id
523: int newId = Integer.parseInt(runtimeData
524: .getParameter("stylesheetID"));
525: if (newId != profile.getThemeStylesheetId()) {
526: profile.setThemeStylesheetId(newId);
527: // see if the mime type has changed, alert user
528: }
529: try {
530: if (profile.isSystemProfile()) {
531: // only administrative users should be able to do this
532: context.getUserLayoutStore()
533: .updateSystemProfile(profile);
534: } else {
535: context.getUserLayoutStore()
536: .updateUserProfile(
537: context.getPerson(),
538: profile);
539: }
540: } catch (Exception e) {
541: throw new PortalException(e);
542: }
543: context.setState(null);
544: }
545: }
546: }
547: }
548:
549: public void renderXML(ContentHandler out)
550: throws PortalException {
551: // construct gpref XML
552: Document doc = DocumentFactory.getNewDocument();
553: Element profileEl = doc.createElement("profile");
554: if (this .modified) {
555: profileEl.setAttribute("modified", "true");
556: } else {
557: profileEl.setAttribute("modified", "false");
558: }
559:
560: // add profile name and description
561: {
562: Element pnameEl = doc.createElement("name");
563: pnameEl.appendChild(doc.createTextNode(profile
564: .getProfileName()));
565: profileEl.appendChild(pnameEl);
566: Element pdescrEl = doc.createElement("description");
567: pdescrEl.appendChild(doc.createTextNode(profile
568: .getProfileDescription()));
569: profileEl.appendChild(pdescrEl);
570: }
571: /*
572: // process mime type information
573: {
574: Element mimeEl=doc.createElement("mimetypes");
575: Hashtable mimeTypeList=context.getCoreStylesheetDescriptionDB().getMimeTypeList();
576: if(mimeTypeList==null) throw new ResourceMissingException("","Mime type list","Unable to retreive a listing of mime types available at this installation.");
577: // determine mime type currently assigned to this profile
578: Element cmtEl=doc.createElement("current");
579: if(currentMimeType==null) {
580: // first rendering, mime type needs to be acquired from the theme stylesheet description
581: if(profile.getThemeStylesheetName()!=null) {
582: ThemeStylesheetDescription tsd=context.getCoreStylesheetDescriptionDB().getThemeStylesheetDescription(profile.getThemeStylesheetName());
583: if(tsd==null) {
584: throw new ResourceMissingException("","Description of stylesheet \""+profile.getThemeStylesheetName()+"\"","Unable to retreive description of the theme stylesheet associated with the profile being edited.");
585: }
586: currentMimeType=tsd.getMimeType();
587: } else {
588: // may be this is a new profile, and nothing has been assigned yet, in this case set the default mimeType to text/html
589: currentMimeType="text/html";
590: }
591: }
592: Element cmtnEl=doc.createElement("name");
593: cmtnEl.appendChild(doc.createTextNode(currentMimeType));
594: Element cmtdEl=doc.createElement("description");
595: cmtdEl.appendChild(doc.createTextNode((String)mimeTypeList.get(currentMimeType)));
596: cmtEl.appendChild(cmtnEl);
597: cmtEl.appendChild(cmtdEl);
598: mimeEl.appendChild(cmtEl);
599: // list alternative mime types
600: // first, remove the current one from the alternate listing
601: mimeTypeList.remove(currentMimeType);
602: for(Enumeration me=mimeTypeList.keys();me.hasMoreElements();) {
603: Element altEl=doc.createElement("alternate");
604: String mimeType=(String)me.nextElement();
605: Element altnEl=doc.createElement("name");
606: altnEl.appendChild(doc.createTextNode(mimeType));
607: Element altdEl=doc.createElement("description");
608: altdEl.appendChild(doc.createTextNode((String)mimeTypeList.get(mimeType)));
609: altEl.appendChild(altnEl);
610: altEl.appendChild(altdEl);
611: mimeEl.appendChild(altEl);
612: }
613: profileEl.appendChild(mimeEl);
614: }
615: // deal with structure stylesheets
616: {
617: Element structEl=doc.createElement("structurestylesheets");
618: Hashtable ssList=context.getCoreStylesheetDescriptionDB().getStructureStylesheetList(currentMimeType);
619: if(ssList==null) throw new ResourceMissingException("","List of structure stylesheets for the mimeType=\""+currentMimeType+"\"","Unable to obtain a list of structure stylesheets supporting specified mime type");
620: // see if the current structure stylesheet is still in the listing
621: if(ssList.get(profile.getStructureStylesheetName())==null) {
622: if(!ssList.isEmpty()) {
623: // assign a first one in the table as a current
624: Enumeration e=ssList.keys();
625: profile.setStructureStylesheetName((String)e.nextElement());
626: } else {
627: // no alternatives :(
628: profile.setStructureStylesheetName(null);
629: }
630: }
631: // if any theme stylesheet is currently assigned
632: if(profile.getStructureStylesheetName()!=null) {
633: Element cssEl=doc.createElement("current");
634: Element cssnEl=doc.createElement("name");
635: cssnEl.appendChild(doc.createTextNode(profile.getStructureStylesheetName()));
636: Element cssdEl=doc.createElement("description");
637: cssdEl.appendChild(doc.createTextNode((String)ssList.get(profile.getStructureStylesheetName())));
638: cssEl.appendChild(cssnEl);
639: cssEl.appendChild(cssdEl);
640: structEl.appendChild(cssEl);
641: // remove the current one from the alternate listing
642: ssList.remove(profile.getStructureStylesheetName());
643: }
644: // list alternative structure stylesheets
645: for(Enumeration me=ssList.keys();me.hasMoreElements();) {
646: Element altEl=doc.createElement("alternate");
647: String ssName=(String)me.nextElement();
648: Element altnEl=doc.createElement("name");
649: altnEl.appendChild(doc.createTextNode(ssName));
650: Element altdEl=doc.createElement("description");
651: altdEl.appendChild(doc.createTextNode((String)ssList.get(ssName)));
652: altEl.appendChild(altnEl);
653: altEl.appendChild(altdEl);
654: structEl.appendChild(altEl);
655: }
656: profileEl.appendChild(structEl);
657: }*/
658:
659: // deal with theme stylesheets
660: {
661: Element themeEl = doc.createElement("themestylesheets");
662: Hashtable tsList;
663: try {
664: tsList = context.getUserLayoutStore()
665: .getThemeStylesheetList(
666: profile.getStructureStylesheetId());
667: } catch (Exception e) {
668: throw new PortalException(e);
669: }
670: if (tsList == null) {
671: throw new ResourceMissingException(
672: "",
673: "List of theme stylesheets for the structure stylesheet \""
674: + profile
675: .getStructureStylesheetId()
676: + "\"",
677: "Unable to obtain a list of theme stylesheets for the specified structure stylesheet");
678: }
679:
680: // see if the current Theme stylesheet is still in the list, otherwise assign a first one in the hastable
681: if (tsList.get(new Integer(profile
682: .getThemeStylesheetId())) == null) {
683: if (!tsList.isEmpty()) {
684: Enumeration e = tsList.keys();
685: profile.setThemeStylesheetId(((Integer) e
686: .nextElement()).intValue());
687: } else {
688: // profile.setThemeStylesheetId(-1);
689: }
690: }
691:
692: for (Enumeration me = tsList.keys(); me
693: .hasMoreElements();) {
694: Integer ssId = (Integer) me.nextElement();
695: // check if the stylesheet is current
696: boolean current = (ssId.intValue() == profile
697: .getThemeStylesheetId());
698: Element altEl;
699: if (current) {
700: altEl = doc.createElement("current");
701: } else {
702: altEl = doc.createElement("alternate");
703: }
704:
705: ThemeStylesheetDescription tsd = (ThemeStylesheetDescription) tsList
706: .get(ssId);
707: Element altnEl = doc.createElement("name");
708: altnEl.appendChild(doc.createTextNode(tsd
709: .getStylesheetName()));
710: Element altidEl = doc.createElement("id");
711: altidEl.appendChild(doc.createTextNode(Integer
712: .toString(tsd.getId())));
713: Element altdEl = doc.createElement("description");
714: altdEl.appendChild(doc.createTextNode(tsd
715: .getStylesheetWordDescription()));
716: Element altmEl = doc.createElement("mimetype");
717: altmEl.appendChild(doc.createTextNode(tsd
718: .getMimeType()));
719: // determine device icon
720: String deviceIconURI;
721: if ((deviceIconURI = mimeImagesProps
722: .getProperty(tsd.getDeviceType())) == null) {
723: deviceIconURI = mimeImagesProps
724: .getProperty("unknown");
725: }
726: Element altdiuEl = doc
727: .createElement("deviceiconuri");
728: altdiuEl.appendChild(doc
729: .createTextNode(deviceIconURI));
730: Element altsuEl = doc.createElement("sampleuri");
731: if (tsd.getSamplePictureURI() == null
732: || tsd.getSamplePictureURI().equals("")) {
733: altsuEl.appendChild(doc.createTextNode(""));
734: } else {
735: altsuEl.appendChild(doc.createTextNode(tsd
736: .getSamplePictureURI()));
737: }
738:
739: Element altsiuEl = doc
740: .createElement("sampleiconuri");
741: if (tsd.getSampleIconURI() == null
742: || tsd.getSampleIconURI().equals("")) {
743: altsiuEl.appendChild(doc.createTextNode(""));
744: } else {
745: altsiuEl.appendChild(doc.createTextNode(tsd
746: .getSampleIconURI()));
747: }
748:
749: altEl.appendChild(altnEl);
750: altEl.appendChild(altidEl);
751: altEl.appendChild(altdEl);
752: altEl.appendChild(altmEl);
753: altEl.appendChild(altdiuEl);
754: altEl.appendChild(altsuEl);
755: altEl.appendChild(altsiuEl);
756: themeEl.appendChild(altEl);
757: }
758: profileEl.appendChild(themeEl);
759: }
760: doc.appendChild(profileEl);
761:
762: // debug printout of the prepared xml
763: if (log.isDebugEnabled()) {
764: try {
765: StringWriter outString = new StringWriter();
766: /*
767: * This should be reviewed at some point to see if we can
768: * use the DOM3 LS capability and hence a standard way of
769: * doing this rather than using an internal implementation
770: * class.
771: */
772: OutputFormat format = new OutputFormat();
773: format.setOmitXMLDeclaration(true);
774: format.setIndenting(true);
775: XMLSerializer serializer = new XMLSerializer(
776: outString, format);
777: serializer.serialize(doc);
778: log.debug(outString.toString());
779: } catch (Exception e) {
780: log.debug(e, e);
781: }
782: }
783: // end debug block
784:
785: StylesheetSet set = context.getStylesheetSet();
786: if (set == null)
787: throw new GeneralRenderingException(
788: "Unable to determine the stylesheet list");
789: String xslURI = set.getStylesheetURI("editProfile",
790: runtimeData.getBrowserInfo());
791: if (xslURI != null) {
792: XSLT xslt = XSLT.getTransformer(this , runtimeData
793: .getLocales());
794: xslt.setXML(doc);
795: xslt.setXSL(this .getClass().getResource(xslURI)
796: .toString());
797: xslt.setTarget(out);
798: xslt.setStylesheetParameter("baseActionURL",
799: runtimeData.getBaseActionURL());
800: xslt.transform();
801: } else {
802: throw new ResourceMissingException("", "stylesheet",
803: "Unable to find stylesheet to display content for this media");
804: }
805: }
806: }
807: }
|