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