1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.codehaus.mojo.appassembler.daemon.jsw;
25
26 import java.io.File;
27 import java.io.FileOutputStream;
28 import java.io.FileWriter;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.InputStreamReader;
32 import java.io.Reader;
33 import java.util.ArrayList;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Properties;
39
40 import org.apache.maven.artifact.Artifact;
41 import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
42 import org.apache.maven.project.MavenProject;
43 import org.codehaus.mojo.appassembler.daemon.DaemonGenerationRequest;
44 import org.codehaus.mojo.appassembler.daemon.DaemonGenerator;
45 import org.codehaus.mojo.appassembler.daemon.DaemonGeneratorException;
46 import org.codehaus.mojo.appassembler.model.Daemon;
47 import org.codehaus.mojo.appassembler.model.Dependency;
48 import org.codehaus.mojo.appassembler.model.GeneratorConfiguration;
49 import org.codehaus.mojo.appassembler.util.FormattedProperties;
50 import org.codehaus.plexus.logging.AbstractLogEnabled;
51 import org.codehaus.plexus.util.IOUtil;
52 import org.codehaus.plexus.util.InterpolationFilterReader;
53 import org.codehaus.plexus.util.StringInputStream;
54 import org.codehaus.plexus.util.StringOutputStream;
55 import org.codehaus.plexus.util.StringUtils;
56
57
58
59
60
61
62 public class JavaServiceWrapperDaemonGenerator
63 extends AbstractLogEnabled
64 implements DaemonGenerator
65 {
66 private static final Map JSW_PLATFORMS_MAP = new HashMap ( ) {
67 {
68 put ( "linux-x86-32-lib", "lib/libwrapper-linux-x86-32.so" );
69 put ( "linux-x86-32-exec", "bin/wrapper-linux-x86-32" );
70 put ( "linux-x86-64-lib", "lib/libwrapper-linux-x86-64.so" );
71 put ( "linux-x86-64-exec", "bin/wrapper-linux-x86-64" );
72 put ( "linux-ppc-64-lib", "lib/libwrapper-linux-ppc-64.so" );
73 put ( "linux-ppc-64-exec", "bin/wrapper-linux-ppc-64" );
74 put ( "macosx-ppc-32-lib", "lib/libwrapper-macosx-ppc-32.jnilib" );
75 put ( "macosx-ppc-32-exec", "bin/wrapper-macosx-ppc-32" );
76 put ( "macosx-x86-universal-32-lib", "lib/libwrapper-macosx-universal-32.jnilib" );
77 put ( "macosx-x86-universal-32-exec", "bin/wrapper-macosx-universal-32" );
78 put ( "solaris-sparc-32-lib", "lib/libwrapper-solaris-sparc-32.so" );
79 put ( "solaris-sparc-32-exec", "bin/wrapper-solaris-sparc-32" );
80 put ( "solaris-sparc-64-lib", "lib/libwrapper-solaris-sparc-64.so" );
81 put ( "solaris-sparc-64-exec", "bin/wrapper-solaris-sparc-64" );
82 put ( "solaris-x86-32-lib", "lib/libwrapper-solaris-x86-32.so" );
83 put ( "solaris-x86-32-exec", "bin/wrapper-solaris-x86-32" );
84 put ( "windows-x86-32-lib", "lib/wrapper-windows-x86-32.dll" );
85 put ( "windows-x86-32-exec", "bin/wrapper-windows-x86-32.exe" );
86 }
87 };
88
89
90
91
92
93 public void generate ( DaemonGenerationRequest request )
94 throws DaemonGeneratorException
95 {
96 Daemon daemon = request.getDaemon ( );
97
98 File outputDirectory = new File ( request.getOutputDirectory ( ), daemon.getId ( ) );
99
100 Properties configuration = createConfiguration ( daemon );
101
102
103 String appBaseEnvVar = configuration.getProperty ( "app.base.envvar", "APP_BASE" );
104 configuration.remove ( "app.base.envvar" );
105 String runAsUserEnvVar = configuration.getProperty ( "run.as.user.envvar", "" );
106 if ( !runAsUserEnvVar.equals ( "" ) )
107 {
108 runAsUserEnvVar = "RUN_AS_USER=" + runAsUserEnvVar;
109 configuration.remove ( "run.as.user.envvar" );
110 }
111
112 Properties context = createContext ( request, daemon );
113 context.setProperty ( "app.base.envvar", appBaseEnvVar );
114 context.setProperty ( "run.as.user.envvar", runAsUserEnvVar );
115
116 writeWrapperConfFile ( request, daemon, outputDirectory, context, configuration );
117
118 writeScriptFiles ( request, daemon, outputDirectory, context );
119
120 List jswPlatformIncludes = getJswPlatformIncludes ( daemon );
121
122 writeLibraryFiles ( outputDirectory, jswPlatformIncludes );
123
124 writeExecutableFiles ( outputDirectory, jswPlatformIncludes );
125 }
126
127 private void writeWrapperConfFile ( DaemonGenerationRequest request, Daemon daemon, File outputDirectory,
128 Properties context, Properties configuration )
129 throws DaemonGeneratorException
130 {
131 InputStream in = this.getClass ( ).getResourceAsStream ( "conf/wrapper.conf.in" );
132
133 if ( in == null )
134 {
135 throw new DaemonGeneratorException ( "Could not load template." );
136 }
137
138 FormattedProperties confFile = new FormattedProperties ( );
139
140 try
141 {
142 confFile.read ( in );
143 }
144 catch ( IOException e )
145 {
146 throw new DaemonGeneratorException ( "Error reading template: " + e.getMessage ( ), e );
147 }
148 finally
149 {
150 IOUtil.close ( in );
151 }
152
153
154 confFile.setPropertyAfter ( "wrapper.working.dir", "..", "wrapper.java.command" );
155 confFile.setProperty ( "wrapper.java.library.path.1", "lib" );
156
157 confFile.setPropertyAfter ( "set.default.REPO_DIR", "lib", "wrapper.java.mainclass" );
158 confFile.setPropertyAfter ( "set.default." + context.getProperty ( "app.base.envvar" ), ".",
159 "wrapper.java.mainclass" );
160
161 if ( daemon.getWrapperLogFile ( ) == null )
162 {
163
164 confFile.setProperty ( "wrapper.logfile", "../logs/wrapper.log" );
165 }
166 else
167 {
168 confFile.setProperty ( "wrapper.logfile", daemon.getWrapperLogFile ( ) );
169 }
170
171 if ( daemon.getJvmSettings ( ) != null
172 && !StringUtils.isEmpty ( daemon.getJvmSettings ( ).getInitialMemorySize ( ) ) )
173 {
174 confFile.setProperty ( "wrapper.java.initmemory", daemon.getJvmSettings ( ).getInitialMemorySize ( ) );
175 }
176
177 if ( daemon.getJvmSettings ( ) != null
178 && !StringUtils.isEmpty ( daemon.getJvmSettings ( ).getMaxMemorySize ( ) ) )
179 {
180 confFile.setProperty ( "wrapper.java.maxmemory", daemon.getJvmSettings ( ).getMaxMemorySize ( ) );
181 }
182
183 confFile.setProperty ( "wrapper.app.parameter.1", daemon.getMainClass ( ) );
184
185 createClasspath ( request, confFile, configuration );
186 createAdditional ( daemon, confFile );
187 createParameters ( daemon, confFile );
188
189 for ( Iterator i = configuration.entrySet ( ).iterator ( ); i.hasNext ( ); )
190 {
191 Map.Entry entry = ( Map.Entry ) i.next ( );
192
193 String key = ( String ) entry.getKey ( );
194 String value = ( String ) entry.getValue ( );
195 if ( value.length ( ) > 0 )
196 {
197 confFile.setProperty ( key, value );
198 }
199 else
200 {
201 confFile.removeProperty ( key );
202 }
203 }
204
205 StringOutputStream string = new StringOutputStream ( );
206 confFile.save ( string );
207
208 Reader reader = new InputStreamReader ( new StringInputStream ( string.toString ( ) ) );
209
210 writeFilteredFile ( request, daemon, reader, new File ( outputDirectory, "conf/wrapper.conf" ), context );
211 }
212
213 private Properties createConfiguration ( Daemon daemon )
214 {
215 Properties configuration = new Properties ( );
216
217 for ( Iterator i = daemon.getGeneratorConfigurations ( ).iterator ( ); i.hasNext ( ); )
218 {
219 GeneratorConfiguration generatorConfiguration = ( GeneratorConfiguration ) i.next ( );
220
221 if ( generatorConfiguration.getGenerator ( ).equals ( "jsw" ) )
222 {
223 configuration.putAll ( generatorConfiguration.getConfiguration ( ) );
224 }
225 }
226 return configuration;
227 }
228
229 private static void writeFilteredFile ( DaemonGenerationRequest request, Daemon daemon, Reader reader,
230 File outputFile, Map context )
231 throws DaemonGeneratorException
232 {
233 InterpolationFilterReader interpolationFilterReader =
234 new InterpolationFilterReader ( reader, context, "@", "@" );
235
236 writeFile ( outputFile, interpolationFilterReader );
237 }
238
239 private static Properties createContext ( DaemonGenerationRequest request, Daemon daemon )
240 {
241 Properties context = new Properties ( );
242 context.setProperty ( "app.long.name", request.getMavenProject ( ).getName ( ) );
243 context.setProperty ( "app.name", daemon.getId ( ) );
244 String description = request.getMavenProject ( ).getDescription ( );
245 if ( description == null )
246 {
247 description = request.getMavenProject ( ).getName ( );
248 }
249 context.setProperty ( "app.description", description );
250 return context;
251 }
252
253 private static void writeFile ( File outputFile, Reader reader )
254 throws DaemonGeneratorException
255 {
256 FileWriter out = null;
257
258 try
259 {
260 outputFile.getParentFile ( ).mkdirs ( );
261 out = new FileWriter ( outputFile );
262
263 IOUtil.copy ( reader, out );
264 }
265 catch ( IOException e )
266 {
267 throw new DaemonGeneratorException ( "Error writing output file: " + outputFile.getAbsolutePath ( ), e );
268 }
269 finally
270 {
271 IOUtil.close ( reader );
272 IOUtil.close ( out );
273 }
274 }
275
276 private static void writeFile ( File outputFile, InputStream inputStream )
277 throws DaemonGeneratorException
278 {
279 FileOutputStream out = null;
280
281 try
282 {
283 outputFile.getParentFile ( ).mkdirs ( );
284 out = new FileOutputStream ( outputFile );
285
286 IOUtil.copy ( inputStream, out );
287 }
288 catch ( IOException e )
289 {
290 throw new DaemonGeneratorException ( "Error writing output file: " + outputFile.getAbsolutePath ( ), e );
291 }
292 finally
293 {
294 IOUtil.close ( inputStream );
295 IOUtil.close ( out );
296 }
297 }
298
299 private static void createClasspath ( DaemonGenerationRequest request, FormattedProperties confFile,
300 Properties configuration )
301 {
302 final String wrapperClassPathPrefix = "wrapper.java.classpath.";
303
304 int counter = 1;
305 confFile.setProperty ( wrapperClassPathPrefix + counter++, "lib/wrapper.jar" );
306
307 String configurationDirFirst = configuration.getProperty ( "configuration.directory.in.classpath.first" );
308 if ( configurationDirFirst != null )
309 {
310 confFile.setProperty ( wrapperClassPathPrefix + counter++, configurationDirFirst );
311 }
312
313 MavenProject project = request.getMavenProject ( );
314 ArtifactRepositoryLayout layout = request.getRepositoryLayout ( );
315
316 confFile.setProperty ( wrapperClassPathPrefix + counter++, "%REPO_DIR%/"
317 + createDependency ( layout, project.getArtifact ( ) ).getRelativePath ( ) );
318
319 Iterator j = project.getRuntimeArtifacts ( ).iterator ( );
320 while ( j.hasNext ( ) )
321 {
322 Artifact artifact = ( Artifact ) j.next ( );
323
324 confFile.setProperty ( wrapperClassPathPrefix + counter, "%REPO_DIR%/"
325 + createDependency ( layout, artifact ).getRelativePath ( ) );
326 counter++;
327 }
328
329 String configurationDirLast = configuration.getProperty ( "configuration.directory.in.classpath.last" );
330 if ( configurationDirLast != null )
331 {
332 confFile.setProperty ( wrapperClassPathPrefix + counter++, configurationDirLast );
333 }
334 }
335
336 private static Dependency createDependency ( ArtifactRepositoryLayout layout, Artifact artifact )
337 {
338 Dependency dependency = new Dependency ( );
339 dependency.setArtifactId ( artifact.getArtifactId ( ) );
340 dependency.setGroupId ( artifact.getGroupId ( ) );
341 dependency.setVersion ( artifact.getVersion ( ) );
342 dependency.setRelativePath ( layout.pathOf ( artifact ) );
343 return dependency;
344 }
345
346 private static void createAdditional ( Daemon daemon, FormattedProperties confFile )
347 {
348 if ( daemon.getJvmSettings ( ) != null )
349 {
350 int count = 1;
351 for ( Iterator i = daemon.getJvmSettings ( ).getSystemProperties ( ).iterator ( ); i.hasNext ( ); count++ )
352 {
353 String systemProperty = ( String ) i.next ( );
354 confFile.setProperty ( "wrapper.java.additional." + count, "-D" + systemProperty );
355 }
356 for ( Iterator i = daemon.getJvmSettings ( ).getExtraArguments ( ).iterator ( ); i.hasNext ( ); count++ )
357 {
358 String extraArgument = ( String ) i.next ( );
359 confFile.setProperty ( "wrapper.java.additional." + count, extraArgument );
360 }
361 }
362 }
363
364 private static void createParameters ( Daemon daemon, FormattedProperties confFile )
365 {
366 int count = 2;
367 for ( Iterator i = daemon.getCommandLineArguments ( ).iterator ( ); i.hasNext ( ); count++ )
368 {
369 String argument = ( String ) i.next ( );
370
371 confFile.setProperty ( "wrapper.app.parameter." + count, argument );
372 }
373 }
374
375 private void writeScriptFiles ( DaemonGenerationRequest request, Daemon daemon, File outputDirectory,
376 Properties context )
377 throws DaemonGeneratorException
378 {
379
380 InputStream shellScriptInputStream = this.getClass ( ).getResourceAsStream ( "bin/sh.script.in" );
381
382 if ( shellScriptInputStream == null )
383 {
384 throw new DaemonGeneratorException ( "Could not load template." );
385 }
386
387 Reader reader = new InputStreamReader ( shellScriptInputStream );
388
389 writeFilteredFile ( request, daemon, reader, new File ( outputDirectory, "bin/" + daemon.getId ( ) ), context );
390
391
392 InputStream batchFileInputStream = this.getClass ( ).getResourceAsStream ( "bin/AppCommand.bat.in" );
393
394 if ( batchFileInputStream == null )
395 {
396 throw new DaemonGeneratorException ( "Could not load template." );
397 }
398
399 writeFile ( new File ( outputDirectory, "bin/" + daemon.getId ( ) + ".bat" ),
400 batchFileInputStream );
401 }
402
403 private void writeLibraryFiles ( File outputDirectory, List jswPlatformIncludes )
404 throws DaemonGeneratorException
405 {
406 copyResourceFile ( outputDirectory, "lib/wrapper.jar" );
407
408 for ( Iterator iter = jswPlatformIncludes.iterator ( ); iter.hasNext ( ); )
409 {
410 String platform = ( String ) iter.next ( );
411 String libFile = ( String ) JSW_PLATFORMS_MAP.get ( platform + "-lib" );
412 if ( libFile != null )
413 {
414 copyResourceFile ( outputDirectory, libFile );
415 }
416 else
417 {
418 getLogger ( ).warn ( "Lib file for " + platform + " not found in map." );
419 }
420 }
421 }
422
423 private void writeExecutableFiles ( File outputDirectory, List jswPlatformIncludes )
424 throws DaemonGeneratorException
425 {
426 for ( Iterator iter = jswPlatformIncludes.iterator ( ); iter.hasNext ( ); )
427 {
428 String platform = ( String ) iter.next ( );
429 String execFile = ( String ) JSW_PLATFORMS_MAP.get ( platform + "-exec" );
430 if ( execFile != null )
431 {
432 copyResourceFile ( outputDirectory, execFile );
433 }
434 else
435 {
436 getLogger ( ).warn ( "Exec file for " + platform + " not found in map." );
437 }
438 }
439 }
440
441 private void copyResourceFile ( File outputDirectory, String fileName )
442 throws DaemonGeneratorException
443 {
444 InputStream batchFileInputStream = this.getClass ( ).getResourceAsStream ( fileName );
445
446 if ( batchFileInputStream == null )
447 {
448 throw new DaemonGeneratorException ( "Could not load library file: " + fileName );
449 }
450
451 writeFile ( new File ( outputDirectory, fileName ), batchFileInputStream );
452 }
453
454 private List getJswPlatformIncludes ( Daemon daemon )
455 {
456 List jswPlatformIncludes = null;
457 for ( Iterator i = daemon.getGeneratorConfigurations ( ).iterator ( ); i.hasNext ( ); )
458 {
459 GeneratorConfiguration generatorConfiguration = ( GeneratorConfiguration ) i.next ( );
460
461 if ( generatorConfiguration.getGenerator ( ).equals ( "jsw" ) )
462 {
463 jswPlatformIncludes = generatorConfiguration.getIncludes ( );
464 }
465 }
466
467
468 if ( jswPlatformIncludes == null || jswPlatformIncludes.isEmpty ( ) )
469 {
470 jswPlatformIncludes = new ArrayList ( );
471 jswPlatformIncludes.add ( "linux-x86-32" );
472 jswPlatformIncludes.add ( "macosx-x86-universal-32" );
473 jswPlatformIncludes.add ( "solaris-x86-32" );
474 jswPlatformIncludes.add ( "windows-x86-32" );
475 }
476
477 return jswPlatformIncludes;
478 }
479 }