View Javadoc

1   package org.apache.maven.continuum.notification.jabber;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.ArrayList;
23  import java.util.List;
24  import java.util.Map;
25  
26  import javax.annotation.Resource;
27  
28  import org.apache.continuum.model.project.ProjectScmRoot;
29  import org.apache.maven.continuum.configuration.ConfigurationService;
30  import org.apache.maven.continuum.model.project.BuildDefinition;
31  import org.apache.maven.continuum.model.project.BuildResult;
32  import org.apache.maven.continuum.model.project.Project;
33  import org.apache.maven.continuum.model.project.ProjectNotifier;
34  import org.apache.maven.continuum.notification.AbstractContinuumNotifier;
35  import org.apache.maven.continuum.notification.ContinuumNotificationDispatcher;
36  import org.apache.maven.continuum.notification.MessageContext;
37  import org.apache.maven.continuum.notification.NotificationException;
38  import org.codehaus.plexus.jabber.JabberClient;
39  import org.codehaus.plexus.jabber.JabberClientException;
40  import org.codehaus.plexus.util.StringUtils;
41  import org.slf4j.Logger;
42  import org.slf4j.LoggerFactory;
43  import org.springframework.stereotype.Service;
44  
45  /**
46   * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
47   * @version $Id: JabberContinuumNotifier.java 769240 2009-04-28 04:59:03Z evenisse $
48   */
49  @Service("notifier#jabber")
50  public class JabberContinuumNotifier
51      extends AbstractContinuumNotifier
52  {
53      private static final Logger log = LoggerFactory.getLogger( JabberContinuumNotifier.class );
54  
55      // ----------------------------------------------------------------------
56      // Requirements
57      // ----------------------------------------------------------------------
58  
59      @Resource
60      private JabberClient jabberClient;
61  
62      @Resource
63      private ConfigurationService configurationService;
64  
65      // ----------------------------------------------------------------------
66      // Configuration
67      // ----------------------------------------------------------------------
68  
69      /**
70       * @plexus.configuration
71       */
72      private String fromAddress;
73  
74      /**
75       * @plexus.configuration
76       */
77      private String fromPassword;
78  
79      /**
80       * @plexus.configuration
81       */
82      private String host;
83  
84      /**
85       * @plexus.configuration
86       */
87      private int port;
88  
89      /**
90       * @plexus.configuration
91       */
92      private String imDomainName;
93  
94      /**
95       * @plexus.configuration
96       */
97      private boolean sslConnection;
98  
99      // ----------------------------------------------------------------------
100     // Notifier Implementation
101     // ----------------------------------------------------------------------
102 
103     public String getType()
104     {
105         return "jabber";
106     }
107 
108     public void sendMessage( String messageId, MessageContext context )
109         throws NotificationException
110     {
111         Project project = context.getProject();
112 
113         List<ProjectNotifier> notifiers = context.getNotifiers();
114         BuildDefinition buildDefinition = context.getBuildDefinition();
115         BuildResult build = context.getBuildResult();
116         ProjectScmRoot projectScmRoot = context.getProjectScmRoot();
117 
118         boolean isPrepareBuildComplete =
119             messageId.equals( ContinuumNotificationDispatcher.MESSAGE_ID_PREPARE_BUILD_COMPLETE );
120 
121         if ( projectScmRoot == null && isPrepareBuildComplete )
122         {
123             return;
124         }
125 
126         // ----------------------------------------------------------------------
127         // If there wasn't any building done, don't notify
128         // ----------------------------------------------------------------------
129 
130         if ( build == null && !isPrepareBuildComplete )
131         {
132             return;
133         }
134 
135         // ----------------------------------------------------------------------
136         //
137         // ----------------------------------------------------------------------
138 
139         List<String> recipients = new ArrayList<String>();
140         for ( ProjectNotifier notifier : notifiers )
141         {
142             Map<String, String> configuration = notifier.getConfiguration();
143             if ( configuration != null && StringUtils.isNotEmpty( configuration.get( ADDRESS_FIELD ) ) )
144             {
145                 recipients.add( configuration.get( ADDRESS_FIELD ) );
146             }
147         }
148 
149         if ( recipients.size() == 0 )
150         {
151             log.info( "No Jabber recipients for '" + project.getName() + "'." );
152 
153             return;
154         }
155 
156         // ----------------------------------------------------------------------
157         //
158         // ----------------------------------------------------------------------
159 
160         if ( messageId.equals( ContinuumNotificationDispatcher.MESSAGE_ID_BUILD_COMPLETE ) )
161         {
162             for ( ProjectNotifier notifier : notifiers )
163             {
164                 buildComplete( project, notifier, build, buildDefinition );
165             }
166         }
167         else if ( isPrepareBuildComplete )
168         {
169             for ( ProjectNotifier notifier : notifiers )
170             {
171                 prepareBuildComplete( projectScmRoot, notifier );
172             }
173         }
174     }
175 
176     // ----------------------------------------------------------------------
177     //
178     // ----------------------------------------------------------------------
179 
180     private void buildComplete( Project project, ProjectNotifier notifier, BuildResult build, BuildDefinition buildDef )
181         throws NotificationException
182     {
183         // ----------------------------------------------------------------------
184         // Check if the mail should be sent at all
185         // ----------------------------------------------------------------------
186 
187         BuildResult previousBuild = getPreviousBuild( project, buildDef, build );
188 
189         if ( !shouldNotify( build, previousBuild, notifier ) )
190         {
191             return;
192         }
193 
194         sendMessage( notifier.getConfiguration(), generateMessage( project, build, configurationService ) );
195     }
196 
197     private void prepareBuildComplete( ProjectScmRoot projectScmRoot, ProjectNotifier notifier )
198         throws NotificationException
199     {
200         if ( !shouldNotify( projectScmRoot, notifier ) )
201         {
202             return;
203         }
204 
205         sendMessage( notifier.getConfiguration(), generateMessage( projectScmRoot, configurationService ) );
206     }
207 
208     private void sendMessage( Map<String, String> configuration, String message )
209         throws NotificationException
210     {
211         jabberClient.setHost( getHost( configuration ) );
212 
213         jabberClient.setPort( getPort( configuration ) );
214 
215         jabberClient.setUser( getUsername( configuration ) );
216 
217         jabberClient.setPassword( getPassword( configuration ) );
218 
219         jabberClient.setImDomainName( getImDomainName( configuration ) );
220 
221         jabberClient.setSslConnection( isSslConnection( configuration ) );
222 
223         try
224         {
225             jabberClient.connect();
226 
227             jabberClient.logon();
228 
229             if ( configuration != null && StringUtils.isNotEmpty( configuration.get( ADDRESS_FIELD ) ) )
230             {
231                 String address = configuration.get( ADDRESS_FIELD );
232                 String[] recipients = StringUtils.split( address, "," );
233                 for ( String recipient : recipients )
234                 {
235                     if ( isGroup( configuration ) )
236                     {
237                         jabberClient.sendMessageToGroup( recipient, message );
238                     }
239                     else
240                     {
241                         jabberClient.sendMessageToUser( recipient, message );
242                     }
243                 }
244             }
245         }
246         catch ( JabberClientException e )
247         {
248             throw new NotificationException( "Exception while sending message.", e );
249         }
250         finally
251         {
252             try
253             {
254                 jabberClient.logoff();
255             }
256             catch ( JabberClientException e )
257             {
258 
259             }
260         }
261     }
262 
263     private String getHost( Map<String, String> configuration )
264     {
265         if ( configuration.containsKey( "host" ) )
266         {
267             return configuration.get( "host" );
268         }
269         else
270         {
271             if ( configuration.containsKey( "address" ) )
272             {
273                 String username = configuration.get( "address" );
274 
275                 if ( username.indexOf( "@" ) > 0 )
276                 {
277                     return username.substring( username.indexOf( "@" ) + 1 );
278                 }
279             }
280         }
281 
282         return host;
283     }
284 
285     private int getPort( Map<String, String> configuration )
286     {
287         if ( configuration.containsKey( "port" ) )
288         {
289             try
290             {
291                 return Integer.parseInt( configuration.get( "port" ) );
292             }
293             catch ( NumberFormatException e )
294             {
295                 log.error( "jabber port isn't a number.", e );
296             }
297         }
298 
299         if ( port > 0 )
300         {
301             return port;
302         }
303         else if ( isSslConnection( configuration ) )
304         {
305             return 5223;
306         }
307         else
308         {
309             return 5222;
310         }
311     }
312 
313     private String getUsername( Map<String, String> configuration )
314     {
315         if ( configuration.containsKey( "login" ) )
316         {
317             String username = configuration.get( "login" );
318 
319             if ( username.indexOf( "@" ) > 0 )
320             {
321                 username = username.substring( 0, username.indexOf( "@" ) );
322             }
323 
324             return username;
325         }
326 
327         return fromAddress;
328     }
329 
330     private String getPassword( Map<String, String> configuration )
331     {
332         if ( configuration.containsKey( "password" ) )
333         {
334             return configuration.get( "password" );
335         }
336 
337         return fromPassword;
338     }
339 
340     private boolean isSslConnection( Map<String, String> configuration )
341     {
342         if ( configuration.containsKey( "sslConnection" ) )
343         {
344             return convertBoolean( configuration.get( "sslConnection" ) );
345         }
346 
347         return sslConnection;
348     }
349 
350     private String getImDomainName( Map<String, String> configuration )
351     {
352         if ( configuration.containsKey( "domainName" ) )
353         {
354             return configuration.get( "domainName" );
355         }
356 
357         return imDomainName;
358     }
359 
360     private boolean isGroup( Map<String, String> configuration )
361     {
362         return configuration.containsKey( "isGroup" ) && convertBoolean( configuration.get( "isGroup" ) );
363     }
364 
365     private boolean convertBoolean( String value )
366     {
367         return "true".equalsIgnoreCase( value ) || "on".equalsIgnoreCase( value ) || "yes".equalsIgnoreCase( value );
368     }
369 }