001: /******************************************************************************
002: * JBoss, a division of Red Hat *
003: * Copyright 2006, Red Hat Middleware, LLC, and individual *
004: * contributors as indicated by the @authors tag. See the *
005: * copyright.txt in the distribution for a full listing of *
006: * individual contributors. *
007: * *
008: * This is free software; you can redistribute it and/or modify it *
009: * under the terms of the GNU Lesser General Public License as *
010: * published by the Free Software Foundation; either version 2.1 of *
011: * the License, or (at your option) any later version. *
012: * *
013: * This software is distributed in the hope that it will be useful, *
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of *
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
016: * Lesser General Public License for more details. *
017: * *
018: * You should have received a copy of the GNU Lesser General Public *
019: * License along with this software; if not, write to the Free *
020: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
021: * 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
022: ******************************************************************************/package org.jboss.portal.wsrp.producer;
023:
024: import org.jboss.portal.common.i18n.LocalizedString;
025: import org.jboss.portal.common.util.Tools;
026: import org.jboss.portal.common.value.StringValue;
027: import org.jboss.portal.common.value.Value;
028: import org.jboss.portal.portlet.InvalidPortletIdException;
029: import org.jboss.portal.portlet.NoSuchPortletException;
030: import org.jboss.portal.portlet.Portlet;
031: import org.jboss.portal.portlet.PortletInvokerException;
032: import org.jboss.portal.portlet.info.PortletInfo;
033: import org.jboss.portal.portlet.info.PreferenceInfo;
034: import org.jboss.portal.portlet.info.PreferencesInfo;
035: import org.jboss.portal.portlet.state.DestroyCloneFailure;
036: import org.jboss.portal.portlet.state.PropertyChange;
037: import org.jboss.portal.portlet.state.PropertyMap;
038: import org.jboss.portal.registration.Registration;
039: import org.jboss.portal.registration.RegistrationLocal;
040: import org.jboss.portal.wsrp.WSRPConstants;
041: import org.jboss.portal.wsrp.WSRPExceptionFactory;
042: import org.jboss.portal.wsrp.WSRPTypeFactory;
043: import org.jboss.portal.wsrp.WSRPUtils;
044: import org.jboss.portal.wsrp.core.AccessDeniedFault;
045: import org.jboss.portal.wsrp.core.ClonePortlet;
046: import org.jboss.portal.wsrp.core.DestroyFailed;
047: import org.jboss.portal.wsrp.core.DestroyPortlets;
048: import org.jboss.portal.wsrp.core.DestroyPortletsResponse;
049: import org.jboss.portal.wsrp.core.GetPortletDescription;
050: import org.jboss.portal.wsrp.core.GetPortletProperties;
051: import org.jboss.portal.wsrp.core.GetPortletPropertyDescription;
052: import org.jboss.portal.wsrp.core.InconsistentParametersFault;
053: import org.jboss.portal.wsrp.core.InvalidHandleFault;
054: import org.jboss.portal.wsrp.core.InvalidRegistrationFault;
055: import org.jboss.portal.wsrp.core.InvalidUserCategoryFault;
056: import org.jboss.portal.wsrp.core.MissingParametersFault;
057: import org.jboss.portal.wsrp.core.OperationFailedFault;
058: import org.jboss.portal.wsrp.core.PortletContext;
059: import org.jboss.portal.wsrp.core.PortletDescription;
060: import org.jboss.portal.wsrp.core.PortletDescriptionResponse;
061: import org.jboss.portal.wsrp.core.PortletPropertyDescriptionResponse;
062: import org.jboss.portal.wsrp.core.Property;
063: import org.jboss.portal.wsrp.core.PropertyDescription;
064: import org.jboss.portal.wsrp.core.PropertyList;
065: import org.jboss.portal.wsrp.core.ResetProperty;
066: import org.jboss.portal.wsrp.core.SetPortletProperties;
067: import org.jboss.portal.wsrp.core.UserContext;
068: import org.jboss.portal.wsrp.core.WSRP_v1_PortletManagement_PortType;
069:
070: import javax.xml.soap.SOAPElement;
071: import java.rmi.RemoteException;
072: import java.util.ArrayList;
073: import java.util.Collections;
074: import java.util.Iterator;
075: import java.util.List;
076: import java.util.Map;
077: import java.util.Set;
078:
079: /**
080: * @author <a href="mailto:chris.laprun@jboss.com">Chris Laprun</a>
081: * @version $Revision: 9360 $
082: * @since 2.4
083: */
084: class PortletManagementHandler extends ServiceHandler implements
085: WSRP_v1_PortletManagement_PortType {
086: private static final String GET_PORTLET_PROPERTY_DESCRIPTION = "GetPortletPropertyDescription";
087: private static final String GET_PORTLET_PROPERTIES = "GetPortletProperties";
088: private static final String PORTLET_CONTEXT = "PortletContext";
089: private static final String GET_PORTLET_DESCRIPTION = "GetPortletDescription";
090:
091: PortletManagementHandler(WSRPProducerImpl producer) {
092: super (producer);
093: }
094:
095: public PortletDescriptionResponse getPortletDescription(
096: GetPortletDescription getPortletDescription)
097: throws AccessDeniedFault, InvalidHandleFault,
098: InvalidUserCategoryFault, InconsistentParametersFault,
099: MissingParametersFault, InvalidRegistrationFault,
100: OperationFailedFault, RemoteException {
101: WSRPExceptionFactory.throwOperationFailedFaultIfValueIsMissing(
102: getPortletDescription, GET_PORTLET_DESCRIPTION);
103: Registration registration = producer
104: .getRegistrationOrFailIfInvalid(getPortletDescription
105: .getRegistrationContext());
106:
107: PortletContext portletContext = getPortletDescription
108: .getPortletContext();
109: WSRPExceptionFactory
110: .throwMissingParametersFaultIfValueIsMissing(
111: portletContext, PORTLET_CONTEXT,
112: GET_PORTLET_DESCRIPTION);
113:
114: UserContext userContext = getPortletDescription
115: .getUserContext();
116: checkUserAuthorization(userContext);
117:
118: // RegistrationLocal.setRegistration is called further down the invocation in ServiceDescriptionHandler.getPortletDescription
119: PortletDescription description = producer
120: .getPortletDescription(portletContext,
121: getPortletDescription.getDesiredLocales(),
122: registration);
123: return WSRPTypeFactory
124: .createPortletDescriptionResponse(description);
125: }
126:
127: public PortletPropertyDescriptionResponse getPortletPropertyDescription(
128: GetPortletPropertyDescription getPortletPropertyDescription)
129: throws MissingParametersFault, InconsistentParametersFault,
130: InvalidUserCategoryFault, InvalidRegistrationFault,
131: AccessDeniedFault, InvalidHandleFault,
132: OperationFailedFault, RemoteException {
133: WSRPExceptionFactory.throwOperationFailedFaultIfValueIsMissing(
134: getPortletPropertyDescription,
135: GET_PORTLET_PROPERTY_DESCRIPTION);
136:
137: PortletContext portletContext = getPortletPropertyDescription
138: .getPortletContext();
139: WSRPExceptionFactory
140: .throwMissingParametersFaultIfValueIsMissing(
141: portletContext, PORTLET_CONTEXT,
142: GET_PORTLET_PROPERTY_DESCRIPTION);
143:
144: Registration registration = producer
145: .getRegistrationOrFailIfInvalid(getPortletPropertyDescription
146: .getRegistrationContext());
147:
148: UserContext userContext = getPortletPropertyDescription
149: .getUserContext();
150: checkUserAuthorization(userContext);
151:
152: String[] desiredLocales = getPortletPropertyDescription
153: .getDesiredLocales();
154: Portlet portlet = getPortletFrom(portletContext, registration);
155: PortletInfo info = portlet.getInfo();
156: PreferencesInfo prefsInfo = info.getPreferences();
157:
158: PropertyDescription[] descs = null;
159: if (prefsInfo != null) {
160: Set keySet = prefsInfo.getKeys();
161: descs = new PropertyDescription[keySet.size()];
162: int index = 0;
163: for (Object key : keySet) {
164: PreferenceInfo prefInfo = prefsInfo
165: .getPreference((String) key);
166:
167: // WSRP Spec 8.7: return only the portion of the Portlet's persistent state the user is allowed to modify
168: // if read only status is not determined, we consider it as being read-only to be safe
169: Boolean readOnly = prefInfo.isReadOnly();
170: if (readOnly != null && !readOnly) {
171: //todo: check what we should use key
172: //todo: right now we only support String properties
173: PropertyDescription desc = WSRPTypeFactory
174: .createPropertyDescription(prefInfo
175: .getKey(), WSRPConstants.XSD_STRING);
176: desc.setLabel(WSRPUtils
177: .convertToWSRPLocalizedString(prefInfo
178: .getDisplayName(), desiredLocales));
179: desc.setHint(WSRPUtils
180: .convertToWSRPLocalizedString(prefInfo
181: .getDescription(), desiredLocales));
182: descs[index++] = desc;
183: }
184: }
185: }
186:
187: return WSRPTypeFactory
188: .createPortletPropertyDescriptionResponse(descs);
189: }
190:
191: public PortletContext clonePortlet(ClonePortlet clonePortlet)
192: throws InvalidUserCategoryFault, AccessDeniedFault,
193: OperationFailedFault, InvalidHandleFault,
194: InvalidRegistrationFault, InconsistentParametersFault,
195: MissingParametersFault, RemoteException {
196: WSRPExceptionFactory.throwOperationFailedFaultIfValueIsMissing(
197: clonePortlet, "ClonePortlet");
198:
199: PortletContext portletContext = clonePortlet
200: .getPortletContext();
201: WSRPExceptionFactory
202: .throwMissingParametersFaultIfValueIsMissing(
203: portletContext, "PortletContext",
204: "ClonePortlet");
205:
206: Registration registration = producer
207: .getRegistrationOrFailIfInvalid(clonePortlet
208: .getRegistrationContext());
209:
210: UserContext userContext = clonePortlet.getUserContext();
211: checkUserAuthorization(userContext);
212:
213: org.jboss.portal.portlet.PortletContext portalPC = WSRPUtils
214: .convertToPortalPortletContext(portletContext);
215: try {
216: RegistrationLocal.setRegistration(registration);
217: org.jboss.portal.portlet.PortletContext response = producer
218: .getInvoker().createClone(portalPC);
219: return WSRPUtils.convertToWSRPPortletContext(response);
220: } catch (NoSuchPortletException e) {
221: throw WSRPExceptionFactory.throwSOAPFaultException(
222: WSRPExceptionFactory.INVALID_HANDLE,
223: "Failed to create clone for portlet '"
224: + portletContext.getPortletHandle(), e);
225: } catch (InvalidPortletIdException e) {
226: throw WSRPExceptionFactory.throwSOAPFaultException(
227: WSRPExceptionFactory.INCONSISTENT_PARAMETERS,
228: "Failed to create clone for portlet '"
229: + portletContext.getPortletHandle(), e);
230: } catch (PortletInvokerException e) {
231: throw WSRPExceptionFactory.throwSOAPFaultException(
232: WSRPExceptionFactory.OPERATION_FAILED,
233: "Failed to create clone for portlet '"
234: + portletContext.getPortletHandle(), e);
235: } finally {
236: RegistrationLocal.setRegistration(null);
237: }
238: }
239:
240: public DestroyPortletsResponse destroyPortlets(
241: DestroyPortlets destroyPortlets)
242: throws InconsistentParametersFault, MissingParametersFault,
243: InvalidRegistrationFault, OperationFailedFault,
244: RemoteException {
245: WSRPExceptionFactory.throwOperationFailedFaultIfValueIsMissing(
246: destroyPortlets, "DestroyPortlets");
247:
248: String[] handles = destroyPortlets.getPortletHandles();
249: WSRPExceptionFactory
250: .throwMissingParametersFaultIfValueIsMissing(handles,
251: "portlet handles to be destroyed",
252: "DestroyPortlets");
253:
254: Registration registration = producer
255: .getRegistrationOrFailIfInvalid(destroyPortlets
256: .getRegistrationContext());
257:
258: List portletContexts = new ArrayList(handles.length);
259: for (int i = 0; i < handles.length; i++) {
260: portletContexts.add(org.jboss.portal.portlet.PortletContext
261: .createPortletContext(handles[i]));
262: }
263:
264: try {
265: RegistrationLocal.setRegistration(registration);
266: List failuresList = producer.getInvoker().destroyClones(
267: portletContexts);
268: int failuresNumber = failuresList.size();
269: DestroyFailed[] destroyFailed;
270: if (failuresNumber > 0) {
271: destroyFailed = new DestroyFailed[failuresNumber];
272: int i = 0;
273: for (Object aFailuresList : failuresList) {
274: DestroyCloneFailure failure = (DestroyCloneFailure) aFailuresList;
275: destroyFailed[i++] = WSRPTypeFactory
276: .createDestroyFailed(
277: failure.getPortletId(), failure
278: .getMessage());
279: }
280: } else {
281: destroyFailed = null;
282: }
283:
284: return WSRPTypeFactory
285: .createDestroyPortletsResponse(destroyFailed);
286: } catch (PortletInvokerException e) {
287: throw WSRPExceptionFactory.throwSOAPFaultException(
288: WSRPExceptionFactory.OPERATION_FAILED,
289: "Failed to destroy clones", e);
290: } finally {
291: RegistrationLocal.setRegistration(null);
292: }
293: }
294:
295: public PortletContext setPortletProperties(
296: SetPortletProperties setPortletProperties)
297: throws OperationFailedFault, InvalidHandleFault,
298: MissingParametersFault, InconsistentParametersFault,
299: InvalidUserCategoryFault, AccessDeniedFault,
300: InvalidRegistrationFault, RemoteException {
301: WSRPExceptionFactory.throwOperationFailedFaultIfValueIsMissing(
302: setPortletProperties, "SetPortletProperties");
303:
304: PortletContext portletContext = setPortletProperties
305: .getPortletContext();
306: WSRPExceptionFactory
307: .throwMissingParametersFaultIfValueIsMissing(
308: portletContext, "PortletContext",
309: "SetPortletProperties");
310:
311: PropertyList propertyList = setPortletProperties
312: .getPropertyList();
313: WSRPExceptionFactory
314: .throwMissingParametersFaultIfValueIsMissing(
315: propertyList, "PropertyList",
316: "SetPortletProperties");
317:
318: Registration registration = producer
319: .getRegistrationOrFailIfInvalid(setPortletProperties
320: .getRegistrationContext());
321:
322: checkUserAuthorization(setPortletProperties.getUserContext());
323:
324: Property[] properties = propertyList.getProperties();
325: ResetProperty[] resetProperties = propertyList
326: .getResetProperties();
327: int changesCount = 0;
328: if (properties != null) {
329: changesCount += properties.length;
330: }
331: if (resetProperties != null) {
332: changesCount += resetProperties.length;
333: }
334:
335: if (changesCount > 0) {
336: List changes = new ArrayList(changesCount);
337:
338: if (properties != null) {
339: for (int i = 0; i < properties.length; i++) {
340: Property property = properties[i];
341: String value = property.getStringValue();
342:
343: // todo: deal with XML values...
344: SOAPElement[] values = property.get_any();
345: String lang = property.getLang(); // todo: deal with language?
346:
347: changes.add(PropertyChange.newUpdate(property
348: .getName(), new StringValue(value)));
349: }
350: }
351:
352: if (resetProperties != null) {
353: for (int i = 0; i < resetProperties.length; i++) {
354: ResetProperty resetProperty = resetProperties[i];
355: changes.add(PropertyChange.newReset(resetProperty
356: .getName()));
357: }
358: }
359:
360: try {
361: RegistrationLocal.setRegistration(registration);
362: org.jboss.portal.portlet.PortletContext resultContext = producer
363: .getInvoker()
364: .setProperties(
365: WSRPUtils
366: .convertToPortalPortletContext(portletContext),
367: (PropertyChange[]) changes
368: .toArray(new PropertyChange[0]));
369: return WSRPUtils
370: .convertToWSRPPortletContext(resultContext);
371: } catch (NoSuchPortletException e) {
372: throw WSRPExceptionFactory.throwSOAPFaultException(
373: WSRPExceptionFactory.INVALID_HANDLE,
374: "Failed to set properties for portlet '"
375: + portletContext.getPortletHandle()
376: + "'", e);
377: } catch (InvalidPortletIdException e) {
378: throw WSRPExceptionFactory.throwSOAPFaultException(
379: WSRPExceptionFactory.INCONSISTENT_PARAMETERS,
380: "Failed to set properties for portlet '"
381: + portletContext.getPortletHandle()
382: + "'", e);
383: } catch (PortletInvokerException e) {
384: throw WSRPExceptionFactory.throwSOAPFaultException(
385: WSRPExceptionFactory.OPERATION_FAILED,
386: "Failed to set properties for portlet '"
387: + portletContext.getPortletHandle()
388: + "'", e);
389: } finally {
390: RegistrationLocal.setRegistration(null);
391: }
392: }
393:
394: return portletContext;
395: }
396:
397: public PropertyList getPortletProperties(
398: GetPortletProperties getPortletProperties)
399: throws InvalidHandleFault, MissingParametersFault,
400: InvalidRegistrationFault, AccessDeniedFault,
401: OperationFailedFault, InconsistentParametersFault,
402: InvalidUserCategoryFault, RemoteException {
403: WSRPExceptionFactory.throwOperationFailedFaultIfValueIsMissing(
404: getPortletProperties, GET_PORTLET_PROPERTIES);
405:
406: PortletContext portletContext = getPortletProperties
407: .getPortletContext();
408: WSRPExceptionFactory
409: .throwMissingParametersFaultIfValueIsMissing(
410: portletContext, PORTLET_CONTEXT,
411: GET_PORTLET_PROPERTIES);
412:
413: Registration registration = producer
414: .getRegistrationOrFailIfInvalid(getPortletProperties
415: .getRegistrationContext());
416:
417: UserContext userContext = getPortletProperties.getUserContext();
418: checkUserAuthorization(userContext);
419:
420: String[] names = getPortletProperties.getNames();
421: Set keys = getKeysFromNames(names);
422:
423: try {
424: PropertyMap properties;
425: org.jboss.portal.portlet.PortletContext jbpContext = WSRPUtils
426: .convertToPortalPortletContext(portletContext);
427:
428: RegistrationLocal.setRegistration(registration);
429: if (keys != null) {
430: properties = producer.getInvoker().getProperties(
431: jbpContext, keys);
432: } else {
433: properties = producer.getInvoker().getProperties(
434: jbpContext);
435: }
436:
437: //todo: we need to check that the user can actually modify the properties
438: Portlet portlet = getPortletFrom(portletContext,
439: registration);
440: PortletInfo info = portlet.getInfo();
441:
442: PropertyList result = WSRPTypeFactory.createPropertyList();
443: int propertyNb = properties.size();
444:
445: if (propertyNb > 0) {
446: Property[] resProperties = new Property[propertyNb];
447: int i = 0;
448: PreferenceInfo prefInfo;
449: String key;
450: Value value;
451: LocalizedString displayName;
452:
453: for (Iterator entries = properties.entrySet()
454: .iterator(); entries.hasNext(); i++) {
455: Map.Entry entry = (Map.Entry) entries.next();
456: key = (String) entry.getKey();
457: value = (Value) entry.getValue();
458: prefInfo = info.getPreferences().getPreference(key);
459: displayName = prefInfo.getDisplayName();
460: String lang = WSRPUtils.toString(displayName
461: .getDefaultLocale());
462: resProperties[i] = WSRPTypeFactory.createProperty(
463: key, lang, value.asString()); //todo: check what we should use key
464: }
465:
466: result.setProperties(resProperties);
467: }
468:
469: return result;
470: } catch (PortletInvokerException e) {
471: throw WSRPExceptionFactory.throwSOAPFaultException(
472: WSRPExceptionFactory.INVALID_HANDLE,
473: "Could not retrieve properties for portlet '"
474: + portletContext + "'", e);
475: } finally {
476: RegistrationLocal.setRegistration(null);
477: }
478: }
479:
480: private void checkUserAuthorization(UserContext userContext) {
481: //todo: implement
482: if (userContext != null) {
483:
484: }
485: }
486:
487: private Set getKeysFromNames(String[] names) {
488: Set keys = null;
489: if (names != null) {
490: if (names.length == 0) {
491: keys = Collections.EMPTY_SET;
492: } else {
493: // todo fix-me we need to work around http://jira.jboss.com/jira/browse/JBWS-1300 for now:
494: boolean allNamesNull = true;
495: for (int i = 0; i < names.length && allNamesNull; i++) {
496: allNamesNull = (names[i] == null);
497: }
498: if (allNamesNull) {
499: keys = null;
500: } else {
501: keys = Tools.toSet(names);
502: }
503: }
504: }
505: return keys;
506: }
507:
508: private Portlet getPortletFrom(PortletContext portletContext,
509: Registration registration) throws InvalidHandleFault {
510: Portlet portlet;
511: try {
512: RegistrationLocal.setRegistration(registration);
513: portlet = producer
514: .getInvoker()
515: .getPortlet(
516: WSRPUtils
517: .convertToPortalPortletContext(portletContext));
518: return portlet;
519: } catch (PortletInvokerException e) {
520: throw WSRPExceptionFactory.throwSOAPFaultException(
521: WSRPExceptionFactory.INVALID_HANDLE,
522: "Could not retrieve portlet '"
523: + portletContext.getPortletHandle() + "'",
524: e);
525: } finally {
526: RegistrationLocal.setRegistration(null);
527: }
528: }
529: }
|