001: /******************************************************************************
002: * JBoss, a division of Red Hat *
003: * Copyright 2007, 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.consumer;
023:
024: import org.jboss.logging.Logger;
025: import org.jboss.portal.common.util.ParameterValidation;
026: import org.jboss.portal.portlet.InvokerUnavailableException;
027: import org.jboss.portal.wsrp.core.WSRP_v1_Markup_PortType;
028: import org.jboss.portal.wsrp.core.WSRP_v1_PortletManagement_PortType;
029: import org.jboss.portal.wsrp.core.WSRP_v1_Registration_PortType;
030: import org.jboss.portal.wsrp.core.WSRP_v1_ServiceDescription_PortType;
031: import org.jboss.portal.wsrp.services.PerEndpointSOAPInvokerServiceFactory;
032: import org.jboss.portal.wsrp.services.RemoteSOAPInvokerServiceFactory;
033: import org.jboss.portal.wsrp.services.ServiceFactory;
034:
035: import java.util.BitSet;
036:
037: /**
038: * @author <a href="mailto:chris.laprun@jboss.com">Chris Laprun</a>
039: * @version $Revision: 9135 $
040: * @since 2.6
041: */
042: public class EndpointConfigurationInfo {
043: private final static Logger log = Logger
044: .getLogger(EndpointConfigurationInfo.class);
045:
046: /** DB primary key */
047: private Long key;
048:
049: private String persistentServiceDescriptionURL = UNSET;
050: private String persistentMarkupURL = UNSET;
051: private String persistentRegistrationURL;
052: private String persistentPortletManagementURL;
053: private String persistentWsdlDefinitionURL = UNSET;
054:
055: // transient variables
056: /** Access to the WS */
057: private ServiceFactory serviceFactory;
058:
059: static final String SERVICE_DESCRIPTION = "service description";
060: static final String MARKUP = "markup";
061: static final String PORTLET_MANAGEMENT = "portlet management";
062: static final String REGISTRATION = "registration";
063:
064: // Used to ensure that even invalid values can be persisted to DB so that it can be accessed from the GUI
065: public final static String UNSET = "MUST BE SET";
066:
067: // maintain the dirty status of each URL
068: private BitSet clean = new BitSet();
069: private final static int SD = 0;
070: private final static int M = 1;
071: private final static int PM = 2;
072: private final static int R = 3;
073:
074: /** Whether we're using information from a WSDL or not. */
075: private boolean usingWSDL = true;
076: private boolean isModifiedWSDL;
077:
078: // todo: public for tests
079: public EndpointConfigurationInfo() {
080: }
081:
082: public EndpointConfigurationInfo(ProducerInfo producerInfo) {
083: ParameterValidation.throwIllegalArgExceptionIfNull(
084: producerInfo, "ProducerInfo");
085: producerInfo.setEndpointConfigurationInfo(this );
086: }
087:
088: public EndpointConfigurationInfo(ProducerInfo producerInfo,
089: ServiceFactory serviceFactory) {
090: this (producerInfo);
091: setServiceFactory(serviceFactory);
092: }
093:
094: public Long getKey() {
095: return key;
096: }
097:
098: public void setKey(Long key) {
099: this .key = key;
100: }
101:
102: public boolean usesWSDL() {
103: return (isWSDLNotNullAndSet() && !isModifiedWSDL) || usingWSDL;
104: }
105:
106: public void setUsesWSDL(boolean useWSDL) {
107: usingWSDL = useWSDL;
108: }
109:
110: public String getWsdlDefinitionURL() {
111: if (serviceFactory instanceof RemoteSOAPInvokerServiceFactory) {
112: persistentWsdlDefinitionURL = ((RemoteSOAPInvokerServiceFactory) serviceFactory)
113: .getWsdlDefinitionURL();
114: }
115:
116: return persistentWsdlDefinitionURL;
117: }
118:
119: public String getServiceDescriptionURL() {
120: if (serviceFactory != null) {
121: persistentServiceDescriptionURL = serviceFactory
122: .getServiceDescriptionURL();
123: }
124: return persistentServiceDescriptionURL;
125: }
126:
127: public String getMarkupURL() {
128: if (serviceFactory != null) {
129: persistentMarkupURL = serviceFactory.getMarkupURL();
130: }
131: return persistentMarkupURL;
132: }
133:
134: public String getPortletManagementURL() {
135: if (serviceFactory != null) {
136: persistentPortletManagementURL = serviceFactory
137: .getPortletManagementURL();
138: }
139: return persistentPortletManagementURL;
140: }
141:
142: public String getRegistrationURL() {
143: if (serviceFactory != null) {
144: persistentRegistrationURL = serviceFactory
145: .getRegistrationURL();
146: }
147: return persistentRegistrationURL;
148: }
149:
150: public void setServiceDescriptionURL(String serviceDescriptionURL) {
151: if (serviceFactory != null) {
152: serviceFactory
153: .setServiceDescriptionURL(serviceDescriptionURL);
154: }
155: this .persistentServiceDescriptionURL = modifyIfNeeded(
156: this .persistentServiceDescriptionURL,
157: serviceDescriptionURL, SD);
158:
159: }
160:
161: public void setMarkupURL(String markupURL) {
162: if (serviceFactory != null) {
163: serviceFactory.setMarkupURL(markupURL);
164: }
165: this .persistentMarkupURL = modifyIfNeeded(
166: this .persistentMarkupURL, markupURL, M);
167: }
168:
169: public void setRegistrationURL(String registrationURL) {
170: if (serviceFactory != null) {
171: serviceFactory.setRegistrationURL(registrationURL);
172: }
173: this .persistentRegistrationURL = modifyIfNeeded(
174: this .persistentRegistrationURL, registrationURL, R);
175: }
176:
177: public void setPortletManagementURL(String portletManagementURL) {
178: if (serviceFactory != null) {
179: serviceFactory
180: .setPortletManagementURL(portletManagementURL);
181: }
182: this .persistentPortletManagementURL = modifyIfNeeded(
183: this .persistentPortletManagementURL,
184: portletManagementURL, PM);
185: }
186:
187: public void setWsdlDefinitionURL(String wsdlDefinitionURL)
188: throws RuntimeException {
189: this .persistentWsdlDefinitionURL = wsdlDefinitionURL;
190:
191: // WSDL url is optional so can be null (and in particular, it is when loaded from Hibernate most of the time)
192: // do not attempt to set the URL if the service factory hasn't been created yet to avoid issues when
193: // ConsumerRegistry starts (in particular, raising an exception if the WSDL is not available)
194: if (isWSDLNotNullAndSet()) {
195: usingWSDL = true;
196:
197: if (serviceFactory != null) {
198: if (!(serviceFactory instanceof RemoteSOAPInvokerServiceFactory)) {
199: serviceFactory = new RemoteSOAPInvokerServiceFactory();
200: }
201: internalSetWsdlURL();
202: }
203: } else {
204: usingWSDL = false;
205: }
206: }
207:
208: private boolean isWSDLNotNullAndSet() {
209: return persistentWsdlDefinitionURL != null
210: && !UNSET.equals(persistentWsdlDefinitionURL);
211: }
212:
213: private String modifyIfNeeded(String oldValue, String newValue,
214: int whichURL) {
215: if ((oldValue != null && !oldValue.equals(newValue))
216: || (oldValue == null && newValue != null)) {
217: if (usesWSDL()) {
218: if (serviceFactory instanceof RemoteSOAPInvokerServiceFactory) {
219: isModifiedWSDL = true;
220: }
221:
222: usingWSDL = false;
223: }
224:
225: oldValue = newValue;
226: clean.clear(whichURL);
227: }
228:
229: return oldValue;
230: }
231:
232: private void initServiceFactoryIfNeeded() throws RuntimeException {
233: if (serviceFactory == null) {
234: if (usesWSDL()) {
235: serviceFactory = new RemoteSOAPInvokerServiceFactory();
236: internalSetWsdlURL();
237: } else {
238: if (!UNSET.equals(persistentServiceDescriptionURL)
239: && !UNSET.equals(persistentMarkupURL)) {
240: serviceFactory = new PerEndpointSOAPInvokerServiceFactory();
241: serviceFactory
242: .setServiceDescriptionURL(persistentServiceDescriptionURL);
243: serviceFactory.setMarkupURL(persistentMarkupURL);
244: serviceFactory
245: .setPortletManagementURL(persistentPortletManagementURL);
246: serviceFactory
247: .setRegistrationURL(persistentRegistrationURL);
248: } else {
249: throw new IllegalStateException(
250: "Cannot initialize ServiceFactory: missing either service description or markup URLs!");
251: }
252: }
253:
254: startServiceFactoryIfNeeded();
255: }
256: }
257:
258: private void startServiceFactoryIfNeeded() {
259: if (!serviceFactory.isAvailable()) {
260: if (!serviceFactory.isFailed()) {
261: try {
262: serviceFactory.start();
263: refreshServices();
264: } catch (Exception e) {
265: throw new ConsumerException(
266: "Couldn't start ServiceFactory", e);
267: }
268: } else {
269: throw new ConsumerException(
270: "ServiceFactory has an error condition that couldn't be recovered from.");
271: }
272: }
273: }
274:
275: private void internalSetWsdlURL() {
276: try {
277: ((RemoteSOAPInvokerServiceFactory) serviceFactory)
278: .setWsdlDefinitionURL(persistentWsdlDefinitionURL);
279:
280: // update the URLs based on WSDL information
281: persistentMarkupURL = serviceFactory.getMarkupURL();
282: persistentPortletManagementURL = serviceFactory
283: .getPortletManagementURL();
284: persistentRegistrationURL = serviceFactory
285: .getRegistrationURL();
286: persistentServiceDescriptionURL = serviceFactory
287: .getServiceDescriptionURL();
288:
289: clean.set(0, 4); // if setting the WSDL URL worked, consider everything clean
290: isModifiedWSDL = false;
291: } catch (Exception e) {
292: throw new RuntimeException(e);
293: }
294: }
295:
296: public void start() throws Exception {
297: initServiceFactoryIfNeeded();
298: }
299:
300: public void stop() throws Exception {
301: getServiceFactory().stop();
302: }
303:
304: // todo: public for tests
305: public ServiceFactory getServiceFactory() {
306: initServiceFactoryIfNeeded();
307: startServiceFactoryIfNeeded();
308: return serviceFactory;
309: }
310:
311: // todo: public for tests
312: public void setServiceFactory(ServiceFactory serviceFactory) {
313: ParameterValidation.throwIllegalArgExceptionIfNull(
314: serviceFactory, "ServiceFactory");
315:
316: this .serviceFactory = serviceFactory;
317: persistentServiceDescriptionURL = serviceFactory
318: .getServiceDescriptionURL();
319: persistentMarkupURL = serviceFactory.getMarkupURL();
320: persistentPortletManagementURL = serviceFactory
321: .getPortletManagementURL();
322: persistentRegistrationURL = serviceFactory.getRegistrationURL();
323:
324: if (serviceFactory instanceof RemoteSOAPInvokerServiceFactory) {
325: persistentWsdlDefinitionURL = ((RemoteSOAPInvokerServiceFactory) serviceFactory)
326: .getWsdlDefinitionURL();
327: }
328:
329: }
330:
331: // todo: public for tests
332: public WSRP_v1_ServiceDescription_PortType getServiceDescriptionService()
333: throws InvokerUnavailableException {
334: return (WSRP_v1_ServiceDescription_PortType) getService(
335: SERVICE_DESCRIPTION,
336: WSRP_v1_ServiceDescription_PortType.class);
337: }
338:
339: // todo: public for tests
340: public WSRP_v1_Markup_PortType getMarkupService()
341: throws InvokerUnavailableException {
342: return (WSRP_v1_Markup_PortType) getService(MARKUP,
343: WSRP_v1_Markup_PortType.class);
344: }
345:
346: // todo: public for tests
347: public WSRP_v1_PortletManagement_PortType getPortletManagementService()
348: throws InvokerUnavailableException {
349: return (WSRP_v1_PortletManagement_PortType) getService(
350: PORTLET_MANAGEMENT,
351: WSRP_v1_PortletManagement_PortType.class);
352: }
353:
354: // todo: public for tests
355: public WSRP_v1_Registration_PortType getRegistrationService()
356: throws InvokerUnavailableException {
357: return (WSRP_v1_Registration_PortType) getService(REGISTRATION,
358: WSRP_v1_Registration_PortType.class);
359: }
360:
361: private Object getService(String description, Class clazz)
362: throws InvokerUnavailableException {
363: try {
364: Object service = getServiceFactory().getService(clazz);
365: clean.set(getIndexFor(clazz));
366: return service;
367: } catch (Exception e) {
368: throw new InvokerUnavailableException("Couldn't access "
369: + description + " service. Cause: "
370: + e.getLocalizedMessage(), e);
371: }
372: }
373:
374: private int getIndexFor(Class clazz) {
375: if (clazz == WSRP_v1_ServiceDescription_PortType.class) {
376: return SD;
377: }
378: if (clazz == WSRP_v1_Markup_PortType.class) {
379: return M;
380: }
381: if (clazz == WSRP_v1_PortletManagement_PortType.class) {
382: return PM;
383: }
384: return R;
385: }
386:
387: public boolean isAvailable() {
388: try {
389: return getServiceFactory().isAvailable();
390: } catch (Exception e) {
391: return false;
392: }
393: }
394:
395: public boolean isRefreshNeeded() {
396: boolean result = !isAvailable() || areURLsDirty();
397: if (result) {
398: log.debug("Refresh needed");
399: }
400: return result;
401: }
402:
403: private boolean areURLsDirty() {
404: return !clean.get(SD)
405: || !clean.get(M)
406: || (persistentPortletManagementURL != null && !clean
407: .get(PM))
408: || (persistentRegistrationURL != null && !clean.get(R));
409: }
410:
411: public void refresh() throws InvokerUnavailableException {
412: if (isRefreshNeeded()) {
413: initServiceFactoryIfNeeded();
414: refreshServices();
415: }
416: }
417:
418: private void refreshServices() throws InvokerUnavailableException {
419: if (areURLsDirty()) {
420: getServiceDescriptionService();
421: getMarkupService();
422: if (persistentPortletManagementURL != null) {
423: getPortletManagementService();
424: }
425: if (persistentRegistrationURL != null) {
426: getRegistrationService();
427: }
428: }
429: }
430: }
|