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