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.util.ParameterValidation;
025: import org.jboss.portal.portlet.Portlet;
026: import org.jboss.portal.portlet.PortletInvokerException;
027: import org.jboss.portal.portlet.info.CapabilitiesInfo;
028: import org.jboss.portal.portlet.info.MetaInfo;
029: import org.jboss.portal.portlet.info.ModeInfo;
030: import org.jboss.portal.portlet.info.PortletInfo;
031: import org.jboss.portal.portlet.info.WindowStateInfo;
032: import org.jboss.portal.registration.Registration;
033: import org.jboss.portal.wsrp.WSRPExceptionFactory;
034: import org.jboss.portal.wsrp.WSRPTypeFactory;
035: import org.jboss.portal.wsrp.WSRPUtils;
036: import org.jboss.portal.wsrp.core.CookieProtocol;
037: import org.jboss.portal.wsrp.core.GetServiceDescription;
038: import org.jboss.portal.wsrp.core.InvalidHandleFault;
039: import org.jboss.portal.wsrp.core.InvalidRegistrationFault;
040: import org.jboss.portal.wsrp.core.MarkupType;
041: import org.jboss.portal.wsrp.core.ModelDescription;
042: import org.jboss.portal.wsrp.core.OperationFailedFault;
043: import org.jboss.portal.wsrp.core.PortletContext;
044: import org.jboss.portal.wsrp.core.PortletDescription;
045: import org.jboss.portal.wsrp.core.ServiceDescription;
046: import org.jboss.portal.wsrp.core.WSRP_v1_ServiceDescription_PortType;
047: import org.jboss.portal.wsrp.producer.config.ProducerRegistrationRequirements;
048:
049: import java.rmi.RemoteException;
050: import java.util.Collection;
051: import java.util.Collections;
052: import java.util.HashSet;
053: import java.util.Iterator;
054: import java.util.Locale;
055: import java.util.Map;
056: import java.util.Set;
057:
058: /**
059: * @author <a href="mailto:chris.laprun@jboss.com">Chris Laprun</a>
060: * @version $Revision: 9360 $
061: * @since 2.4
062: */
063: class ServiceDescriptionHandler extends ServiceHandler implements
064: WSRP_v1_ServiceDescription_PortType {
065: // JBPORTAL-1220: force call to initCookie... Required so that BEA version < 9.2 will behave properly as a Consumer
066: private final CookieProtocol BEA_8_CONSUMER_FIX = CookieProtocol.perUser;
067:
068: ServiceDescriptionHandler(WSRPProducerImpl producer) {
069: super (producer);
070: }
071:
072: public ServiceDescription getServiceDescription(
073: GetServiceDescription gs) throws InvalidRegistrationFault,
074: OperationFailedFault, RemoteException {
075: WSRPExceptionFactory.throwOperationFailedFaultIfValueIsMissing(
076: gs, "GetServiceDescription");
077:
078: Registration registration = producer.getRegistrationFrom(gs
079: .getRegistrationContext());
080: boolean registrationValid = producer
081: .isRegistrationValid(registration);
082:
083: ProducerRegistrationRequirements requirements = producer
084: .getProducerRegistrationRequirements();
085:
086: PortletDescription[] offeredPortlets = null;
087: ServiceDescription serviceDescription = WSRPTypeFactory
088: .createServiceDescription(requirements
089: .isRegistrationRequired());
090: serviceDescription.setRequiresInitCookie(BEA_8_CONSUMER_FIX);
091: serviceDescription.setLocales(producer.getSupportedLocales());
092:
093: if (!requirements.isRegistrationRequired()) {
094: offeredPortlets = getPortletDescriptions(gs
095: .getDesiredLocales(), null);
096: } else {
097: if (!registrationValid) {
098: log
099: .debug("Unregistered consumer while registration is required. Sending registration information.");
100:
101: if (requirements
102: .isRegistrationRequiredForFullDescription()) {
103: log
104: .debug("Sending offered portlets description despite not being registered, per Producer configuration.");
105: offeredPortlets = getPortletDescriptions(gs
106: .getDesiredLocales(), null);
107: }
108:
109: // do not create a ModelDescription if there is no registration properties
110: Map info = requirements.getRegistrationProperties();
111: ModelDescription description = null;
112: if (info != null && !info.isEmpty()) {
113: description = WSRPUtils
114: .convertRegistrationPropertiesToModelDescription(info);
115: }
116:
117: serviceDescription
118: .setRegistrationPropertyDescription(description);
119: } else {
120: log.debug("Sending registered service description.");
121: // should we be sending the registration properties description as well?
122: offeredPortlets = getPortletDescriptions(gs
123: .getDesiredLocales(), registration);
124: }
125: }
126:
127: serviceDescription.setOfferedPortlets(offeredPortlets);
128: return serviceDescription;
129: }
130:
131: public Set<PortletDescription> getOfferedPortletDescriptions(
132: String[] desiredLocales) {
133: Set<Portlet> portlets;
134: try {
135: portlets = producer.getRemotablePortlets();
136: } catch (PortletInvokerException e) {
137: log.warn("Could not retrieve portlets. Reason:\n\t"
138: + e.getLocalizedMessage());
139: return Collections.emptySet();
140: }
141:
142: Set<PortletDescription> offeredPortletDescriptions = new HashSet<PortletDescription>(
143: portlets.size());
144:
145: for (Portlet portlet : portlets) {
146: PortletDescription desc = getPortletDescription(portlet,
147: desiredLocales);
148: offeredPortletDescriptions.add(desc);
149: }
150:
151: return offeredPortletDescriptions;
152: }
153:
154: public PortletDescription getPortletDescription(
155: PortletContext portletContext, String[] desiredLocales,
156: Registration registration) throws InvalidHandleFault,
157: OperationFailedFault {
158: ParameterValidation.throwIllegalArgExceptionIfNull(
159: portletContext, "portlet context");
160: Portlet portlet;
161: try {
162: portlet = producer.getPortletWith(WSRPUtils
163: .convertToPortalPortletContext(portletContext),
164: registration);
165: return getPortletDescription(portlet, desiredLocales);
166: } catch (PortletInvokerException e) {
167: throw WSRPExceptionFactory.throwSOAPFaultException(
168: WSRPExceptionFactory.OPERATION_FAILED,
169: "Could not retrieve portlet '" + portletContext
170: + "'", e);
171: }
172: }
173:
174: /**
175: * @param desiredLocales
176: * @param registration here so that we can do filtering of portlets based on registration data (not currently
177: * implemented)
178: * @return
179: */
180: private PortletDescription[] getPortletDescriptions(
181: String[] desiredLocales, Registration registration) {
182: Set<PortletDescription> descriptions = getOfferedPortletDescriptions(desiredLocales);
183: return descriptions.toArray(new PortletDescription[descriptions
184: .size()]);
185: }
186:
187: /**
188: * Creates a PortletDescription based on the user desired locales (ordered according to user preferences) for the
189: * specified component.
190: *
191: * @param portlet
192: * @param desiredLocales the user desired locales (ordered according to user preferences) to use for the description
193: * @return a PortletDescription describing the specified portlet
194: */
195: PortletDescription getPortletDescription(Portlet portlet,
196: String[] desiredLocales) {
197: String id = portlet.getContext().getId();
198: PortletInfo info = portlet.getInfo();
199: log.debug("Constructing portlet description for: " + id);
200:
201: CapabilitiesInfo capInfo = info.getCapabilities();
202: Collection allMimeTypes = capInfo.getMimeTypes();
203: MarkupType[] markupTypes = new MarkupType[allMimeTypes.size()];
204: Iterator mimeTypes = allMimeTypes.iterator();
205: for (int i = 0; mimeTypes.hasNext(); i++) {
206: String mimeType = (String) mimeTypes.next();
207: markupTypes[i] = new MarkupType(mimeType,
208: getModeNamesFrom(capInfo.getModes(mimeType)),
209: getWindowStateNamesFrom(capInfo
210: .getWindowStates(mimeType)),
211: getLocaleNamesFrom(capInfo.getLocales(mimeType)),
212: null);
213: }
214:
215: //todo generate a valid and better portlet handle
216: PortletDescription desc = WSRPTypeFactory
217: .createPortletDescription(id, markupTypes);
218:
219: // todo: group ID
220:
221: MetaInfo metaInfo = info.getMeta();
222:
223: // description
224: desc.setDescription(WSRPUtils.convertToWSRPLocalizedString(
225: metaInfo.getMetaValue(MetaInfo.DESCRIPTION),
226: desiredLocales));
227:
228: // short title
229: desc.setShortTitle(WSRPUtils.convertToWSRPLocalizedString(
230: metaInfo.getMetaValue(MetaInfo.SHORT_TITLE),
231: desiredLocales));
232:
233: // title
234: desc.setTitle(WSRPUtils.convertToWSRPLocalizedString(metaInfo
235: .getMetaValue(MetaInfo.TITLE), desiredLocales));
236:
237: // display name
238: desc.setDisplayName(WSRPUtils.convertToWSRPLocalizedString(
239: metaInfo.getMetaValue(MetaInfo.DISPLAY_NAME),
240: desiredLocales));
241:
242: // keywords
243: // metaInfo contains comma-separated keywords: we need to extract them into an array
244: org.jboss.portal.wsrp.core.LocalizedString concatenatedKeywords = WSRPUtils
245: .convertToWSRPLocalizedString(metaInfo
246: .getMetaValue(MetaInfo.KEYWORDS),
247: desiredLocales);
248: if (concatenatedKeywords != null) {
249: String commaSeparatedKeywords = concatenatedKeywords
250: .getValue();
251: if (commaSeparatedKeywords != null
252: && commaSeparatedKeywords.length() > 0) {
253: String lang = concatenatedKeywords.getLang();
254: String[] keywordArray = commaSeparatedKeywords
255: .split(",");
256: org.jboss.portal.wsrp.core.LocalizedString[] keywords = new org.jboss.portal.wsrp.core.LocalizedString[keywordArray.length];
257: for (int i = 0; i < keywordArray.length; i++) {
258: keywords[i] = WSRPTypeFactory
259: .createLocalizedString(lang, null,
260: keywordArray[i].trim()); // fix-me: resource name
261: }
262: desc.setKeywords(keywords);
263: }
264: }
265:
266: /* todo:
267: * [O] string userCategories[]
268: * [O] string userProfileItems[]
269: * [O] boolean usesMethodGet
270: * [O] boolean defaultMarkupSecure
271: * [O] boolean onlySecure
272: * [O] boolean userContextStoredInSession
273: * [O] boolean templatesStoredInSession
274: * [O] boolean hasUserSpecificState
275: * [O] boolean doesUrlTemplateProcessing
276: * [O] Extension extensions
277: */
278: return desc;
279: }
280:
281: private String[] getLocaleNamesFrom(Collection locales) {
282: if (locales == null || locales.isEmpty()) {
283: return null;
284: }
285:
286: String[] localeNames = new String[locales.size()];
287: int i = 0;
288: for (Object locale : locales) {
289: localeNames[i++] = WSRPUtils.toString((Locale) locale);
290: }
291: return localeNames;
292: }
293:
294: private String[] getWindowStateNamesFrom(Collection windowStates) {
295: String[] result = new String[windowStates.size()];
296: int i = 0;
297: for (Iterator windowsStatesIt = windowStates.iterator(); windowsStatesIt
298: .hasNext(); i++) {
299: WindowStateInfo windowStateInfo = (WindowStateInfo) windowsStatesIt
300: .next();
301: result[i] = WSRPUtils
302: .convertJSR168WindowStateNameToWSRPName(windowStateInfo
303: .getWindowStateName());
304: }
305:
306: return result;
307: }
308:
309: private String[] getModeNamesFrom(Collection modes) {
310: String[] result = new String[modes.size()];
311: int i = 0;
312: for (Iterator modesIt = modes.iterator(); modesIt.hasNext(); i++) {
313: ModeInfo modeInfo = (ModeInfo) modesIt.next();
314: result[i] = WSRPUtils
315: .convertJSR168PortletModeNameToWSRPName(modeInfo
316: .getModeName());
317: }
318:
319: return result;
320: }
321: }
|