1 /**
2 * Copyright 2005-2006 the original author or authors.
3 *
4 * Licensed under the Gnu General Pubic License, Version 2.0 (the
5 * "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/gpl-license.php
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the Gnu General Public License for more details.
14 */
15 package org.figure8.join.services.notification;
16
17 import org.figure8.join.core.Configurable;
18 import org.figure8.join.core.ParameterDefinition;
19 import org.figure8.join.core.ContainerContextHandler;
20 import org.figure8.join.core.InfrastructureException;
21 import org.figure8.join.core.InvalidParameterException;
22 import org.figure8.join.core.setup.BootstrapManager;
23 import org.figure8.join.services.remoting.ReportingService;
24 import org.figure8.join.services.remoting.beans.RemoteSubscriber;
25 import org.figure8.join.services.remoting.beans.RemoteMailingList;
26 import org.figure8.join.util.LogUtil;
27
28 import com.caucho.hessian.client.HessianProxyFactory;
29
30 import org.apache.commons.logging.Log;
31
32 import java.util.List;
33 import java.util.Iterator;
34 import java.util.ArrayList;
35 import java.util.Properties;
36 import java.rmi.RemoteException;
37 /**
38 * This is a support class to extend for classes wanting to use {@link SubscribersNotifier}.
39 * @author <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
40 * @version $Revision: 1.1 $
41 */
42 public abstract class SubscribersNotifierAdapterSupport implements Configurable{
43
44
45
46 /** Get a commons logger. */
47 private static final Log log = LogUtil.getLog(SubscribersNotifierAdapterSupport.class);
48
49 /** Name of configurable parameter denoting the key of event to notity. */
50 public static final String EVENT_PARAM = "eventKey";
51 /** Name of configuratble parameter denoting the key of resource to notifiy event for. */
52 public static final String RESOURCE_PARAM = "resourceKey";
53
54 /** List of {@link ParameterDefinition}s supported by this adapter */
55 protected static List parameters = new ArrayList();
56
57 /** ParameterDefinition representation of parameter denoting the key of event to notify. */
58 protected static final ParameterDefinition eventParam = new ParameterDefinition(EVENT_PARAM,
59 "The key of event to notify using this notifier", "delivery", true);
60 /** ParameterDefinition representation of parameter denoting the key of resource to notify event for. */
61 protected static final ParameterDefinition resourceParam = new ParameterDefinition(RESOURCE_PARAM,
62 "The key of resource to notify event for", "mydeliverablekey", false);
63
64
65
66
67 /** The name identifying this notifier adapter. */
68 protected String name;
69 /** The key of event to notify to subscribers */
70 private String eventKey;
71 /** The key of resource to notify event for */
72 private String resourceKey;
73
74
75
76
77 /** Creates a new instance of SubscribersNotifierAdapterSupport. */
78 protected SubscribersNotifierAdapterSupport(){
79 }
80
81
82
83
84 /**
85 * Retrieve the name of this adapter.
86 * @return The name identifying this adapter
87 */
88 public String getName(){
89 return name;
90 }
91 /**
92 * Set the name identifying this adapter.
93 * @param name The name of this adapter
94 */
95 public void setName(String name){
96 this.name = name;
97 }
98 /** @return The key of event to notify to subscribers */
99 public String getEventKey(){
100 return eventKey;
101 }
102 /** @param eventKey The key of event to notify to subscribers */
103 public void setEventKey(String eventKey){
104 this.eventKey = eventKey;
105 }
106 /** @return The key of resource to notify event for */
107 public String getResourceKey(){
108 return resourceKey;
109 }
110 /** @param resourceKey The key of resource to notify event for */
111 public void setResourceKey(String resourceKey){
112 this.resourceKey = resourceKey;
113 }
114
115 /**
116 * Subclasses must implement this method in order to specify the
117 * Notifier implementation to use (and thus the publication media).
118 * @return The notifier implementation
119 */
120 public abstract SubscribersNotifier getSubscribersNotifier();
121
122
123
124
125 /**
126 * Get this object parameters definitions as a list
127 * @return A list of {@code ParameterDefinition} objects
128 */
129 public List getParameterDefinitionsAsList(){
130
131 if (parameters.isEmpty()){
132 parameters.addAll(getSubscribersNotifier().getParameterDefinitionsAsList());
133 parameters.add(eventParam);
134 parameters.add(resourceParam);
135 }
136 return parameters;
137 }
138
139 /**
140 * Get this object parameters definitions as an array
141 * @return An array of {@code ParameterDefinition} objects
142 */
143 public ParameterDefinition[] getParameterDefinitions(){
144 List result = getParameterDefinitionsAsList();
145 return (ParameterDefinition[])result.toArray(new ParameterDefinition[result.size()]);
146 }
147
148 /**
149 * Set the value of a parameter using its nama
150 * @param parameterName The name of parameter so set value for
151 * @param parameterValue The value of the paramater
152 * @throws InvalidParameterException if this parameter is not supported by this object
153 */
154 public void setParameter(String parameterName, String parameterValue) throws InvalidParameterException{
155 try{
156
157 getSubscribersNotifier().setParameter(parameterName, parameterValue);
158 }
159 catch (InvalidParameterException ipe){
160
161 if (EVENT_PARAM.equals(parameterName))
162 setEventKey(parameterValue);
163 else if (RESOURCE_PARAM.equals(parameterName))
164 setResourceKey(parameterValue);
165 else{
166 log.warn("The parameter '" + parameterName + "' is not supported by SubscribersNotifierAdapterSupport");
167 throw new InvalidParameterException("The parameter '" + parameterName + "' is not supported by SubscribersNotifierAdapterSupport");
168 }
169 }
170 }
171
172 /**
173 * Set the value of a parameter using its definitions
174 * @param parameter The definitino of the paramater to set
175 * @param parameterValue The value of the parameter
176 * @throws InvalidParameterException if this parameter is not supported by this object
177 */
178 public void setParameter(ParameterDefinition parameter, String parameterValue) throws InvalidParameterException{
179 setParameter(parameter.getName(), parameterValue);
180 }
181
182 /**
183 * Convenient methods for setting all attributes values using a single method.
184 * @param parameters Properties where keys are parameter names
185 * @throws InvalidParameterException if one of these parameters is not supported by this object
186 */
187 public void setParameters(Properties parameters) throws InvalidParameterException{
188 Iterator keys = parameters.keySet().iterator();
189 while (keys != null && keys.hasNext()){
190 String parameterName = (String)keys.next();
191 String parameterValue = parameters.getProperty(parameterName);
192 setParameter(parameterName, parameterValue);
193 }
194 }
195
196
197
198
199 /**
200 * Connect to remote reporting service and retrieve mailing list
201 * @param eventKey The key of event to retrieve mailing list for
202 * @param resourceId The id of resource to retrieve mailing list for (may be null if no resource specified)
203 * @return The corresponding mailing list
204 */
205 protected RemoteMailingList retrieveMailingList(String eventKey, String resourceId) throws Exception{
206
207 ReportingService service = retrieveReportingService();
208 if (resourceId != null)
209 return service.getMailingList(eventKey, resourceId);
210
211 RemoteMailingList[] lists = service.getMailingLists(eventKey);
212 if (lists != null){
213 if (lists.length > 0){
214 log.warn("There's more than one mailing list for event '" + eventKey + "' (" + lists.length + " lists )");
215 log.warn("Choosing the first list: " + lists[0].getName());
216 }
217 return lists[0];
218 }
219 return null;
220 }
221
222 /**
223 * Connect to remote reporting service and retrieve subscribers
224 * @param list The mailing list to retrieve subscribers for
225 * @return An array of list subscribers
226 */
227 protected RemoteSubscriber[] retrieveSubscribers(RemoteMailingList list) throws Exception{
228
229 ReportingService service = retrieveReportingService();
230 return service.getSubscribers(list);
231 }
232
233 /**
234 * Helper method for retrieving remote ReportingService. ReportingService is defined
235 * on synchronous side of application and notifiers are expected to run on asynchronous
236 * side of application. So we are using the <code>BootstrapManager.getOtherSideUrl()</code>
237 * as the root of remote service url.
238 * @throws InfrastructureException if BoostrapManager and url cannot be retrieved
239 * @throws RemoteException if remote service cannot be retievied
240 * @return The retievied remote ReportingService
241 * @see org.figure8.join.core.setup.BootstrapManager
242 */
243 protected ReportingService retrieveReportingService() throws InfrastructureException, RemoteException{
244
245 String connectionUrl = null;
246 ReportingService service = null;
247 try{
248
249 ContainerContextHandler handler = ContainerContextHandler.getInstance();
250 log.debug("ContainerContextHandler is available");
251 BootstrapManager manager = (BootstrapManager)handler.getComponent("bootstrapManager");
252 connectionUrl = manager.getOtherSideUrl();
253 connectionUrl += "/remoting/hessian/ReportingService";
254 }
255 catch (Exception e){
256
257 log.error("Exception while retrieving BootstrapManager. Maybe application is not correctly configured ?");
258 log.error("Here's the detailed message: " + e.getMessage());
259 throw new InfrastructureException("Exception while retrieving BootstrapManager", e);
260 }
261 try{
262
263 HessianProxyFactory proxyFactory = new HessianProxyFactory();
264 service = (ReportingService)proxyFactory.create(ReportingService.class, connectionUrl);
265 return service;
266 }
267 catch (Exception e){
268
269 log.error("Exception while connecting to remote ReportignService: " + e.getMessage());
270 throw new RemoteException("Exception while connecting to remote ReportingService", e);
271 }
272 }
273 }