1 package org.apache.maven.archetype.old;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.archetype.ArchetypeGenerationRequest;
23 import org.apache.maven.archetype.old.descriptor.ArchetypeDescriptor;
24 import org.apache.maven.archetype.old.descriptor.ArchetypeDescriptorBuilder;
25 import org.apache.maven.archetype.old.descriptor.TemplateDescriptor;
26 import org.apache.maven.artifact.repository.ArtifactRepository;
27 import org.apache.maven.archetype.common.ArchetypeArtifactManager;
28 import org.apache.maven.archetype.common.Constants;
29 import org.apache.maven.archetype.exception.UnknownArchetype;
30 import org.apache.maven.model.Build;
31 import org.apache.maven.model.Model;
32 import org.apache.maven.model.Parent;
33 import org.apache.maven.model.Resource;
34 import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
35 import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
36 import org.apache.velocity.VelocityContext;
37 import org.apache.velocity.context.Context;
38 import org.codehaus.plexus.logging.AbstractLogEnabled;
39 import org.codehaus.plexus.util.FileUtils;
40 import org.codehaus.plexus.util.IOUtil;
41 import org.codehaus.plexus.util.ReaderFactory;
42 import org.codehaus.plexus.util.StringUtils;
43 import org.codehaus.plexus.util.WriterFactory;
44 import org.codehaus.plexus.util.xml.XmlStreamReader;
45 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
46 import org.codehaus.plexus.velocity.VelocityComponent;
47 import org.dom4j.Document;
48 import org.dom4j.DocumentException;
49 import org.dom4j.Element;
50 import org.dom4j.Node;
51 import org.dom4j.io.SAXReader;
52 import org.dom4j.io.XMLWriter;
53
54 import java.io.File;
55 import java.io.FileOutputStream;
56 import java.io.IOException;
57 import java.io.InputStream;
58 import java.io.OutputStream;
59 import java.io.OutputStreamWriter;
60 import java.io.Reader;
61 import java.io.StringWriter;
62 import java.io.Writer;
63 import java.net.URL;
64 import java.net.URLClassLoader;
65 import java.util.HashMap;
66 import java.util.Iterator;
67 import java.util.Map;
68
69
70
71
72
73
74 public class DefaultOldArchetype
75 extends AbstractLogEnabled
76 implements OldArchetype
77 {
78 private static final String DEFAULT_TEST_RESOURCE_DIR = "/src/test/resources";
79
80 private static final String DEFAULT_TEST_SOURCE_DIR = "/src/test/java";
81
82 private static final String DEFAULT_RESOURCE_DIR = "/src/main/resources";
83
84 private static final String DEFAULT_SOURCE_DIR = "/src/main/java";
85
86
87
88
89
90
91
92
93 private VelocityComponent velocity;
94
95
96 private ArchetypeArtifactManager archetypeArtifactManager;
97
98
99
100
101
102
103
104
105
106 public void createArchetype( ArchetypeGenerationRequest request, ArtifactRepository archetypeRepository )
107 throws UnknownArchetype, ArchetypeNotFoundException, ArchetypeDescriptorException,
108 ArchetypeTemplateProcessingException
109 {
110
111
112
113
114 File archetypeFile = archetypeArtifactManager.getArchetypeFile(
115 request.getArchetypeGroupId(), request.getArchetypeArtifactId(), request.getArchetypeVersion(),
116 archetypeRepository, request.getLocalRepository(), request.getRemoteArtifactRepositories() );
117
118 createArchetype( request, archetypeFile );
119 }
120
121 public void createArchetype( ArchetypeGenerationRequest request, File archetypeFile )
122 throws ArchetypeDescriptorException, ArchetypeTemplateProcessingException
123 {
124 Map<String, String> parameters = new HashMap<String, String>();
125
126 parameters.put( "basedir", request.getOutputDirectory() );
127
128 parameters.put( Constants.PACKAGE, request.getPackage() );
129
130 parameters.put( "packageName", request.getPackage() );
131
132 parameters.put( Constants.GROUP_ID, request.getGroupId() );
133
134 parameters.put( Constants.ARTIFACT_ID, request.getArtifactId() );
135
136 parameters.put( Constants.VERSION, request.getVersion() );
137
138
139
140
141 if ( getLogger().isInfoEnabled() )
142 {
143 getLogger().info( "----------------------------------------------------------------------------" );
144
145 getLogger().info( "Using following parameters for creating project from Old (1.x) Archetype: "
146 + request.getArchetypeArtifactId() + ":" + request.getArchetypeVersion() );
147
148 getLogger().info( "----------------------------------------------------------------------------" );
149
150 for ( Map.Entry<String, String> entry : parameters.entrySet() )
151 {
152 String parameterName = entry.getKey();
153
154 String parameterValue = entry.getValue();
155
156 getLogger().info( "Parameter: " + parameterName + ", Value: " + parameterValue );
157 }
158 }
159
160
161
162
163
164 ArchetypeDescriptorBuilder builder = new ArchetypeDescriptorBuilder();
165
166 ArchetypeDescriptor descriptor;
167
168 URLClassLoader archetypeJarLoader;
169
170 InputStream is = null;
171
172 try
173 {
174 URL[] urls = new URL[1];
175
176 urls[0] = archetypeFile.toURL();
177
178 archetypeJarLoader = new URLClassLoader( urls );
179
180 is = getStream( ARCHETYPE_DESCRIPTOR, archetypeJarLoader );
181
182 if ( is == null )
183 {
184 is = getStream( ARCHETYPE_OLD_DESCRIPTOR, archetypeJarLoader );
185 }
186
187 if ( is == null )
188 {
189 throw new ArchetypeDescriptorException( "The " + ARCHETYPE_DESCRIPTOR + " descriptor cannot be found." );
190 }
191
192 descriptor = builder.build( new XmlStreamReader( is ) );
193 }
194 catch ( IOException e )
195 {
196 throw new ArchetypeDescriptorException( "Error reading the " + ARCHETYPE_DESCRIPTOR + " descriptor.", e );
197 }
198 catch ( XmlPullParserException e )
199 {
200 throw new ArchetypeDescriptorException( "Error reading the " + ARCHETYPE_DESCRIPTOR + " descriptor.", e );
201 }
202 finally
203 {
204 IOUtil.close( is );
205 }
206
207
208
209
210
211 String artifactId = request.getArtifactId();
212
213 File parentPomFile = new File( request.getOutputDirectory(), ARCHETYPE_POM );
214
215 File outputDirectoryFile;
216
217 boolean creating;
218 File pomFile;
219 if ( parentPomFile.exists() && descriptor.isAllowPartial() && artifactId == null )
220 {
221 outputDirectoryFile = new File( request.getOutputDirectory() );
222 creating = false;
223 pomFile = parentPomFile;
224 }
225 else
226 {
227 if ( artifactId == null )
228 {
229 throw new ArchetypeTemplateProcessingException(
230 "Artifact ID must be specified when creating a new project from an archetype." );
231 }
232
233 outputDirectoryFile = new File( request.getOutputDirectory(), artifactId );
234 creating = true;
235
236 if ( outputDirectoryFile.exists() )
237 {
238 if ( descriptor.isAllowPartial() )
239 {
240 creating = false;
241 }
242 else
243 {
244 throw new ArchetypeTemplateProcessingException( "Directory "
245 + outputDirectoryFile.getName() + " already exists - please run from a clean directory" );
246 }
247 }
248
249 pomFile = new File( outputDirectoryFile, ARCHETYPE_POM );
250 }
251
252 if ( creating )
253 {
254 if ( request.getGroupId() == null )
255 {
256 throw new ArchetypeTemplateProcessingException(
257 "Group ID must be specified when creating a new project from an archetype." );
258 }
259
260 if ( request.getVersion() == null )
261 {
262 throw new ArchetypeTemplateProcessingException(
263 "Version must be specified when creating a new project from an archetype." );
264 }
265 }
266
267 String outputDirectory = outputDirectoryFile.getAbsolutePath();
268
269 String packageName = request.getPackage();
270
271
272
273
274
275 Context context = new VelocityContext();
276
277 context.put( Constants.PACKAGE, packageName );
278
279 for ( Map.Entry<String, String> entry : parameters.entrySet() )
280 {
281 context.put( entry.getKey(), entry.getValue() );
282 }
283
284
285
286
287
288 ClassLoader old = Thread.currentThread().getContextClassLoader();
289
290 Thread.currentThread().setContextClassLoader( archetypeJarLoader );
291
292 Model parentModel = null;
293 if ( creating )
294 {
295 if ( parentPomFile.exists() )
296 {
297 Reader fileReader = null;
298
299 try
300 {
301 fileReader = ReaderFactory.newXmlReader( parentPomFile );
302 MavenXpp3Reader reader = new MavenXpp3Reader();
303 parentModel = reader.read( fileReader );
304 if ( !"pom".equals( parentModel.getPackaging() ) )
305 {
306 throw new ArchetypeTemplateProcessingException(
307 "Unable to add module to the current project as it is not of packaging type 'pom'" );
308 }
309 }
310 catch ( IOException e )
311 {
312 throw new ArchetypeTemplateProcessingException( "Unable to read parent POM", e );
313 }
314 catch ( XmlPullParserException e )
315 {
316 throw new ArchetypeTemplateProcessingException( "Unable to read parent POM", e );
317 }
318 finally
319 {
320 IOUtil.close( fileReader );
321 }
322
323 parentModel.getModules().add( artifactId );
324 }
325 }
326
327 try
328 {
329 processTemplates( pomFile, outputDirectory, context, descriptor, packageName, parentModel );
330 }
331 finally
332 {
333 Thread.currentThread().setContextClassLoader( old );
334 }
335
336 if ( parentModel != null )
337 {
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359 Reader fileReader = null;
360 boolean added;
361 StringWriter w = new StringWriter();
362 try
363 {
364 fileReader = ReaderFactory.newXmlReader( parentPomFile );
365 added = addModuleToParentPom( artifactId, fileReader, w );
366 }
367 catch ( IOException e )
368 {
369 throw new ArchetypeTemplateProcessingException( "Unable to rewrite parent POM", e );
370 }
371 catch ( DocumentException e )
372 {
373 throw new ArchetypeTemplateProcessingException( "Unable to rewrite parent POM", e );
374 }
375 finally
376 {
377 IOUtil.close( fileReader );
378 }
379
380 if ( added )
381 {
382 Writer out = null;
383 try
384 {
385 out = WriterFactory.newXmlWriter( parentPomFile );
386 IOUtil.copy( w.toString(), out );
387 }
388 catch ( IOException e )
389 {
390 throw new ArchetypeTemplateProcessingException( "Unable to rewrite parent POM", e );
391 }
392 finally
393 {
394 IOUtil.close( out );
395 }
396 }
397 }
398
399
400
401
402 if ( getLogger().isInfoEnabled() )
403 {
404 getLogger().info( "project created from Old (1.x) Archetype in dir: " + outputDirectory );
405 }
406
407 }
408
409 static boolean addModuleToParentPom( String artifactId, Reader fileReader, Writer fileWriter )
410 throws DocumentException, IOException, ArchetypeTemplateProcessingException
411 {
412 SAXReader reader = new SAXReader();
413 Document document = reader.read( fileReader );
414 Element project = document.getRootElement();
415
416 String packaging = null;
417 Element packagingElement = project.element( "packaging" );
418 if ( packagingElement != null )
419 {
420 packaging = packagingElement.getStringValue();
421 }
422 if ( !"pom".equals( packaging ) )
423 {
424 throw new ArchetypeTemplateProcessingException(
425 "Unable to add module to the current project as it is not of packaging type 'pom'" );
426 }
427
428 Element modules = project.element( "modules" );
429 if ( modules == null )
430 {
431 modules = project.addText( " " ).addElement( "modules" );
432 modules.setText( "\n " );
433 project.addText( "\n" );
434 }
435 boolean found = false;
436 for ( Iterator<?> i = modules.elementIterator( "module" ); i.hasNext() && !found; )
437 {
438 Element module = (Element) i.next();
439 if ( module.getText().equals( artifactId ) )
440 {
441 found = true;
442 }
443 }
444 if ( !found )
445 {
446 Node lastTextNode = null;
447 for ( Iterator<?> i = modules.nodeIterator(); i.hasNext(); )
448 {
449 Node node = (Node) i.next();
450 if ( node.getNodeType() == Node.ELEMENT_NODE )
451 {
452 lastTextNode = null;
453 }
454 else if ( node.getNodeType() == Node.TEXT_NODE )
455 {
456 lastTextNode = node;
457 }
458 }
459
460 if ( lastTextNode != null )
461 {
462 modules.remove( lastTextNode );
463 }
464
465 modules.addText( "\n " );
466 modules.addElement( "module" ).setText( artifactId );
467 modules.addText( "\n " );
468
469 XMLWriter writer = new XMLWriter( fileWriter );
470 writer.write( document );
471 }
472 return !found;
473 }
474
475 private void processTemplates( File pomFile, String outputDirectory, Context context,
476 ArchetypeDescriptor descriptor, String packageName, Model parentModel )
477 throws ArchetypeTemplateProcessingException
478 {
479 if ( !pomFile.exists() )
480 {
481 processTemplate( outputDirectory, context, ARCHETYPE_POM, new TemplateDescriptor(), false, null );
482 }
483
484
485
486
487
488 Model generatedModel;
489 Reader pomReader = null;
490 try
491 {
492 pomReader = ReaderFactory.newXmlReader( pomFile );
493
494 MavenXpp3Reader reader = new MavenXpp3Reader();
495
496 generatedModel = reader.read( pomReader );
497 }
498 catch ( IOException e )
499 {
500 throw new ArchetypeTemplateProcessingException( "Error reading POM", e );
501 }
502 catch ( XmlPullParserException e )
503 {
504 throw new ArchetypeTemplateProcessingException( "Error reading POM", e );
505 }
506 finally
507 {
508 IOUtil.close( pomReader );
509 }
510
511 if ( parentModel != null )
512 {
513 Parent parent = new Parent();
514 parent.setGroupId( parentModel.getGroupId() );
515 if ( parent.getGroupId() == null )
516 {
517 parent.setGroupId( parentModel.getParent().getGroupId() );
518 }
519 parent.setArtifactId( parentModel.getArtifactId() );
520 parent.setVersion( parentModel.getVersion() );
521 if ( parent.getVersion() == null )
522 {
523 parent.setVersion( parentModel.getParent().getVersion() );
524 }
525 generatedModel.setParent( parent );
526
527 Writer pomWriter = null;
528 try
529 {
530 pomWriter = WriterFactory.newXmlWriter( pomFile );
531
532 MavenXpp3Writer writer = new MavenXpp3Writer();
533 writer.write( pomWriter, generatedModel );
534 }
535 catch ( IOException e )
536 {
537 throw new ArchetypeTemplateProcessingException( "Error rewriting POM", e );
538 }
539 finally
540 {
541 IOUtil.close( pomWriter );
542 }
543 }
544
545
546
547
548 Build build = generatedModel.getBuild();
549
550 boolean overrideSrcDir = false;
551
552 boolean overrideResourceDir = false;
553
554 boolean overrideTestSrcDir = false;
555
556 boolean overrideTestResourceDir = false;
557
558 boolean foundBuildElement = build != null;
559
560 if ( getLogger().isDebugEnabled() )
561 {
562 getLogger().debug(
563 "********************* Debug info for resources created from generated Model ***********************" );
564 getLogger().debug( "Was build element found in generated POM?: " + foundBuildElement );
565 }
566
567
568 if ( foundBuildElement && null != build.getSourceDirectory() )
569 {
570 getLogger().debug( "Overriding default source directory " );
571
572 overrideSrcDir = true;
573
574 String srcDirectory = build.getSourceDirectory();
575
576 srcDirectory = StringUtils.replace( srcDirectory, "\\", "/" );
577
578 FileUtils.mkdir( getOutputDirectory( outputDirectory, srcDirectory ) );
579 }
580
581
582 if ( foundBuildElement && null != build.getScriptSourceDirectory() )
583 {
584 getLogger().debug( "Overriding default script source directory " );
585
586 String scriptSourceDirectory = build.getScriptSourceDirectory();
587
588 scriptSourceDirectory = StringUtils.replace( scriptSourceDirectory, "\\", "/" );
589
590 FileUtils.mkdir( getOutputDirectory( outputDirectory, scriptSourceDirectory ) );
591 }
592
593
594 if ( foundBuildElement && build.getResources().size() > 0 )
595 {
596 getLogger().debug( "Overriding default resource directory " );
597
598 overrideResourceDir = true;
599
600 Iterator<?> resourceItr = build.getResources().iterator();
601
602 while ( resourceItr.hasNext() )
603 {
604 Resource resource = (Resource) resourceItr.next();
605
606 String resourceDirectory = resource.getDirectory();
607
608 resourceDirectory = StringUtils.replace( resourceDirectory, "\\", "/" );
609
610 FileUtils.mkdir( getOutputDirectory( outputDirectory, resourceDirectory ) );
611 }
612 }
613
614 if ( foundBuildElement && null != build.getTestSourceDirectory() )
615 {
616 getLogger().debug( "Overriding default test directory " );
617
618 overrideTestSrcDir = true;
619
620 String testDirectory = build.getTestSourceDirectory();
621
622 testDirectory = StringUtils.replace( testDirectory, "\\", "/" );
623
624 FileUtils.mkdir( getOutputDirectory( outputDirectory, testDirectory ) );
625 }
626
627
628 if ( foundBuildElement && build.getTestResources().size() > 0 )
629 {
630 getLogger().debug( "Overriding default test resource directory " );
631
632 overrideTestResourceDir = true;
633
634 Iterator<?> testResourceItr = build.getTestResources().iterator();
635
636 while ( testResourceItr.hasNext() )
637 {
638 Resource resource = (Resource) testResourceItr.next();
639
640 String testResourceDirectory = resource.getDirectory();
641
642 testResourceDirectory = StringUtils.replace( testResourceDirectory, "\\", "/" );
643
644 FileUtils.mkdir( getOutputDirectory( outputDirectory, testResourceDirectory ) );
645 }
646 }
647
648 getLogger().debug(
649 "********************* End of debug info from resources from generated POM ***********************" );
650
651
652
653
654
655 if ( descriptor.getSources().size() > 0 )
656 {
657 if ( !overrideSrcDir )
658 {
659 FileUtils.mkdir( outputDirectory + DEFAULT_SOURCE_DIR );
660 processSources( outputDirectory, context, descriptor, packageName, DEFAULT_SOURCE_DIR );
661 }
662 else
663 {
664 processSources( outputDirectory, context, descriptor, packageName, build.getSourceDirectory() );
665 }
666 }
667
668 if ( descriptor.getResources().size() > 0 )
669 {
670 if ( !overrideResourceDir )
671 {
672 FileUtils.mkdir( outputDirectory + DEFAULT_RESOURCE_DIR );
673 }
674 processResources( outputDirectory, context, descriptor, packageName );
675 }
676
677
678
679
680
681 if ( descriptor.getTestSources().size() > 0 )
682 {
683 if ( !overrideTestSrcDir )
684 {
685 FileUtils.mkdir( outputDirectory + DEFAULT_TEST_SOURCE_DIR );
686 processTestSources( outputDirectory, context, descriptor, packageName, DEFAULT_TEST_SOURCE_DIR );
687 }
688 else
689 {
690 processTestSources( outputDirectory, context, descriptor, packageName, build.getTestSourceDirectory() );
691 }
692 }
693
694 if ( descriptor.getTestResources().size() > 0 )
695 {
696 if ( !overrideTestResourceDir )
697 {
698 FileUtils.mkdir( outputDirectory + DEFAULT_TEST_RESOURCE_DIR );
699 }
700 processTestResources( outputDirectory, context, descriptor, packageName );
701 }
702
703
704
705
706
707 if ( descriptor.getSiteResources().size() > 0 )
708 {
709 processSiteResources( outputDirectory, context, descriptor, packageName );
710 }
711 }
712
713 private void processTemplate( String outputDirectory, Context context, String template,
714 TemplateDescriptor descriptor, boolean packageInFileName, String packageName )
715 throws ArchetypeTemplateProcessingException
716 {
717 processTemplate( outputDirectory, context, template, descriptor, packageInFileName, packageName, null );
718 }
719
720 private String getOutputDirectory( String outputDirectory, String testResourceDirectory )
721 {
722 return outputDirectory
723 + ( testResourceDirectory.startsWith( "/" ) ? testResourceDirectory : "/" + testResourceDirectory );
724 }
725
726
727
728
729
730 protected void processSources( String outputDirectory, Context context, ArchetypeDescriptor descriptor,
731 String packageName, String sourceDirectory )
732 throws ArchetypeTemplateProcessingException
733 {
734 for ( String template : descriptor.getSources() )
735 {
736 processTemplate( outputDirectory, context, template, descriptor.getSourceDescriptor( template ), true,
737 packageName, sourceDirectory );
738 }
739 }
740
741 protected void processTestSources( String outputDirectory, Context context, ArchetypeDescriptor descriptor,
742 String packageName, String testSourceDirectory )
743 throws ArchetypeTemplateProcessingException
744 {
745 for ( String template : descriptor.getTestSources() )
746 {
747 processTemplate( outputDirectory, context, template, descriptor.getTestSourceDescriptor( template ), true,
748 packageName, testSourceDirectory );
749 }
750 }
751
752 protected void processResources( String outputDirectory, Context context, ArchetypeDescriptor descriptor,
753 String packageName )
754 throws ArchetypeTemplateProcessingException
755 {
756 for ( String template : descriptor.getResources() )
757 {
758 processTemplate( outputDirectory, context, template, descriptor.getResourceDescriptor( template ), false,
759 packageName );
760 }
761 }
762
763 protected void processTestResources( String outputDirectory, Context context, ArchetypeDescriptor descriptor,
764 String packageName )
765 throws ArchetypeTemplateProcessingException
766 {
767 for ( String template : descriptor.getTestResources() )
768 {
769 processTemplate( outputDirectory, context, template, descriptor.getTestResourceDescriptor( template ),
770 false, packageName );
771 }
772 }
773
774 protected void processSiteResources( String outputDirectory, Context context, ArchetypeDescriptor descriptor,
775 String packageName )
776 throws ArchetypeTemplateProcessingException
777 {
778 for ( String template : descriptor.getSiteResources() )
779 {
780 processTemplate( outputDirectory, context, template, descriptor.getSiteResourceDescriptor( template ),
781 false, packageName );
782 }
783 }
784
785 protected void processTemplate( String outputDirectory, Context context, String template,
786 TemplateDescriptor descriptor, boolean packageInFileName, String packageName,
787 String sourceDirectory )
788 throws ArchetypeTemplateProcessingException
789 {
790 File f;
791
792 template = StringUtils.replace( template, "\\", "/" );
793
794 if ( packageInFileName && packageName != null )
795 {
796 String templateFileName = StringUtils.replace( template, "/", File.separator );
797
798 String path = packageName.replace( '.', '/' );
799
800 String filename = FileUtils.filename( templateFileName );
801
802 String dirname = FileUtils.dirname( templateFileName ).replace( '\\', '/' );
803
804 sourceDirectory = sourceDirectory.replace( '\\', '/' );
805 if ( sourceDirectory.startsWith( "/" ) )
806 {
807 sourceDirectory = sourceDirectory.substring( 1 );
808 }
809
810 if ( !dirname.startsWith( sourceDirectory ) )
811 {
812 throw new ArchetypeTemplateProcessingException(
813 "Template '" + template + "' not in directory '" + sourceDirectory + "'" );
814 }
815
816 String extraPackages = dirname.substring( sourceDirectory.length() );
817 if ( extraPackages.startsWith( "/" ) )
818 {
819 extraPackages = extraPackages.substring( 1 );
820 }
821 if ( extraPackages.length() > 0 )
822 {
823 path += "/" + extraPackages;
824 }
825
826 f = new File( new File( new File( outputDirectory, sourceDirectory ), path ), filename );
827 }
828 else
829 {
830 f = new File( outputDirectory, template );
831 }
832
833 if ( !f.getParentFile().exists() )
834 {
835 f.getParentFile().mkdirs();
836 }
837
838 if ( descriptor.isFiltered() )
839 {
840 Writer writer = null;
841 try
842 {
843 StringWriter stringWriter = new StringWriter();
844
845 template = ARCHETYPE_RESOURCES + "/" + template;
846
847 velocity.getEngine().mergeTemplate( template, descriptor.getEncoding(), context, stringWriter );
848
849 writer = new OutputStreamWriter( new FileOutputStream( f ), descriptor.getEncoding() );
850
851 writer.write( StringUtils.unifyLineSeparators( stringWriter.toString() ) );
852
853 writer.flush();
854 }
855 catch ( Exception e )
856 {
857 throw new ArchetypeTemplateProcessingException( "Error merging velocity templates", e );
858 }
859 finally
860 {
861 IOUtil.close( writer );
862 }
863 }
864 else
865 {
866 InputStream is = getStream( ARCHETYPE_RESOURCES + "/" + template, null );
867
868 OutputStream fos = null;
869
870 try
871 {
872 fos = new FileOutputStream( f );
873
874 IOUtil.copy( is, fos );
875 }
876 catch ( Exception e )
877 {
878 throw new ArchetypeTemplateProcessingException( "Error copying file", e );
879 }
880 finally
881 {
882 IOUtil.close( fos );
883
884 IOUtil.close( is );
885 }
886 }
887 }
888
889 protected void createProjectDirectoryStructure( String outputDirectory )
890 {
891 }
892
893 private InputStream getStream( String name, ClassLoader loader )
894 {
895 if ( loader == null )
896 {
897 return Thread.currentThread().getContextClassLoader().getResourceAsStream( name );
898 }
899 return loader.getResourceAsStream( name );
900 }
901 }