View Javadoc
1   package org.codehaus.mojo.appassembler.daemon.jsw;
2   
3   /*
4    * The MIT License
5    *
6    * Copyright (c) 2006-2012, The Codehaus
7    *
8    * Permission is hereby granted, free of charge, to any person obtaining a copy of
9    * this software and associated documentation files (the "Software"), to deal in
10   * the Software without restriction, including without limitation the rights to
11   * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12   * of the Software, and to permit persons to whom the Software is furnished to do
13   * so, subject to the following conditions:
14   *
15   * The above copyright notice and this permission notice shall be included in all
16   * copies or substantial portions of the Software.
17   *
18   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24   * SOFTWARE.
25   */
26  
27  import java.io.ByteArrayInputStream;
28  import java.io.ByteArrayOutputStream;
29  import java.io.File;
30  import java.io.FileInputStream;
31  import java.io.FileNotFoundException;
32  import java.io.FileOutputStream;
33  import java.io.FileWriter;
34  import java.io.IOException;
35  import java.io.InputStream;
36  import java.io.InputStreamReader;
37  import java.io.Reader;
38  import java.util.ArrayList;
39  import java.util.HashMap;
40  import java.util.Iterator;
41  import java.util.List;
42  import java.util.Map;
43  import java.util.Properties;
44  
45  import org.apache.maven.artifact.Artifact;
46  import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
47  import org.apache.maven.project.MavenProject;
48  import org.codehaus.mojo.appassembler.daemon.DaemonGenerationRequest;
49  import org.codehaus.mojo.appassembler.daemon.DaemonGenerator;
50  import org.codehaus.mojo.appassembler.daemon.DaemonGeneratorException;
51  import org.codehaus.mojo.appassembler.model.Daemon;
52  import org.codehaus.mojo.appassembler.model.GeneratorConfiguration;
53  import org.codehaus.mojo.appassembler.util.DependencyFactory;
54  import org.codehaus.mojo.appassembler.util.FormattedProperties;
55  import org.codehaus.plexus.logging.AbstractLogEnabled;
56  import org.codehaus.plexus.util.FileUtils;
57  import org.codehaus.plexus.util.IOUtil;
58  import org.codehaus.plexus.util.InterpolationFilterReader;
59  import org.codehaus.plexus.util.StringUtils;
60  
61  /**
62   * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
63   * @version $Id$
64   * @plexus.component role-hint="jsw"
65   */
66  public class JavaServiceWrapperDaemonGenerator
67      extends AbstractLogEnabled
68      implements DaemonGenerator
69  {
70      private static final Map<String, String> JSW_PLATFORMS_MAP = new HashMap<String, String>()
71      {
72          {
73              put( "aix-ppc-32-lib", "libwrapper-aix-ppc-32.a" );
74              put( "aix-ppc-32-exec", "wrapper-aix-ppc-32" );
75              put( "aix-ppc-64-lib", "libwrapper-aix-ppc-64.a" );
76              put( "aix-ppc-64-exec", "wrapper-aix-ppc-64" );
77              put( "hpux-parisc-64-lib", "libwrapper-hpux-parisc-64.sl" );
78              put( "hpux-parisc-64-exec", "wrapper-hpux-parisc-64" );
79              put( "linux-x86-32-lib", "libwrapper-linux-x86-32.so" );
80              put( "linux-x86-32-exec", "wrapper-linux-x86-32" );
81              put( "linux-x86-64-lib", "libwrapper-linux-x86-64.so" );
82              put( "linux-x86-64-exec", "wrapper-linux-x86-64" );
83              put( "linux-ppc-64-lib", "libwrapper-linux-ppc-64.so" );
84              put( "linux-ppc-64-exec", "wrapper-linux-ppc-64" );
85              put( "macosx-ppc-32-lib", "libwrapper-macosx-ppc-32.jnilib" );
86              put( "macosx-ppc-32-exec", "wrapper-macosx-ppc-32" );
87              put( "macosx-x86-universal-32-lib", "libwrapper-macosx-universal-32.jnilib" );
88              put( "macosx-x86-universal-32-exec", "wrapper-macosx-universal-32" );
89              put( "macosx-universal-32-lib", "libwrapper-macosx-universal-32.jnilib" );
90              put( "macosx-universal-32-exec", "wrapper-macosx-universal-32" );
91              put( "macosx-universal-64-lib", "libwrapper-macosx-universal-64.jnilib" );
92              put( "macosx-universal-64-exec", "wrapper-macosx-universal-64" );
93              put( "solaris-sparc-32-lib", "libwrapper-solaris-sparc-32.so" );
94              put( "solaris-sparc-32-exec", "wrapper-solaris-sparc-32" );
95              put( "solaris-sparc-64-lib", "libwrapper-solaris-sparc-64.so" );
96              put( "solaris-sparc-64-exec", "wrapper-solaris-sparc-64" );
97              put( "solaris-x86-32-lib", "libwrapper-solaris-x86-32.so" );
98              put( "solaris-x86-32-exec", "wrapper-solaris-x86-32" );
99              put( "solaris-x86-64-lib", "libwrapper-solaris-x86-64.so" );
100             put( "solaris-x86-64-exec", "wrapper-solaris-x86-64" );
101             put( "windows-x86-32-lib", "wrapper-windows-x86-32.dll" );
102             put( "windows-x86-32-exec", "wrapper-windows-x86-32.exe" );
103             put( "windows-x86-64-lib", "wrapper-windows-x86-64.dll" );
104             put( "windows-x86-64-exec", "wrapper-windows-x86-64.exe" );
105         }
106     };
107 
108     /**
109      * The directory where the JSW executable files are fetched from.
110      */
111     private static final String JSW_BIN_DIR = "bin";
112 
113     /**
114      * The directory where the JSW lib files are fetched from.
115      */
116     private static final String JSW_LIB_DIR = "lib";
117 
118     // -----------------------------------------------------------------------
119     // DaemonGenerator Implementation
120     // -----------------------------------------------------------------------
121 
122     public void generate( DaemonGenerationRequest request )
123         throws DaemonGeneratorException
124     {
125         Daemon daemon = request.getDaemon();
126 
127         File outputDirectory = new File( request.getOutputDirectory(), daemon.getId() );
128 
129         Properties configuration = createConfiguration( daemon );
130 
131         // Don't want these in the wrapper.conf file
132         String appBaseEnvVar = configuration.getProperty( "app.base.envvar", "APP_BASE" );
133         configuration.remove( "app.base.envvar" );
134         String runAsUserEnvVar = configuration.getProperty( "run.as.user.envvar", "" );
135         if ( !runAsUserEnvVar.equals( "" ) )
136         {
137             runAsUserEnvVar = "RUN_AS_USER=" + runAsUserEnvVar;
138             configuration.remove( "run.as.user.envvar" );
139         }
140         String pidFile = configuration.getProperty( "wrapper.pidfile", "$BASEDIR/logs" );
141 
142         // Don't want these in the wrapper.conf file
143         String chkconfigRun = configuration.getProperty( "chkconfig.run", "2345" ); // 2345 is the original run level,
144                                                                                     // donot change this default value
145         configuration.remove( "chkconfig.level" );
146         String chkconfigStart = configuration.getProperty( "chkconfig.start", "20" );
147         configuration.remove( "chkconfig.start" );
148         String chkconfigStop = configuration.getProperty( "chkconfig.stop", "80" );
149         configuration.remove( "chkconfig.stop" );
150 
151         Properties context = createContext( request, daemon );
152         context.setProperty( "app.base.envvar", appBaseEnvVar );
153         context.setProperty( "wrapper.pidfile", pidFile );
154         context.setProperty( "run.as.user.envvar", runAsUserEnvVar );
155         context.setProperty( "wrapper.conf.directory", daemon.getConfigurationDirectory() );
156         context.setProperty( "wrapper.conf.fileName", this.getWrapperConfigFileName( daemon ) );
157         context.setProperty( "chkconfig.run", chkconfigRun );
158         context.setProperty( "chkconfig.start", chkconfigStart );
159         context.setProperty( "chkconfig.stop", chkconfigStop );
160         context.setProperty( "wrapper.exe.prefix", "wrapper" );
161         if ( daemon.isUseDaemonIdAsWrapperExePrefixName() )
162         {
163             context.setProperty( "wrapper.exe.prefix", daemon.getId() );
164         }
165 
166         writeWrapperConfFile( request, daemon, outputDirectory, context, configuration );
167 
168         writeScriptFiles( request, daemon, outputDirectory, context );
169 
170         List<String> jswPlatformIncludes = getJswPlatformIncludes( daemon );
171 
172         writeLibraryFiles( outputDirectory, daemon, jswPlatformIncludes );
173 
174         writeExecutableFiles( outputDirectory, daemon, jswPlatformIncludes );
175     }
176 
177     private void writeWrapperConfFile( DaemonGenerationRequest request, Daemon daemon, File outputDirectory,
178                                        Properties context, Properties configuration )
179         throws DaemonGeneratorException
180     {
181         InputStream in = this.getClass().getResourceAsStream( "conf/wrapper.conf.in" );
182 
183         if ( in == null )
184         {
185             throw new DaemonGeneratorException( "Could not load template." );
186         }
187 
188         FormattedProperties confFile = new FormattedProperties();
189 
190         try
191         {
192             confFile.read( in );
193         }
194         catch ( IOException e )
195         {
196             throw new DaemonGeneratorException( "Error reading template: " + e.getMessage(), e );
197         }
198         finally
199         {
200             IOUtil.close( in );
201         }
202 
203         // TODO: configurable?
204         confFile.setPropertyAfter( "wrapper.working.dir", "..", "wrapper.java.command" );
205         confFile.setProperty( "wrapper.java.library.path.1", daemon.getRepositoryName() );
206         confFile.setPropertyAfter( "set.default.REPO_DIR", daemon.getRepositoryName(), "wrapper.java.mainclass" );
207 
208         confFile.setPropertyAfter( "set." + context.getProperty( "app.base.envvar" ), ".", "wrapper.java.mainclass" );
209 
210         if ( daemon.getWrapperLogFile() == null )
211         {
212             // Write the default value to the wrapper.logfile.
213             confFile.setProperty( "wrapper.logfile", "../logs/wrapper.log" );
214         }
215         else
216         {
217             confFile.setProperty( "wrapper.logfile", daemon.getWrapperLogFile() );
218         }
219 
220         if ( daemon.getJvmSettings() != null && !StringUtils.isEmpty( daemon.getJvmSettings().getInitialMemorySize() ) )
221         {
222             confFile.setProperty( "wrapper.java.initmemory", daemon.getJvmSettings().getInitialMemorySize() );
223         }
224 
225         if ( daemon.getJvmSettings() != null && !StringUtils.isEmpty( daemon.getJvmSettings().getMaxMemorySize() ) )
226         {
227             confFile.setProperty( "wrapper.java.maxmemory", daemon.getJvmSettings().getMaxMemorySize() );
228         }
229 
230         confFile.setProperty( "wrapper.java.mainclass", daemon.getWrapperMainClass() );
231         if ( !StringUtils.isEmpty( daemon.getMainClass() ) )
232         {
233             confFile.setProperty( "wrapper.app.parameter.1", daemon.getMainClass() );
234         }
235 
236         createClasspath( daemon, request, confFile, configuration );
237         createAdditional( daemon, confFile );
238         createParameters( daemon, confFile );
239 
240         for ( Map.Entry entry : configuration.entrySet() )
241         {
242             String key = (String) entry.getKey();
243             String value = (String) entry.getValue();
244             if ( value.length() > 0 )
245             {
246                 confFile.setProperty( key, value );
247             }
248             else
249             {
250                 confFile.removeProperty( key );
251             }
252         }
253 
254         ByteArrayOutputStream string = new ByteArrayOutputStream();
255         confFile.save( string );
256 
257         Reader reader = new InputStreamReader( new ByteArrayInputStream( string.toByteArray() ) );
258 
259         File wrapperConf =
260             new File( outputDirectory, daemon.getConfigurationDirectory() + "/" + getWrapperConfigFileName( daemon ) );
261         writeFilteredFile( request, daemon, reader, wrapperConf, context );
262 
263         if ( daemon.getPreWrapperConf() != null )
264         {
265             insertPreWrapperConf( wrapperConf, new File( daemon.getPreWrapperConf() ) );
266         }
267 
268     }
269 
270     private void insertPreWrapperConf( File wrapperConf, File preWrapperConf )
271         throws DaemonGeneratorException
272     {
273         try
274         {
275             StringBuilder buffer = new StringBuilder();
276             buffer.append( FileUtils.fileRead( preWrapperConf ) );
277             buffer.append( "\n" );
278             buffer.append( FileUtils.fileRead( wrapperConf ) );
279             FileUtils.fileWrite( wrapperConf, buffer.toString() );
280         }
281         catch ( IOException e )
282         {
283             throw new DaemonGeneratorException( "Unable to merge pre wrapper config file." );
284         }
285     }
286 
287     private String getWrapperConfigFileName( Daemon daemon )
288     {
289         String wrapperConfigFileName = "wrapper.conf";
290         if ( daemon.isUseDaemonIdAsWrapperConfName() )
291         {
292             wrapperConfigFileName = "wrapper-" + daemon.getId() + ".conf";
293         }
294 
295         return wrapperConfigFileName;
296     }
297 
298     private Properties createConfiguration( Daemon daemon )
299     {
300         Properties configuration = new Properties();
301 
302         for ( GeneratorConfiguration generatorConfiguration : daemon.getGeneratorConfigurations() )
303         {
304             if ( generatorConfiguration.getGenerator().equals( "jsw" ) )
305             {
306                 configuration.putAll( generatorConfiguration.getConfiguration() );
307             }
308         }
309         return configuration;
310     }
311 
312     private static void writeFilteredFile( DaemonGenerationRequest request, Daemon daemon, Reader reader,
313                                            File outputFile, Map context )
314         throws DaemonGeneratorException
315     {
316         InterpolationFilterReader interpolationFilterReader = new InterpolationFilterReader( reader, context, "@", "@" );
317 
318         writeFile( outputFile, interpolationFilterReader );
319     }
320 
321     private static Properties createContext( DaemonGenerationRequest request, Daemon daemon )
322     {
323         Properties context = new Properties();
324         context.setProperty( "app.long.name", request.getMavenProject().getName() );
325         context.setProperty( "app.name", daemon.getId() );
326         String description = request.getMavenProject().getDescription();
327         if ( description == null )
328         {
329             description = request.getMavenProject().getName();
330         }
331         context.setProperty( "app.description", description );
332 
333         String envSetupFileName = daemon.getEnvironmentSetupFileName();
334 
335         String envSetup = "";
336         if ( envSetupFileName != null )
337         {
338             String envScriptPath = "\"%BASEDIR%\\bin\\" + envSetupFileName + ".bat\"";
339             envSetup = "if exist " + envScriptPath + " call " + envScriptPath;
340             context.put( "env.setup.windows", envSetup );
341 
342             envScriptPath = "\"$BASEDIR\"/bin/" + envSetupFileName;
343             envSetup = "[ -f " + envScriptPath + " ] && . " + envScriptPath;
344             context.put( "env.setup.unix", envSetup );
345         }
346         else
347         {
348             context.put( "env.setup.windows", envSetup );
349             context.put( "env.setup.unix", envSetup );
350         }
351 
352         return context;
353     }
354 
355     private static void writeFile( File outputFile, Reader reader )
356         throws DaemonGeneratorException
357     {
358         FileWriter out = null;
359 
360         try
361         {
362             outputFile.getParentFile().mkdirs();
363             out = new FileWriter( outputFile );
364 
365             IOUtil.copy( reader, out );
366         }
367         catch ( IOException e )
368         {
369             throw new DaemonGeneratorException( "Error writing output file: " + outputFile.getAbsolutePath(), e );
370         }
371         finally
372         {
373             IOUtil.close( reader );
374             IOUtil.close( out );
375         }
376     }
377 
378     private static void writeFile( File outputFile, InputStream inputStream )
379         throws DaemonGeneratorException
380     {
381         FileOutputStream out = null;
382 
383         try
384         {
385             outputFile.getParentFile().mkdirs();
386             out = new FileOutputStream( outputFile );
387 
388             IOUtil.copy( inputStream, out );
389         }
390         catch ( IOException e )
391         {
392             throw new DaemonGeneratorException( "Error writing output file: " + outputFile.getAbsolutePath(), e );
393         }
394         finally
395         {
396             IOUtil.close( inputStream );
397             IOUtil.close( out );
398         }
399     }
400 
401     private void createClasspath( Daemon daemon, DaemonGenerationRequest request, FormattedProperties confFile,
402                                   Properties configuration )
403     {
404         final String wrapperClassPathPrefix = "wrapper.java.classpath.";
405 
406         int counter = 1;
407         // @todo dennisl: Shouldn't we be using %REPO_DIR% here?
408         confFile.setProperty( wrapperClassPathPrefix + counter++, daemon.getRepositoryName() + "/wrapper.jar" );
409 
410         String configurationDirFirst = configuration.getProperty( "configuration.directory.in.classpath.first" );
411         if ( configurationDirFirst != null )
412         {
413             confFile.setProperty( wrapperClassPathPrefix + counter++, configurationDirFirst );
414         }
415 
416         MavenProject project = request.getMavenProject();
417         ArtifactRepositoryLayout layout = request.getRepositoryLayout();
418 
419         // Load all jars in %ENDORSED_DIR% if specified
420         if ( daemon.getEndorsedDir() != null )
421         {
422             confFile.setProperty( wrapperClassPathPrefix + counter++, daemon.getEndorsedDir() + "/*" );
423         }
424 
425         if ( daemon.isUseWildcardClassPath() )
426         {
427             confFile.setProperty( wrapperClassPathPrefix + counter++, "%REPO_DIR%/*" );
428         }
429         else
430         {
431             confFile.setProperty( wrapperClassPathPrefix + counter++,
432                                   "%REPO_DIR%/"
433                                       + DependencyFactory.create( project.getArtifact(), layout, true,
434                                                                   request.getOutputFileNameMapping() ).getRelativePath() );
435 
436             Iterator j = project.getRuntimeArtifacts().iterator();
437             while ( j.hasNext() )
438             {
439                 Artifact artifact = (Artifact) j.next();
440 
441                 confFile.setProperty( wrapperClassPathPrefix + counter,
442                                       "%REPO_DIR%/"
443                                           + DependencyFactory.create( artifact, layout,
444                                                                       daemon.isUseTimestampInSnapshotFileName(),
445                                                                       request.getOutputFileNameMapping() ).getRelativePath() );
446                 counter++;
447             }
448         }
449 
450         String configurationDirLast = configuration.getProperty( "configuration.directory.in.classpath.last" );
451         if ( configurationDirLast != null )
452         {
453             confFile.setProperty( wrapperClassPathPrefix + counter++, configurationDirLast );
454         }
455     }
456 
457     private static void createAdditional( Daemon daemon, FormattedProperties confFile )
458     {
459         if ( daemon.getJvmSettings() != null )
460         {
461             int count = 1;
462             for ( Iterator i = daemon.getJvmSettings().getSystemProperties().iterator(); i.hasNext(); count++ )
463             {
464                 String systemProperty = (String) i.next();
465                 confFile.setProperty( "wrapper.java.additional." + count, "-D" + systemProperty );
466             }
467             for ( Iterator i = daemon.getJvmSettings().getExtraArguments().iterator(); i.hasNext(); count++ )
468             {
469                 String extraArgument = (String) i.next();
470                 confFile.setProperty( "wrapper.java.additional." + count, extraArgument );
471             }
472         }
473     }
474 
475     private static void createParameters( Daemon daemon, FormattedProperties confFile )
476     {
477         int count = StringUtils.isEmpty( daemon.getMainClass() ) ? 1 : 2;
478 
479         for ( Iterator i = daemon.getCommandLineArguments().iterator(); i.hasNext(); count++ )
480         {
481             String argument = (String) i.next();
482             if ( StringUtils.isNotEmpty( argument ) )
483             {
484                 confFile.setProperty( "wrapper.app.parameter." + count, argument );
485             }
486         }
487 
488         if ( count == 1 )
489         { // Remove default parameter if not set
490             confFile.removeProperty( "wrapper.app.parameter.1" );
491         }
492     }
493 
494     private void writeScriptFiles( DaemonGenerationRequest request, Daemon daemon, File outputDirectory,
495                                    Properties context )
496         throws DaemonGeneratorException
497     {
498         InputStream shellScriptInputStream = null;
499         InputStream batchFileInputStream = null;
500         try
501         {
502             // TODO: selectively depending on selected platforms instead of always doing both
503             shellScriptInputStream = getUnixTemplate( daemon );
504 
505             if ( shellScriptInputStream == null )
506             {
507                 throw new DaemonGeneratorException( "Could not load template." );
508             }
509 
510             Reader reader = new InputStreamReader( shellScriptInputStream );
511 
512             writeFilteredFile( request, daemon, reader, new File( outputDirectory, "bin/" + daemon.getId() ), context );
513 
514             batchFileInputStream = this.getWindowsTemplate( daemon );
515 
516             if ( batchFileInputStream == null )
517             {
518                 throw new DaemonGeneratorException( "Could not load template." );
519             }
520 
521             reader = new InputStreamReader( batchFileInputStream );
522 
523             writeFilteredFile( request, daemon, reader, new File( outputDirectory, "bin/" + daemon.getId() + ".bat" ),
524                                context );
525         }
526         finally
527         {
528             IOUtil.close( shellScriptInputStream );
529             IOUtil.close( batchFileInputStream );
530         }
531     }
532 
533     private InputStream getUnixTemplate( Daemon daemon )
534         throws DaemonGeneratorException
535     {
536         return getTemplate( daemon.getUnixScriptTemplate(), "bin/sh.script.in" );
537     }
538 
539     private InputStream getWindowsTemplate( Daemon daemon )
540         throws DaemonGeneratorException
541     {
542         return getTemplate( daemon.getWindowsScriptTemplate(), "bin/AppCommand.bat.in" );
543     }
544 
545     private InputStream getTemplate( String customTemplate, String internalTemplate )
546         throws DaemonGeneratorException
547     {
548 
549         InputStream is = null;
550 
551         try
552         {
553             if ( customTemplate != null )
554             {
555                 File customTemplateFile = new File( customTemplate );
556                 if ( customTemplateFile.exists() )
557                 {
558                     is = new FileInputStream( customTemplateFile );
559                 }
560                 else
561                 {
562                     is = getClass().getClassLoader().getResourceAsStream( customTemplate );
563                     if ( is == null )
564                     {
565                         throw new DaemonGeneratorException( "Unable to load external template resource: "
566                             + customTemplate );
567                     }
568 
569                 }
570             }
571             else
572             {
573                 is = this.getClass().getResourceAsStream( internalTemplate );
574                 if ( is == null )
575                 {
576                     throw new DaemonGeneratorException( "Unable to load internal template resource: "
577                         + internalTemplate );
578                 }
579             }
580 
581         }
582         catch ( FileNotFoundException e )
583         {
584             throw new DaemonGeneratorException( "Unable to load external template file", e );
585         }
586 
587         return is;
588     }
589 
590     private void writeLibraryFiles( File outputDirectory, Daemon daemon, List<String> jswPlatformIncludes )
591         throws DaemonGeneratorException
592     {
593         if ( daemon.getExternalDeltaPackDirectory() != null )
594         {
595             copyExternalFile( new File( daemon.getExternalDeltaPackDirectory(), JSW_LIB_DIR + "/wrapper.jar" ),
596                               new File( outputDirectory, daemon.getRepositoryName() + "/wrapper.jar" ) );
597         }
598         else
599         {
600             copyResourceFile( new File( outputDirectory, daemon.getRepositoryName() ), JSW_LIB_DIR, "wrapper.jar",
601                               "wrapper.jar" );
602         }
603 
604         for ( String platform : jswPlatformIncludes )
605         {
606             String libFile = JSW_PLATFORMS_MAP.get( platform + "-lib" );
607             if ( libFile != null )
608             {
609                 if ( daemon.getExternalDeltaPackDirectory() != null )
610                 {
611                     copyExternalFile( new File( daemon.getExternalDeltaPackDirectory(), JSW_LIB_DIR + "/" + libFile ),
612                                       new File( outputDirectory, daemon.getRepositoryName() + "/" + libFile ) );
613                 }
614                 else
615                 {
616                     copyResourceFile( new File( outputDirectory, daemon.getRepositoryName() ), JSW_LIB_DIR, libFile,
617                                       libFile );
618                 }
619             }
620             else
621             {
622                 getLogger().warn( "Lib file for " + platform + " not found in map." );
623             }
624         }
625     }
626 
627     private void writeExecutableFiles( File outputDirectory, Daemon daemon, List<String> jswPlatformIncludes )
628         throws DaemonGeneratorException
629     {
630         for ( String platform : jswPlatformIncludes )
631         {
632             String execFile = JSW_PLATFORMS_MAP.get( platform + "-exec" );
633             if ( execFile != null )
634             {
635                 String outputExecFile = execFile;
636                 if ( daemon.isUseDaemonIdAsWrapperExePrefixName() )
637                 {
638                     outputExecFile = StringUtils.replaceOnce( execFile, "wrapper", daemon.getId() );
639                 }
640 
641                 if ( daemon.getExternalDeltaPackDirectory() != null )
642                 {
643                     copyExternalFile( new File( daemon.getExternalDeltaPackDirectory(), JSW_BIN_DIR + "/" + execFile ),
644                                       new File( outputDirectory, JSW_BIN_DIR + "/" + outputExecFile ) );
645                 }
646                 else
647                 {
648                     copyResourceFile( new File( outputDirectory, JSW_BIN_DIR ), JSW_BIN_DIR, execFile, outputExecFile );
649                 }
650             }
651             else
652             {
653                 getLogger().warn( "Exec file for " + platform + " not found in map." );
654             }
655         }
656     }
657 
658     private void copyExternalFile( File from, File to )
659         throws DaemonGeneratorException
660     {
661         try
662         {
663             from.getParentFile().mkdirs();
664             FileUtils.copyFile( from, to );
665         }
666         catch ( IOException e )
667         {
668             throw new DaemonGeneratorException( "Could not copy external file: " + from, e );
669         }
670 
671     }
672 
673     private void copyResourceFile( File outputDirectory, String inputDirectory, String fileName, String outFileName )
674         throws DaemonGeneratorException
675     {
676         InputStream batchFileInputStream = this.getClass().getResourceAsStream( inputDirectory + "/" + fileName );
677 
678         if ( batchFileInputStream == null )
679         {
680             throw new DaemonGeneratorException( "Could not load library file: " + fileName );
681         }
682 
683         writeFile( new File( outputDirectory, outFileName ), batchFileInputStream );
684     }
685 
686     private List<String> getJswPlatformIncludes( Daemon daemon )
687     {
688         List<String> jswPlatformIncludes = null;
689         for ( GeneratorConfiguration generatorConfiguration : daemon.getGeneratorConfigurations() )
690         {
691             if ( generatorConfiguration.getGenerator().equals( "jsw" ) )
692             {
693                 jswPlatformIncludes = generatorConfiguration.getIncludes();
694             }
695         }
696 
697         // set default if none is specified
698         if ( jswPlatformIncludes == null || jswPlatformIncludes.isEmpty() )
699         {
700             jswPlatformIncludes = new ArrayList<String>();
701             jswPlatformIncludes.add( "aix-ppc-32" );
702             jswPlatformIncludes.add( "aix-ppc-64" );
703             jswPlatformIncludes.add( "linux-x86-32" );
704             jswPlatformIncludes.add( "macosx-x86-universal-32" );
705             jswPlatformIncludes.add( "solaris-x86-32" );
706             jswPlatformIncludes.add( "windows-x86-32" );
707         }
708 
709         return jswPlatformIncludes;
710     }
711 }