1 package org.apache.maven.plugins.shade.resource;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.BufferedReader;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.InputStreamReader;
26 import java.io.OutputStreamWriter;
27 import java.io.PrintWriter;
28 import java.io.Writer;
29 import java.text.SimpleDateFormat;
30 import java.util.Date;
31 import java.util.Iterator;
32 import java.util.LinkedHashMap;
33 import java.util.LinkedHashSet;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Set;
37 import java.util.TreeSet;
38 import java.util.jar.JarEntry;
39 import java.util.jar.JarOutputStream;
40
41 import org.codehaus.plexus.util.StringUtils;
42
43
44
45
46 public class ApacheNoticeResourceTransformer
47 implements ResourceTransformer
48 {
49 Set entries = new LinkedHashSet();
50 Map organizationEntries = new LinkedHashMap();
51
52 String projectName = "";
53 boolean addHeader = true;
54
55 String preamble1 =
56 "// ------------------------------------------------------------------\n"
57 + "// NOTICE file corresponding to the section 4d of The Apache License,\n"
58 + "// Version 2.0, in this case for ";
59
60 String preamble2 = "\n// ------------------------------------------------------------------\n";
61
62 String preamble3 = "This product includes software developed at\n";
63
64
65 String organizationName = "The Apache Software Foundation";
66 String organizationURL = "http://www.apache.org/";
67 String inceptionYear = "2006";
68
69 String copyright;
70
71
72
73
74 String encoding;
75
76 private static final String NOTICE_PATH = "META-INF/NOTICE";
77
78 private static final String NOTICE_TXT_PATH = "META-INF/NOTICE.txt";
79
80 public boolean canTransformResource( String resource )
81 {
82 if ( NOTICE_PATH.equalsIgnoreCase( resource ) || NOTICE_TXT_PATH.equalsIgnoreCase( resource ) )
83 {
84 return true;
85 }
86
87 return false;
88 }
89
90 public void processResource( String resource, InputStream is, List relocators )
91 throws IOException
92 {
93 if ( entries.isEmpty() )
94 {
95 String year = new SimpleDateFormat( "yyyy" ).format( new Date() );
96 if ( !inceptionYear.equals( year ) )
97 {
98 year = inceptionYear + "-" + year;
99 }
100
101
102
103 if ( addHeader )
104 {
105 entries.add( preamble1 + projectName + preamble2 );
106 }
107 else
108 {
109 entries.add( "" );
110 }
111
112 entries.add( projectName + "\nCopyright " + year + " " + organizationName + "\n" );
113 entries.add( preamble3 + organizationName + " (" + organizationURL + ").\n" );
114 }
115
116
117 BufferedReader reader;
118 if ( StringUtils.isNotEmpty( encoding ) )
119 {
120 reader = new BufferedReader( new InputStreamReader( is, encoding ) );
121 }
122 else
123 {
124 reader = new BufferedReader( new InputStreamReader( is ) );
125 }
126
127 String line = reader.readLine();
128 StringBuffer sb = new StringBuffer();
129 Set currentOrg = null;
130 int lineCount = 0;
131 while ( line != null )
132 {
133 String trimedLine = line.trim();
134
135 if ( !trimedLine.startsWith( "//" ) )
136 {
137 if ( trimedLine.length() > 0 )
138 {
139 if ( trimedLine.startsWith( "- " ) )
140 {
141
142 if ( lineCount == 1
143 && sb.toString().indexOf( "This product includes/uses software(s) developed by" ) != -1 )
144 {
145 currentOrg = (Set) organizationEntries.get( sb.toString().trim() );
146 if ( currentOrg == null )
147 {
148 currentOrg = new TreeSet();
149 organizationEntries.put( sb.toString().trim(), currentOrg );
150 }
151 sb = new StringBuffer();
152 }
153 else if ( sb.length() > 0 && currentOrg != null )
154 {
155 currentOrg.add( sb.toString() );
156 sb = new StringBuffer();
157 }
158
159 }
160 sb.append( line ).append( "\n" );
161 lineCount++;
162 }
163 else
164 {
165 String ent = sb.toString();
166 if ( ent.startsWith( projectName )
167 && ent.indexOf( "Copyright " ) != -1 )
168 {
169 copyright = ent;
170 }
171 if ( currentOrg == null )
172 {
173 entries.add( ent );
174 }
175 else
176 {
177 currentOrg.add( ent );
178 }
179 sb = new StringBuffer();
180 lineCount = 0;
181 currentOrg = null;
182 }
183 }
184
185 line = reader.readLine();
186 }
187 if ( sb.length() > 0 )
188 {
189 if ( currentOrg == null )
190 {
191 entries.add( sb.toString() );
192 }
193 else
194 {
195 currentOrg.add( sb.toString() );
196 }
197 }
198 }
199
200 public boolean hasTransformedResource()
201 {
202 return true;
203 }
204
205 public void modifyOutputStream( JarOutputStream jos )
206 throws IOException
207 {
208 jos.putNextEntry( new JarEntry( NOTICE_PATH ) );
209
210 Writer pow;
211 if ( StringUtils.isNotEmpty( encoding ) )
212 {
213 pow = new OutputStreamWriter( jos, encoding );
214 }
215 else
216 {
217 pow = new OutputStreamWriter( jos );
218 }
219 PrintWriter writer = new PrintWriter( pow );
220
221 int count = 0;
222 for ( Iterator itr = entries.iterator() ; itr.hasNext() ; )
223 {
224 ++count;
225 String line = (String) itr.next();
226 if ( line.equals( copyright ) && count != 2 )
227 {
228 continue;
229 }
230
231 if ( count == 2 && copyright != null )
232 {
233 writer.print( copyright );
234 writer.print( '\n' );
235 }
236 else
237 {
238 writer.print( line );
239 writer.print( '\n' );
240 }
241 if ( count == 3 )
242 {
243
244 for ( Iterator oit = organizationEntries.entrySet().iterator(); oit.hasNext(); )
245 {
246 Map.Entry entry = (Map.Entry) oit.next();
247 writer.print( entry.getKey().toString() );
248 writer.print( '\n' );
249 Set entrySet = (Set) entry.getValue();
250 for ( Iterator eit = entrySet.iterator(); eit.hasNext(); )
251 {
252 writer.print( eit.next().toString() );
253 }
254 writer.print( '\n' );
255 }
256 }
257 }
258
259 writer.flush();
260
261 entries.clear();
262 }
263 }