KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > loom > components > monitor > DefaultDeploymentMonitor


1 /* ====================================================================
2  * Loom Software License, version 1.1
3  *
4  * Copyright (c) 2003, Loom Group. All rights reserved.
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in
14  * the documentation and/or other materials provided with the
15  * distribution.
16  *
17  * 3. Neither the name of the Loom Group nor the name "Loom" nor
18  * the names of its contributors may be used to endorse or promote
19  * products derived from this software without specific prior
20  * written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  * ====================================================================
36  *
37  * Loom includes code from the Apache Software Foundation
38  *
39  * ====================================================================
40  * The Apache Software License, Version 1.1
41  *
42  * Copyright (c) 1997-2003 The Apache Software Foundation. All rights
43  * reserved.
44  *
45  * Redistribution and use in source and binary forms, with or without
46  * modification, are permitted provided that the following conditions
47  * are met:
48  *
49  * 1. Redistributions of source code must retain the above copyright
50  * notice, this list of conditions and the following disclaimer.
51  *
52  * 2. Redistributions in binary form must reproduce the above copyright
53  * notice, this list of conditions and the following disclaimer in
54  * the documentation and/or other materials provided with the
55  * distribution.
56  *
57  * 3. The end-user documentation included with the redistribution,
58  * if any, must include the following acknowledgment:
59  * "This product includes software developed by the
60  * Apache Software Foundation (http://www.apache.org/)."
61  * Alternately, this acknowledgment may appear in the software
62  * itself, if and wherever such third-party acknowledgments
63  * normally appear.
64  *
65  * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation"
66  * must not be used to endorse or promote products derived from this
67  * software without prior written permission. For written
68  * permission, please contact apache@apache.org.
69  *
70  * 5. Products derived from this software may not be called "Apache",
71  * nor may "Apache" appear in their name, without prior written
72  * permission of the Apache Software Foundation.
73  *
74  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
75  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
76  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
78  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
79  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
80  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
81  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
82  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
83  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
84  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
85  * SUCH DAMAGE.
86  */

87 package org.codehaus.loom.components.monitor;
88
89 import java.io.File JavaDoc;
90 import java.util.Arrays JavaDoc;
91 import java.util.HashSet JavaDoc;
92 import java.util.Iterator JavaDoc;
93 import java.util.Set JavaDoc;
94
95 import org.codehaus.loom.components.util.monitor.DirectoryChangeListener;
96 import org.codehaus.loom.components.util.monitor.DirectoryScanner;
97 import org.codehaus.loom.components.util.ExtensionFileFilter;
98 import org.codehaus.loom.interfaces.Deployer;
99
100 import org.codehaus.spice.salt.i18n.ResourceManager;
101 import org.codehaus.spice.salt.i18n.Resources;
102 import org.codehaus.spice.salt.io.FileUtil;
103
104 import org.codehaus.dna.AbstractLogEnabled;
105 import org.codehaus.dna.Active;
106 import org.codehaus.dna.Composable;
107 import org.codehaus.dna.Configurable;
108 import org.codehaus.dna.Configuration;
109 import org.codehaus.dna.ConfigurationException;
110 import org.codehaus.dna.MissingResourceException;
111 import org.codehaus.dna.ResourceLocator;
112
113 /**
114  * This class is responsible for monitoring the deployment directory and
115  * deploying, undelploying or redeploying applicatios as necessary.
116  *
117  * @author Peter Donald
118  * @author Johan Sjoberg
119  * @version $Revision: 1.6 $ $Date: 2004/10/11 20:12:27 $
120  */

121 public class DefaultDeploymentMonitor
122     extends AbstractLogEnabled
123     implements Configurable, Composable, Active, DirectoryChangeListener
124 {
125     private final static Resources REZ =
126       ResourceManager.getPackageResources( DefaultDeploymentMonitor.class );
127
128     /** The application directory */
129     private File JavaDoc m_appsDir;
130
131     /** Directory scanner */
132     private DirectoryScanner m_scanner;
133
134     /** Deployer that handles applications */
135     private Deployer m_deployer;
136
137     /** Frequency to poll the directory */
138     private long m_frequency;
139
140     /**
141      * Configure the class
142      * <br/>
143      * The parameters <code>scanner-frequency</code> and
144      * <code>base-application-directory</code> are used. The latter is
145      * mandatory. If no <code>scanner-frequency</code> is given it defaults
146      * to 5, which means five seconds. If the value is zero or negative five
147      * seconds will also be used as the default.
148      *
149      * @param configuration The configuration object
150      */

151     public void configure( final Configuration configuration )
152         throws ConfigurationException
153     {
154         m_frequency = 1000L
155           * configuration.getChild( "scanner-frequency" ).getValueAsLong( 5L );
156         if( m_frequency <= 0 )
157         {
158             m_frequency = 5000L;
159         }
160
161         final String JavaDoc appsDir =
162           configuration.getChild( "base-application-directory" ).getValue();
163         m_appsDir = new File JavaDoc( appsDir );
164     }
165
166     /**
167      * Compose
168      *
169      * @dna.dependency type="Deployer"
170      */

171     public void compose( final ResourceLocator locator )
172         throws MissingResourceException
173     {
174         m_deployer = (Deployer)locator.lookup( Deployer.class.getName() );
175     }
176
177     /**
178      * Start the scanner.
179      */

180     public void initialize()
181         throws Exception JavaDoc
182     {
183         deployDefaultApplications();
184         m_scanner = new DirectoryScanner();
185         m_scanner.setDirectory( m_appsDir.getPath() );
186         m_scanner.setFrequency( m_frequency );
187         m_scanner.setDirectoryChangeListener( this );
188         m_scanner.start();
189     }
190
191     /**
192      * Stop the scanner.
193      */

194     public void dispose()
195         throws Exception JavaDoc
196     {
197         m_scanner.stop();
198     }
199
200     public void unableToListContents()
201     {
202         getLogger().error( REZ.format( "monitor.no-list-contents.error", m_appsDir.toString() ) );
203     }
204
205     /**
206      * This method is called when the scanner notices changes
207      * in the deployment directory.
208      *
209      * @param type The type of change ( addition, removal or change )
210      * @param fileSet A set of <code>File</code>s that were changed
211      */

212     public void directoryChange( final int type, final Set JavaDoc fileSet )
213     {
214         final Set JavaDoc deployments = getDeployments( fileSet );
215         final Iterator JavaDoc iterator = deployments.iterator();
216         if( getLogger().isDebugEnabled() )
217         {
218             final String JavaDoc message =
219               REZ.format( "monitor.directory-change.notice",
220                                 new Integer JavaDoc( type ),
221                                 new Integer JavaDoc( fileSet.size() ),
222                                 new Integer JavaDoc( deployments.size() ) );
223             getLogger().debug( message );
224         }
225         if( deployments.isEmpty() )
226         {
227             return;
228         }
229
230         if( DirectoryChangeListener.ADDITION == type )
231         {
232             while( iterator.hasNext() )
233             {
234                 final File JavaDoc file = (File JavaDoc)iterator.next();
235                 deployApplication( file );
236             }
237         }
238         else if( DirectoryChangeListener.REMOVAL == type )
239         {
240             while( iterator.hasNext() )
241             {
242                 final File JavaDoc file = (File JavaDoc)iterator.next();
243                 undeployApplication( file );
244             }
245         }
246         else if( DirectoryChangeListener.MODIFICATION == type )
247         {
248             while( iterator.hasNext() )
249             {
250                 final File JavaDoc file = (File JavaDoc)iterator.next();
251                 redeployApplication( file );
252             }
253         }
254     }
255
256     /**
257      * Deploy application for specified file.
258      *
259      * @param file the application archive
260      */

261     private void deployApplication( final File JavaDoc file )
262     {
263         final String JavaDoc name = FileUtil.removeExtension( file.getName() );
264         try
265         {
266             final String JavaDoc message =
267               REZ.format( "monitor.deploy.notice", name, file );
268             getLogger().info( message );
269             m_deployer.deploy( name, file.toURL() );
270         }
271         catch( final Exception JavaDoc e )
272         {
273             final String JavaDoc message =
274               REZ.format( "monitor.no-deploy.error", file, e );
275             getLogger().warn( message, e );
276         }
277     }
278
279     /**
280      * Undeploy application for specified file.
281      *
282      * @param file the application archive
283      */

284     private void undeployApplication( final File JavaDoc file )
285     {
286         final String JavaDoc name = FileUtil.removeExtension( file.getName() );
287         try
288         {
289             final String JavaDoc message =
290                 REZ.format( "monitor.undeploy.notice", name );
291             getLogger().info( message );
292             m_deployer.undeploy( name );
293         }
294         catch( final Exception JavaDoc e )
295         {
296             final String JavaDoc message =
297                 REZ.format( "monitor.no-undeploy.error", file, e );
298             getLogger().warn( message, e );
299         }
300     }
301
302     /**
303      * Redeploy application for specified file.
304      *
305      * @param file the application archive
306      */

307     private void redeployApplication( final File JavaDoc file )
308     {
309         final String JavaDoc name =
310             FileUtil.removeExtension( file.getName() );
311         try
312         {
313             final String JavaDoc message =
314               REZ.format( "monitor.redeploy.notice", name, file );
315             getLogger().info( message );
316             m_deployer.redeploy( name, file.toURL() );
317         }
318         catch( final Exception JavaDoc e )
319         {
320             final String JavaDoc message =
321               REZ.format( "monitor.no-redeploy.error", file, e );
322             getLogger().warn( message, e );
323         }
324     }
325
326     /**
327      * Retrieve the set of files that are candidate deployments.
328      *
329      * @param newValue The file set to check.
330      */

331     private Set JavaDoc getDeployments( final Set JavaDoc newValue )
332     {
333         final Set JavaDoc deployments = new HashSet JavaDoc();
334         final Iterator JavaDoc iterator = newValue.iterator();
335         while( iterator.hasNext() )
336         {
337             final File JavaDoc file = (File JavaDoc)iterator.next();
338             if( isDeployment( file ) )
339             {
340                 deployments.add( file );
341             }
342             else
343             {
344                 final String JavaDoc message =
345                   REZ.format( "monitor.skipping-file.notice", file );
346                 getLogger().info( message );
347             }
348         }
349         return deployments;
350     }
351
352     /**
353      * Check if a file represents a loom deployment.
354      *
355      * @param file The file to check
356      * @return true If file represents a loom deployment, else false
357      */

358     private boolean isDeployment( final File JavaDoc file )
359     {
360         return !file.isDirectory() && file.getName().endsWith( ".sar" );
361     }
362
363     /**
364      * The deployer is used to load the applications from the
365      * default-apps-location specified in Parameters.
366      *
367      * @throws Exception if an error occurs
368      */

369     protected void deployDefaultApplications()
370         throws Exception JavaDoc
371     {
372         final ExtensionFileFilter filter = new ExtensionFileFilter( ".sar" );
373         final File JavaDoc[] files = m_appsDir.listFiles( filter );
374         if( null != files )
375         {
376             deployFiles( files );
377         }
378     }
379
380     /**
381      * Deploy SAR files
382      *
383      * @param files A list of .sar files
384      * @throws Exception if an error occurs
385      */

386     private void deployFiles( final File JavaDoc[] files )
387         throws Exception JavaDoc
388     {
389         Arrays.sort( files );
390         for( int i = 0; i < files.length; i++ )
391         {
392             final File JavaDoc file = files[i];
393             deployApplication( file );
394         }
395     }
396 }
397
Popular Tags