001: /*
002: * Copyright 2000-2001,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: /*
018:
019: */
020:
021: package org.apache.wsrp4j.consumer.driver;
022:
023: import java.net.URL;
024: import java.util.Hashtable;
025:
026: import oasis.names.tc.wsrp.v1.intf.WSRP_v1_PortletManagement_PortType;
027: import oasis.names.tc.wsrp.v1.intf.WSRP_v1_Registration_PortType;
028: import oasis.names.tc.wsrp.v1.intf.WSRP_v1_ServiceDescription_PortType;
029: import oasis.names.tc.wsrp.v1.types.GetServiceDescription;
030: import oasis.names.tc.wsrp.v1.types.InvalidRegistrationFault;
031: import oasis.names.tc.wsrp.v1.types.ModifyRegistration;
032: import oasis.names.tc.wsrp.v1.types.PortletDescription;
033: import oasis.names.tc.wsrp.v1.types.RegistrationContext;
034: import oasis.names.tc.wsrp.v1.types.RegistrationData;
035: import oasis.names.tc.wsrp.v1.types.RegistrationState;
036: import oasis.names.tc.wsrp.v1.types.ReturnAny;
037: import oasis.names.tc.wsrp.v1.types.ServiceDescription;
038: import oasis.names.tc.wsrp.v1.wsdl.WSRPServiceLocator;
039:
040: import org.apache.wsrp4j.consumer.Producer;
041: import org.apache.wsrp4j.exception.ErrorCodes;
042: import org.apache.wsrp4j.exception.WSRPException;
043: import org.apache.wsrp4j.exception.WSRPXHelper;
044: import org.apache.wsrp4j.log.LogManager;
045: import org.apache.wsrp4j.log.Logger;
046: import org.apache.wsrp4j.util.ParameterChecker;
047: import org.apache.wsrp4j.util.StateChangedServiceImpl;
048:
049: /**
050: * A consumer representation of a WSRP-producer providing WSRP-portlets.
051: * Generally a producer can expose up to four WSRP-Interfaces. These interfaces are
052: * Markup-, Service Description-,Registration- and WSRPPortlet Management Interface. Whereas
053: * the Registration- and Portlet Management Interface are optional.
054: *
055: * @see Producer
056: * @author Stephan Laertz
057: * @author Richard Jacob
058: **/
059: public class ProducerImpl extends StateChangedServiceImpl implements
060: Producer {
061:
062: // ID and misc. infos
063: private String name = null;
064:
065: private String producerID = null;
066:
067: private String description = null;
068:
069: // URL's of the WSRP interfaces
070: private String registrationURL;
071:
072: private String serviceDescriptionURL;
073:
074: private String markupURL;
075:
076: private String portletManagementURL;
077:
078: // Registration
079: private boolean registrationRequired = false;
080:
081: private RegistrationContext registrationContext = null;
082:
083: private RegistrationData consumerRegData = null;
084:
085: // Service and portlet description
086: private ServiceDescription serviceDescription = null;
087:
088: private Hashtable portletDesc = null;
089:
090: // Stubs
091: private WSRP_v1_ServiceDescription_PortType serviceDescriptionInterface = null;
092:
093: private WSRP_v1_Registration_PortType registrationInterface = null;
094:
095: private WSRP_v1_PortletManagement_PortType portletManagementInterface = null;
096:
097: // Logger and parameter checker
098: private Logger logger = null;
099:
100: private ParameterChecker checker = null;
101:
102: /**
103: * Default Constructor should not be used directly. But is
104: * required for persistence support by castor.
105: **/
106: public ProducerImpl() {
107: this .portletDesc = new Hashtable();
108: logger = LogManager.getLogManager().getLogger(getClass());
109: checker = new ParameterChecker();
110:
111: }
112:
113: /**
114: * This constructor can be used to create a new producer object
115: **/
116: public ProducerImpl(String producerID, String markupURL,
117: String serviceDescriptionURL) throws WSRPException {
118:
119: this ();
120: this .producerID = producerID;
121:
122: if (markupURL != null) {
123: this .markupURL = markupURL;
124: } else {
125: WSRPXHelper.throwX(logger, Logger.ERROR, "init",
126: ErrorCodes.MISSING_MARKUP_PORT);
127: }
128:
129: if (serviceDescriptionURL != null) {
130:
131: this .serviceDescriptionURL = serviceDescriptionURL;
132: initServiceDescInterface(serviceDescriptionURL);
133:
134: } else {
135: WSRPXHelper.throwX(logger, Logger.ERROR, "init",
136: ErrorCodes.MISSING_SERVCICE_DESC_PORT);
137: }
138:
139: }
140:
141: /**
142: * This constructor can be used to create a new producer object
143: **/
144: public ProducerImpl(String producerID, String markupURL,
145: String serviceDescriptionURL, String registrationURL,
146: String portletManagementURL,
147: RegistrationData registrationData) throws WSRPException {
148:
149: this (producerID, markupURL, serviceDescriptionURL);
150:
151: if (registrationURL != null) {
152:
153: initRegistrationInterface(registrationURL);
154: this .registrationURL = registrationURL;
155: this .consumerRegData = registrationData;
156: }
157:
158: if (portletManagementURL != null) {
159: this .portletManagementURL = portletManagementURL;
160: initPortletManagementInterface(portletManagementURL);
161: }
162: }
163:
164: /**
165: * Initialize the service description interface of the producer.
166: *
167: * @param serviceDescriptionURL The URL of the producers service description interface
168: **/
169: public void initServiceDescInterface(String serviceDescriptionURL)
170: throws WSRPException {
171:
172: // just in case this has not been done before and for castor persistence
173: this .serviceDescriptionURL = serviceDescriptionURL;
174:
175: try {
176: WSRPServiceLocator serviceLocator = new WSRPServiceLocator();
177: serviceDescriptionInterface = serviceLocator
178: .getWSRPServiceDescriptionService(new URL(
179: serviceDescriptionURL));
180:
181: } catch (javax.xml.rpc.ServiceException xmlEx) {
182:
183: WSRPXHelper.throwX(logger, Logger.ERROR,
184: "initServiceDescInterface",
185: ErrorCodes.INIT_OF_SERVICE_DESC_PORT_FAILED, xmlEx);
186:
187: } catch (java.net.MalformedURLException urlEx) {
188:
189: WSRPXHelper.throwX(logger, Logger.ERROR,
190: "initServiceDescInterface",
191: ErrorCodes.INVALID_URL_OF_SERVICE_DESC_PORT, urlEx);
192:
193: }
194: }
195:
196: /**
197: * Initialize the registration interface of the producer.
198: *
199: * @param registrationURL The URL of the producers registration interface
200: **/
201: public void initRegistrationInterface(String registrationURL)
202: throws WSRPException {
203:
204: // just in case this has not been done before and for castor persistence
205: this .registrationURL = registrationURL;
206:
207: try {
208: WSRPServiceLocator serviceLocator = new WSRPServiceLocator();
209: registrationInterface = serviceLocator
210: .getWSRPRegistrationService(new URL(registrationURL));
211:
212: } catch (javax.xml.rpc.ServiceException xmlEx) {
213:
214: WSRPXHelper.throwX(logger, Logger.ERROR,
215: "initRegistrationInterface",
216: ErrorCodes.INIT_OF_REGISTRATION_PORT_FAILED, xmlEx);
217:
218: } catch (java.net.MalformedURLException urlEx) {
219:
220: WSRPXHelper.throwX(logger, Logger.ERROR,
221: "initRegistrationInterface",
222: ErrorCodes.INVALID_URL_OF_REGISTRATION_PORT, urlEx);
223:
224: }
225: }
226:
227: /**
228: * Get the URL of the producers service description interface.
229: *
230: * @return URL of the service description interface.
231: **/
232: public String getServiceDescriptionInterfaceEndpoint() {
233: return this .serviceDescriptionURL;
234: }
235:
236: /**
237: * Set the URL of the producers service description interface.
238: *
239: * @param url URL of the service description interface.
240: **/
241: public void setServiceDescriptionInterfaceEndpoint(String url) {
242: serviceDescriptionURL = url;
243: stateChanged();
244: }
245:
246: /**
247: * Get the URL of the producers registration interface.
248: *
249: * @return URL of the registration interface.
250: **/
251: public String getRegistrationInterfaceEndpoint() {
252: return registrationURL;
253: }
254:
255: /**
256: * Set the URL of the producers registration interface.
257: *
258: * @param url URL of the registration interface.
259: **/
260: public void setRegistrationInterfaceEndpoint(String url) {
261: registrationURL = url;
262: stateChanged();
263: }
264:
265: /**
266: * Get the ID of the producer.
267: *
268: * @return The ID of the producer
269: **/
270: public String getID() {
271: return producerID;
272: }
273:
274: /**
275: * Set the ID of the producer to he given value.
276: *
277: * @param id ID of the producer.
278: **/
279: public void setID(String id) {
280: producerID = id;
281: stateChanged();
282: }
283:
284: /**
285: * Get the name of the producer.
286: *
287: * @return The name of the producer
288: **/
289: public String getName() {
290: return name;
291: }
292:
293: /**
294: * Set the name of the producer.
295: *
296: * @param name The name of the producer
297: **/
298: public void setName(String name) {
299: this .name = name;
300: stateChanged();
301: }
302:
303: /**
304: * Get a description of the producer.
305: *
306: * @return A description of the producer
307: **/
308: public String getDescription() {
309: return this .description;
310: }
311:
312: /**
313: * Set a description of the producer.
314: *
315: * @param description Some descriptive information about the producer
316: **/
317: public void setDescription(String description) {
318: this .description = description;
319: stateChanged();
320: }
321:
322: /**
323: * Indicates wether or not the producer requires consumer registration.
324: *
325: * @return True if consumer registration is required.
326: **/
327: public boolean isRegistrationRequired() {
328: return this .registrationRequired;
329: }
330:
331: /**
332: * Define if the producer requires in-band registration or not.
333: *
334: * @param registrationRequired True if the producer requires in-band registration
335: **/
336: public void setIsRegistrationRequired(boolean registrationRequired) {
337: this .registrationRequired = registrationRequired;
338: stateChanged();
339: }
340:
341: /**
342: * Get the registration data the consumer uses to register at this producer.
343: *
344: * @return The consumer registration data
345: **/
346: public RegistrationData getRegistrationData() {
347: return consumerRegData;
348: }
349:
350: /**
351: * Set the registration the consumer uses the register at this producer.
352: *
353: * @param regData The registration data which is used to register at this producer
354: **/
355: public void setRegistrationData(RegistrationData regData) {
356: consumerRegData = regData;
357: stateChanged();
358: }
359:
360: /**
361: * Get the current registration context of the consumer registered at this producer or null
362: * if no registration is required or happend so far.
363: *
364: * @return The current registration context of the consumer at this producer or null.
365: **/
366: public RegistrationContext getRegistrationContext() {
367: return this .registrationContext;
368: }
369:
370: /**
371: * Set the registration context.
372: *
373: * @param registrationContext The registration context of a consumer registered at the producer.
374: **/
375: public void setRegistrationContext(
376: RegistrationContext registrationContext) {
377: if (registrationContext != null) {
378: this .registrationContext = registrationContext;
379: stateChanged();
380: }
381: }
382:
383: /**
384: * Same as getServiceDescription(false)
385: **/
386: public ServiceDescription getServiceDescription()
387: throws WSRPException {
388: return getServiceDescription(false);
389: }
390:
391: /**
392: * Get the service description of the producer
393: *
394: * @param newRequest If set to true a new request is send to the producer otherwise a cached service description
395: * is used if available
396: *
397: * @return Service description of the producer
398: **/
399: public ServiceDescription getServiceDescription(boolean newRequest)
400: throws WSRPException {
401: if (this .serviceDescription == null || newRequest) {
402: GetServiceDescription request = new GetServiceDescription();
403:
404: if (registrationContext != null) {
405: request.setRegistrationContext(registrationContext);
406: }
407:
408: // TODO: Set desired locales which are supported by the consumer
409: //request.setDesiredLocales(new String[]{Constants.LOCALE_EN_US, Constants.LOCALE_DE_DE});
410: // for now request all locales
411: request.setDesiredLocales(null);
412:
413: ServiceDescription response = null;
414: try {
415:
416: response = serviceDescriptionInterface
417: .getServiceDescription(request);
418:
419: if (response != null) {
420:
421: try {
422:
423: checker.check(response);
424:
425: } catch (java.rmi.RemoteException wsrpFault) {
426:
427: WSRPXHelper.handleWSRPFault(logger, wsrpFault);
428:
429: }
430:
431: if (registrationContext == null
432: && response.isRequiresRegistration()) {
433: register(consumerRegData);
434: getServiceDescription(true);
435:
436: } else {
437: setServiceDescription(response);
438: }
439:
440: } else {
441:
442: WSRPXHelper.throwX(logger, Logger.ERROR,
443: "getServiceDescription",
444: ErrorCodes.INVALID_SERVICE_DESCRIPTION);
445: }
446:
447: } catch (InvalidRegistrationFault invalidReg) {
448:
449: // producer did not accept the registration
450: // lets try it again
451: register(consumerRegData);
452: getServiceDescription(true);
453:
454: } catch (java.rmi.RemoteException wsrpFault) {
455:
456: WSRPXHelper.handleWSRPFault(logger, wsrpFault);
457:
458: }
459: }
460:
461: return this .serviceDescription;
462: }
463:
464: /**
465: * Get the portlet description of the portlet with the given handle from the
466: * service description or null if the producer doesn't offer an portlet with this handle
467: * in it's service description.
468: *
469: * @param portletHandle The portlet handle of the portlet
470: *
471: * @return The portlet description of the portlet with the given handle
472: **/
473: public PortletDescription getPortletDescription(String portletHandle)
474: throws WSRPException {
475:
476: PortletDescription desc = null;
477: if (portletHandle != null) {
478:
479: if (serviceDescription == null) {
480:
481: // fetch a new portlet description from the producer
482: getServiceDescription();
483: }
484:
485: desc = (PortletDescription) portletDesc.get(portletHandle);
486:
487: if (desc == null) {
488:
489: WSRPXHelper.throwX(logger, Logger.ERROR,
490: "getPortletDescription",
491: ErrorCodes.INVALID_PORTLET_HANDLE);
492: }
493: }
494:
495: return desc;
496: }
497:
498: /**
499: * Set the consumer environment this producer is used.
500: *
501: * @param consumerEnvironment The consumer environment of the consumer using
502: * the producer object.
503: **/
504: public void setServiceDescription(
505: ServiceDescription serviceDescription) {
506: if (serviceDescription != null) {
507: this .serviceDescription = serviceDescription;
508: updatePortletDescriptions(serviceDescription);
509: setIsRegistrationRequired(serviceDescription
510: .isRequiresRegistration());
511: }
512: }
513:
514: /**
515: * Add an portlet description to the producer. This portlet description is
516: * accessable through the portlet handle in the portlet description. If the
517: * producer has already an portlet description with this portlet handle than
518: * the old description will be overwritten.
519: *
520: * @param portletDescription New portlet description
521: **/
522: public void addPortletDescription(
523: PortletDescription portletDescription) {
524: if (portletDescription != null) {
525: this .portletDesc.put(portletDescription.getPortletHandle(),
526: portletDescription);
527: }
528: }
529:
530: private void updatePortletDescriptions(
531: ServiceDescription serviceDescription) {
532: if (serviceDescription != null) {
533: PortletDescription[] offeredPortlets = serviceDescription
534: .getOfferedPortlets();
535: if (offeredPortlets != null) {
536: this .portletDesc.clear();
537:
538: for (int i = 0; i < offeredPortlets.length; i++) {
539: if (offeredPortlets[i] != null) {
540: addPortletDescription(offeredPortlets[i]);
541: }
542:
543: }
544: }
545: }
546: }
547:
548: /**
549: * Method establishes a relationship between consumer and producer.
550: *
551: * Note: A additional call of setRegistrationContext() is not neccesary
552: *
553: * @param registrationData Data which is used to register the consumer
554: *
555: * @return The registration context received by the producer
556: **/
557: public RegistrationContext register(
558: RegistrationData registrationData) throws WSRPException {
559:
560: if (registrationData != null
561: && this .registrationInterface != null) {
562:
563: try {
564:
565: RegistrationContext regContext = registrationInterface
566: .register(registrationData);
567: checker.check(regContext, false);
568: setRegistrationContext(regContext);
569:
570: } catch (java.rmi.RemoteException wsrpFault) {
571:
572: WSRPXHelper.handleWSRPFault(logger, wsrpFault);
573:
574: }
575:
576: } else {
577:
578: // TODO: Either no registration data or producer does not support in-band registration
579: }
580:
581: return this .registrationContext;
582: }
583:
584: /**
585: * Can be used to modify the relationship between consumer and producer.
586: *
587: * Note: A additional call of setRegistrationContext() is not neccesary
588: *
589: * @param registrationData The new registration data
590: *
591: * @return New registration context
592: **/
593: public RegistrationState modifyRegistration(
594: RegistrationData registrationData) throws WSRPException {
595:
596: RegistrationState newState = null;
597:
598: try {
599: if (registrationData != null
600: && this .registrationInterface != null) {
601:
602: ModifyRegistration request = new ModifyRegistration();
603: if (registrationContext != null) {
604: request.setRegistrationContext(registrationContext);
605: }
606: request.setRegistrationData(registrationData);
607:
608: newState = registrationInterface
609: .modifyRegistration(request);
610:
611: getRegistrationContext().setRegistrationState(
612: newState.getRegistrationState());
613: stateChanged();
614:
615: } else {
616:
617: // TODO: Either no data or producer does not support in-band registration
618: }
619: } catch (java.rmi.RemoteException wsrpFault) {
620:
621: WSRPXHelper.handleWSRPFault(logger, wsrpFault);
622:
623: }
624:
625: return newState;
626: }
627:
628: /**
629: * End an existing consumer producer relationship and remove the registration context
630: *
631: * @return Can be anything
632: **/
633: public ReturnAny deregister() throws WSRPException {
634: ReturnAny any = null;
635:
636: try {
637: if (registrationContext != null
638: && this .registrationInterface != null) {
639:
640: any = registrationInterface
641: .deregister(this .registrationContext);
642: registrationContext = null;
643: registrationRequired = false;
644:
645: stateChanged();
646:
647: } else {
648: // TODO: Either we aren't registered at the producer or
649: // the producer does not support in-band registration
650: }
651:
652: } catch (java.rmi.RemoteException wsrpFault) {
653:
654: WSRPXHelper.handleWSRPFault(logger, wsrpFault);
655: }
656:
657: return any;
658: }
659:
660: /**
661: * @see org.apache.wsrp4j.consumer.Producer#getMarkupInterfaceEndpoint()
662: */
663: public String getMarkupInterfaceEndpoint() {
664: return markupURL;
665: }
666:
667: /**
668: * @see org.apache.wsrp4j.consumer.Producer#setMarkupInterfaceEndpoint(java.lang.String)
669: */
670: public void setMarkupInterfaceEndpoint(String url) {
671: markupURL = url;
672: stateChanged();
673: }
674:
675: /**
676: * @see org.apache.wsrp4j.consumer.Producer#getPortletManagementInterfaceEndpoint()
677: */
678: public String getPortletManagementInterfaceEndpoint() {
679: return portletManagementURL;
680: }
681:
682: /**
683: * @see org.apache.wsrp4j.consumer.Producer#setPortletManagementInterfaceEndpoint(java.lang.String)
684: */
685: public void setPortletManagementInterfaceEndpoint(String url) {
686: portletManagementURL = url;
687: stateChanged();
688: }
689:
690: public void initPortletManagementInterface(
691: String portletManagementURL) throws WSRPException {
692: final String MN = "initPortletManagementInterface";
693:
694: // just in case this has not been done before and for castor persistence
695: this .portletManagementURL = portletManagementURL;
696:
697: try {
698: WSRPServiceLocator serviceLocator = new WSRPServiceLocator();
699: portletManagementInterface = serviceLocator
700: .getWSRPPortletManagementService(new URL(
701: portletManagementURL));
702: } catch (javax.xml.rpc.ServiceException xmlEx) {
703:
704: WSRPXHelper.throwX(logger, Logger.ERROR, MN,
705: ErrorCodes.INIT_OF_PORTLET_MGMT_PORT_FAILED, xmlEx);
706:
707: } catch (java.net.MalformedURLException urlEx) {
708:
709: WSRPXHelper.throwX(logger, Logger.ERROR, MN,
710: ErrorCodes.INVALID_URL_OF_PORTLET_MGMT_PORT, urlEx);
711:
712: }
713: }
714:
715: public WSRP_v1_PortletManagement_PortType getPortletManagementInterface() {
716: return portletManagementInterface;
717: }
718:
719: public WSRP_v1_Registration_PortType getRegistrationInterface() {
720: return registrationInterface;
721: }
722:
723: public WSRP_v1_ServiceDescription_PortType getServiceDescriptionInterface() {
724: return serviceDescriptionInterface;
725: }
726:
727: public boolean isPortletManagementInferfaceSupported() {
728: if (portletManagementURL != null) {
729: return true;
730: }
731: return false;
732: }
733:
734: public boolean isRegistrationInterfaceSupported() {
735: if (registrationURL != null) {
736: return true;
737: }
738: return false;
739: }
740:
741: }
|