001: /* Copyright 2004 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.alm.channels;
007:
008: import java.util.ArrayList;
009: import java.util.Collection;
010: import java.util.HashMap;
011: import java.util.Iterator;
012: import java.util.List;
013: import java.util.Map;
014:
015: import org.jasig.portal.AuthorizationException;
016: import org.jasig.portal.ChannelRuntimeData;
017: import org.jasig.portal.IServant;
018: import org.jasig.portal.PortalControlStructures;
019: import org.jasig.portal.PortalException;
020: import org.jasig.portal.channels.groupsmanager.CGroupsManagerServantFactory;
021: import org.jasig.portal.groups.IGroupMember;
022: import org.jasig.portal.layout.alm.ALFragment;
023: import org.jasig.portal.layout.alm.ALNode;
024: import org.jasig.portal.layout.alm.IALFolderDescription;
025: import org.jasig.portal.layout.node.IUserLayoutNodeDescription;
026: import org.jasig.portal.services.GroupService;
027: import org.jasig.portal.utils.CommonUtils;
028: import org.jasig.portal.utils.DocumentFactory;
029: import org.jasig.portal.utils.SAX2FilterImpl;
030: import org.jasig.portal.utils.XSLT;
031: import org.w3c.dom.Document;
032: import org.w3c.dom.Element;
033: import org.xml.sax.Attributes;
034: import org.xml.sax.ContentHandler;
035: import org.xml.sax.SAXException;
036:
037: /**
038: * A channel for adding new content to a layout.
039: *
040: * Prior to uPortal 2.5, this channel existed in the package
041: * org.jasig.portal.layout.channels. It was moved to its present package to reflect that
042: * it is part of Aggregated Layouts.
043: *
044: * @author Michael Ivanov, mvi@immagic.com
045: * @version $Revision: 36811 $
046: * @since uPortal 2.5
047: */
048: public class CFragmentManager extends FragmentManager {
049:
050: private static final String sslLocation = "/org/jasig/portal/channels/CFragmentManager/CFragmentManager.ssl";
051: private boolean servantRender = false;
052: private String servantFragmentId;
053: private static Map servants = new HashMap();
054: private final static int MAX_SERVANTS = 50;
055:
056: public CFragmentManager() throws PortalException {
057: super ();
058: }
059:
060: private class ServantSAXFilter extends SAX2FilterImpl {
061:
062: public ServantSAXFilter(ContentHandler ch)
063: throws PortalException {
064: super (ch);
065: }
066:
067: public void startElement(String uri, String localName,
068: String qName, Attributes atts) throws SAXException {
069: try {
070: super .startElement(uri, localName, qName, atts);
071: if (qName.equals("groupServant")) {
072: if (servantRender) {
073: getGroupServant().renderXML(contentHandler);
074: }
075: }
076:
077: } catch (Exception e) {
078: throw new SAXException(e.toString());
079: }
080: }
081:
082: }
083:
084: private synchronized IGroupMember[] getGroupMembers(
085: String fragmentId) throws PortalException {
086: Collection groupKeys = alm.getPublishGroups(fragmentId);
087: ArrayList members = new ArrayList();
088: int i = 0;
089: IGroupMember member;
090: for (Iterator keys = groupKeys.iterator(); keys.hasNext(); i++) {
091: String groupKey = (String) keys.next();
092: member = GroupService.findGroup(groupKey);
093: if (member != null) {
094: members.add(member);
095: } else {
096: log
097: .warn("Unable to find group member for the groupKey: "
098: + groupKey);
099: }
100: }
101: return (IGroupMember[]) members.toArray(new IGroupMember[0]);
102: }
103:
104: private String getServantKey() {
105: return CommonUtils.envl(servantFragmentId, "new");
106: }
107:
108: /**
109: * Produces a group servant
110: * @return the group servant
111: */
112: private synchronized IServant getGroupServant()
113: throws PortalException {
114: if (servants.size() > MAX_SERVANTS)
115: servants.clear();
116: IServant groupServant = (IServant) servants
117: .get(getServantKey());
118: if (groupServant == null) {
119: try {
120: // create the appropriate servant
121: if (servantFragmentId != null
122: && CommonUtils.parseInt(servantFragmentId) > 0) {
123: IGroupMember[] members = getGroupMembers(servantFragmentId);
124: groupServant = CGroupsManagerServantFactory
125: .getGroupsServantforSelection(
126: staticData,
127: "Please select groups or people who should have access to this fragment:",
128: GroupService.EVERYONE, true, true,
129: members);
130: } else
131: groupServant = CGroupsManagerServantFactory
132: .getGroupsServantforSelection(
133: staticData,
134: "Please select groups or people who should have access to this fragment:",
135: GroupService.EVERYONE);
136:
137: if (groupServant != null)
138: servants.put(getServantKey(), groupServant);
139:
140: } catch (Exception e) {
141: throw new PortalException(e);
142: }
143: }
144: groupServant.setRuntimeData((ChannelRuntimeData) runtimeData
145: .clone());
146: return groupServant;
147: }
148:
149: private String createFolder(ALFragment fragment)
150: throws PortalException {
151: IALFolderDescription folderDesc = (IALFolderDescription) alm
152: .createNodeDescription(IUserLayoutNodeDescription.FOLDER);
153: folderDesc.setName("Fragment column");
154: folderDesc.setFragmentId(fragment.getId());
155: return alm.addNode(folderDesc,
156: getFragmentRootId(fragment.getId()), null).getId();
157: }
158:
159: protected ErrorMessage[] analyzeParameters(XSLT xslt)
160: throws PortalException {
161:
162: String fragmentId = CommonUtils.nvl(runtimeData
163: .getParameter("uPcFM_selectedID"));
164: String action = CommonUtils.nvl(runtimeData
165: .getParameter("uPcFM_action"));
166: List rslt = new ArrayList();
167:
168: if (action.equals("save_new")) {
169: String fragmentName = runtimeData
170: .getParameter("fragment_name");
171: String funcName = runtimeData
172: .getParameter("fragment_fname");
173: String fragmentDesc = runtimeData
174: .getParameter("fragment_desc");
175: String fragmentType = runtimeData
176: .getParameter("fragment_type");
177: String fragmentFolder = runtimeData
178: .getParameter("fragment_add_folder");
179: boolean isPushedFragment = ("pushed".equals(fragmentType)) ? true
180: : false;
181: fragmentId = alm.createFragment(CommonUtils.nvl(funcName),
182: CommonUtils.nvl(fragmentDesc), CommonUtils
183: .nvl(fragmentName));
184: ALFragment newFragment = (ALFragment) alm
185: .getFragment(fragmentId);
186: if (newFragment != null) {
187: if (isPushedFragment)
188: newFragment.setPushedFragment();
189: else
190: newFragment.setPulledFragment();
191: // Saving the changes in the database
192: alm.saveFragment(newFragment);
193: // Saving user's layout to database
194: alm.saveUserLayout();
195: // Updating the fragments map
196: fragments.put(fragmentId, newFragment);
197: // Check if we need to create an additional folder on the fragment root
198: if ("true".equals(fragmentFolder)) {
199: alm.loadFragment(fragmentId);
200: createFolder(newFragment);
201: alm.saveFragment();
202: }
203: }
204: } else if (action.equals("save")) {
205: String funcName = runtimeData
206: .getParameter("fragment_fname");
207: String fragmentName = runtimeData
208: .getParameter("fragment_name");
209: String fragmentDesc = runtimeData
210: .getParameter("fragment_desc");
211: String fragmentType = runtimeData
212: .getParameter("fragment_type");
213: boolean isPushedFragment = ("pushed".equals(fragmentType)) ? true
214: : false;
215: ALFragment fragment = (ALFragment) fragments
216: .get(fragmentId);
217: if (fragment != null) {
218: if (isPushedFragment)
219: fragment.setPushedFragment();
220: else
221: fragment.setPulledFragment();
222: fragment.setFunctionalName(CommonUtils.nvl(funcName));
223: fragment.setDescription(CommonUtils.nvl(fragmentDesc));
224: String fragmentRootId = getFragmentRootId(fragmentId);
225: ALNode fragmentRoot = fragment.getNode(fragmentRootId);
226: fragmentRoot.getNodeDescription().setName(fragmentName);
227: // Saving the changes in the database
228: alm.saveFragment(fragment);
229: }
230: } else if (action.equals("delete")) {
231: if (CommonUtils.parseInt(fragmentId) > 0) {
232: alm.deleteFragment(fragmentId);
233: // Updating the fragments map
234: fragments.remove(fragmentId);
235: fragmentId = (fragments != null && !fragments.isEmpty()) ? (String) fragments
236: .keySet().toArray()[0]
237: : "";
238: } else
239: new PortalException("Invalid fragment ID=" + fragmentId);
240: } else if (action.equals("publish")) {
241: servantRender = true;
242: servantFragmentId = fragmentId;
243: } else if (action.equals("publish_finish")) {
244: IGroupMember[] gms = (IGroupMember[]) getGroupServant()
245: .getResults();
246: for (int i = 0; i < gms.length; i++)
247: System.out.println("group key: " + gms[i].getKey());
248: servantRender = false;
249: }
250:
251: if (getGroupServant().isFinished()) {
252: IGroupMember[] gms = (IGroupMember[]) getGroupServant()
253: .getResults();
254: List fwd = new ArrayList();
255: List cull = new ArrayList();
256: for (int i = 0; i < gms.length; i++) {
257: if (gms[i].isGroup()) {
258: fwd.add(gms[i]);
259: } else {
260: cull.add(gms[i]);
261: }
262: }
263: gms = (IGroupMember[]) fwd.toArray(new IGroupMember[0]);
264:
265: // Send a msg if there were users selected.
266: if (cull.size() > 0) {
267: String title = "Unable to Publish to Some Targets";
268: StringBuffer desc = new StringBuffer();
269: desc
270: .append(
271: "Fragments may only be associated with groups. ")
272: .append(
273: "The following selections are not groups, and ")
274: .append("will be ignored: ");
275: for (int i = 0; i < cull.size(); i++) {
276: IGroupMember m = (IGroupMember) cull.get(i);
277: desc.append(m.getKey());
278: if (i == cull.size() - 1) {
279: desc.append(".");
280: } else {
281: desc.append(", ");
282: }
283: }
284: rslt.add(new ErrorMessage(title, desc.toString()));
285: }
286:
287: if (gms != null
288: && "Done".equals(runtimeData
289: .getParameter("grpCommand")))
290: alm.setPublishGroups(gms, servantFragmentId);
291: servants.remove(getServantKey());
292: servantRender = false;
293: }
294:
295: boolean noAction = action.equals("");
296: if (servantRender && noAction) {
297: fragmentId = servantFragmentId;
298: action = "publish";
299: }
300:
301: // Loading the default layout if the fragment is loaded in the theme
302: if ("default".equals(action) && alm.isFragmentLoaded())
303: alm.loadUserLayout();
304:
305: xslt.setStylesheetParameter("uPcFM_selectedID", fragmentId);
306: xslt.setStylesheetParameter("uPcFM_action", action);
307: return (ErrorMessage[]) rslt.toArray(new ErrorMessage[rslt
308: .size()]);
309: }
310:
311: /**
312: * Passes portal control structure to the channel.
313: * @see PortalControlStructures
314: */
315: public void setPortalControlStructures(PortalControlStructures pcs)
316: throws PortalException {
317: super .setPortalControlStructures(pcs);
318: if (alm == null)
319: throw new PortalException(
320: "The layout manager must have type IAgreggatedUserLayoutManager!");
321: refreshFragmentMap();
322: }
323:
324: private Document getFragmentList() throws PortalException {
325: Document document = DocumentFactory.getNewDocument();
326: super .getFragmentList(document);
327: return document;
328: }
329:
330: protected Collection getFragments() throws PortalException {
331: return alm.getFragments();
332: }
333:
334: public void renderXML(ContentHandler out) throws PortalException {
335:
336: if (!staticData.getAuthorizationPrincipal().canPublish()) {
337: final String msg = "User is not authorized to access Fragment Manager";
338: throw new AuthorizationException(msg, false, false);
339: }
340:
341: XSLT xslt = XSLT.getTransformer(this , runtimeData.getLocales());
342:
343: ErrorMessage[] errors = analyzeParameters(xslt);
344: Document doc = getFragmentList();
345: Element frag = doc.getDocumentElement();
346: Element cat = (Element) frag.getFirstChild();
347: for (int i = 0; i < errors.length; i++) {
348: Element e = errors[i].toElement(doc);
349: frag.insertBefore(e, cat);
350: }
351:
352: xslt.setXML(doc);
353: xslt.setXSL(sslLocation, "fragmentManager", runtimeData
354: .getBrowserInfo());
355: xslt.setTarget(new ServantSAXFilter(out));
356: xslt.setStylesheetParameter("baseActionURL", runtimeData
357: .getBaseActionURL());
358:
359: xslt.transform();
360: }
361:
362: }
|