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