001 /**
002 * Copyright 2010-2012 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.codehaus.mojo.license.header.transformer;
017
018
019 import org.apache.commons.lang.StringUtils;
020 import org.codehaus.mojo.license.header.FileHeader;
021
022 import java.util.regex.Matcher;
023 import java.util.regex.Pattern;
024
025 /**
026 * Abstract implementation of {@link FileHeaderTransformer}.
027 * <p/>
028 * Concrete implementation should only have to give comment configuration.
029 *
030 * @author tchemit <chemit@codelutin.com>
031 * @since 1.0
032 */
033 public abstract class AbstractFileHeaderTransformer
034 implements FileHeaderTransformer
035 {
036
037 /**
038 * pattern of the copyright string representation :
039 * <ul>
040 * <li>group(1) is Copyright prefix</li>
041 * <li>group(2) is Copyright first year</li>
042 * <li>group(3) is Copyright last year with prefix (can be null)</li>
043 * <li>group(4) is Copyright last year (can be null)</li>
044 * <li>group(5) is Copyright holder</li>
045 * </ul>
046 */
047 protected static final Pattern COPYRIGHT_PATTERN =
048 Pattern.compile( "(.[^\\d]+)?\\s(\\d{4})?(\\s+-\\s+(\\d{4})?){0,1}\\s+(.+)?" );
049
050 /**
051 * name of transformer
052 */
053 protected String name;
054
055 /**
056 * description of transfomer
057 */
058 protected String description;
059
060 /**
061 * section delimiter
062 */
063 protected String sectionDelimiter = DEFAULT_SECTION_DELIMITER;
064
065 /**
066 * start process tag
067 */
068 protected String processStartTag = DEFAULT_PROCESS_START_TAG;
069
070 /**
071 * end process tag
072 */
073 protected String processEndTag = DEFAULT_PROCESS_END_TAG;
074
075 /**
076 * comment start tag
077 */
078 protected String commentStartTag;
079
080 /**
081 * comment end tag
082 */
083 protected String commentEndTag;
084
085 /**
086 * comment line prefix (to add for header content)
087 */
088 protected String commentLinePrefix;
089
090 protected AbstractFileHeaderTransformer( String name, String description, String commentStartTag,
091 String commentEndTag, String commentLinePrefix )
092 {
093 this.name = name;
094 this.description = description;
095
096 // checks comment start tag is different from comment prefix
097 if ( commentStartTag.equals( commentLinePrefix ) )
098 {
099 throw new IllegalStateException(
100 "commentStartTag can not be equals to commentPrefixLine, " + "but was [" + commentStartTag + "]" );
101 }
102
103 // checks comment end tag is different from comment prefix
104 if ( commentEndTag.equals( commentLinePrefix ) )
105 {
106 throw new IllegalStateException(
107 "commentEndTag can not be equals to commentPrefixLine, " + "but was [" + commentEndTag + "]" );
108 }
109
110 this.commentStartTag = commentStartTag;
111 this.commentEndTag = commentEndTag;
112 this.commentLinePrefix = commentLinePrefix;
113 }
114
115 public String getName()
116 {
117 return name;
118 }
119
120 public void setName( String name )
121 {
122 this.name = name;
123 }
124
125 public String getDescription()
126 {
127 return description;
128 }
129
130 public void setDescription( String description )
131 {
132 this.description = description;
133 }
134
135 public String getSectionDelimiter()
136 {
137 return sectionDelimiter;
138 }
139
140 public void setSectionDelimiter( String sectionDelimiter )
141 {
142 this.sectionDelimiter = sectionDelimiter;
143 }
144
145 public String getProcessStartTag()
146 {
147 return processStartTag;
148 }
149
150 public void setProcessStartTag( String processStartTag )
151 {
152 this.processStartTag = processStartTag;
153 }
154
155 public String getProcessEndTag()
156 {
157 return processEndTag;
158 }
159
160 public void setProcessEndTag( String processEndTag )
161 {
162 this.processEndTag = processEndTag;
163 }
164
165 public String getCommentStartTag()
166 {
167 return commentStartTag;
168 }
169
170 public void setCommentStartTag( String commentStartTag )
171 {
172 this.commentStartTag = commentStartTag;
173 }
174
175 public String getCommentEndTag()
176 {
177 return commentEndTag;
178 }
179
180 public void setCommentEndTag( String commentEndTag )
181 {
182 this.commentEndTag = commentEndTag;
183 }
184
185 public String getCommentLinePrefix()
186 {
187 return commentLinePrefix;
188 }
189
190 public String addHeader( String header, String content )
191 {
192 return header + content;
193 }
194
195 public void setCommentLinePrefix( String commentLinePrefix )
196 {
197 this.commentLinePrefix = commentLinePrefix;
198 }
199
200 public FileHeader toFileHeader( String header )
201 {
202 FileHeader model = new FileHeader();
203
204 String[] sections = header.split( getSectionDelimiter() );
205 if ( sections.length != 3 )
206 {
207 throw new IllegalStateException( "could not find 3 sections in\n" + header );
208 }
209
210 // first section is the description
211 String description = sections[0].trim();
212 model.setDescription( description );
213
214 // second section is the copyright
215 String copyright = sections[1].trim();
216 Matcher matcher = COPYRIGHT_PATTERN.matcher( copyright );
217 if ( !matcher.matches() )
218 {
219 throw new IllegalStateException( "copyright [" + copyright + "] is not valid" );
220 }
221 String firstYear = matcher.group( 2 );
222 String lastYear = matcher.group( 4 );
223 String holder = matcher.group( 5 );
224 model.setCopyrightFirstYear( Integer.valueOf( firstYear.trim() ) );
225 if ( lastYear != null )
226 {
227 model.setCopyrightLastYear( Integer.valueOf( lastYear.trim() ) );
228 }
229 model.setCopyrightHolder( holder.trim() );
230
231 // third section is the license
232 String license = sections[2].trim();
233 model.setLicense( license );
234 return model;
235 }
236
237 public String toString( FileHeader model )
238 throws NullPointerException
239 {
240 if ( model == null )
241 {
242 throw new NullPointerException( "model can not be null!" );
243 }
244 StringBuilder buffer = new StringBuilder();
245
246 String sectionDelimiter = LINE_SEPARATOR + getSectionDelimiter() + LINE_SEPARATOR;
247
248 // add description section
249 buffer.append( model.getDescription().trim() );
250 buffer.append( sectionDelimiter );
251
252 // add copyright section
253 buffer.append( model.getCopyright().trim() );
254 buffer.append( sectionDelimiter );
255
256 // add license section
257 buffer.append( model.getLicense().trim() ).append( LINE_SEPARATOR );
258 return buffer.toString();
259 }
260
261 public String toHeaderContent( FileHeader model )
262 throws NullPointerException
263 {
264
265 String result;
266
267 // model to text
268 result = toString( model );
269
270 // box with process tag
271 result = boxProcessTag( result );
272
273 // box header with comment prefix
274 result = boxComment( result, false );
275
276 // remove all before process start tag
277 // remove all after process end tag
278 // this is a requirement for processor to respect involution.
279 int index = result.indexOf( getProcessStartTag() );
280 int lastIndex = result.lastIndexOf( getProcessEndTag() ) + getProcessEndTag().length();
281
282 result = result.substring( index, lastIndex );
283 return result;
284 }
285
286 public String boxComment( String header, boolean withTags )
287 {
288 StringBuilder buffer = new StringBuilder();
289 if ( withTags )
290 {
291 buffer.append( getCommentStartTag() ).append( LINE_SEPARATOR );
292 }
293 for ( String line : header.split( LINE_SEPARATOR + "" ) )
294 {
295 buffer.append( getCommentLinePrefix() );
296 buffer.append( line );
297 buffer.append( LINE_SEPARATOR );
298 }
299 if ( withTags )
300 {
301 buffer.append( getCommentEndTag() ).append( LINE_SEPARATOR );
302 }
303 return buffer.toString();
304 }
305
306 public String unboxComent( String header )
307 {
308 StringBuilder buffer = new StringBuilder();
309 int prefixLength = getCommentLinePrefix().length();
310 for ( String line : header.split( LINE_SEPARATOR + "" ) )
311 {
312 if ( StringUtils.isEmpty( line ) || line.contains( getCommentStartTag() ) ||
313 line.contains( getCommentEndTag() ) )
314 {
315
316 // not be unboxed, but just skipped
317 continue;
318 }
319 int index = line.indexOf( getCommentLinePrefix() );
320 if ( index > -1 )
321 {
322
323 // remove comment prefix
324 line = line.substring( index + prefixLength );
325 }
326 else
327 {
328 String s = getCommentLinePrefix().trim();
329 if ( line.startsWith( s ) )
330 {
331 if ( line.length() <= s.length() )
332 {
333 line = "";
334 }
335 }
336 else
337 {
338 line = line.substring( s.length() );
339 }
340 }
341 buffer.append( line ).append( LINE_SEPARATOR );
342 }
343 return buffer.toString();
344 }
345
346 public String boxProcessTag( String header )
347 {
348 StringBuilder buffer = new StringBuilder();
349 buffer.append( getProcessStartTag() ).append( LINE_SEPARATOR );
350 buffer.append( header.trim() ).append( LINE_SEPARATOR );
351 buffer.append( getProcessEndTag() ).append( LINE_SEPARATOR );
352 return buffer.toString();
353 }
354
355 public String unboxProcessTag( String boxedHeader )
356 {
357 StringBuilder buffer = new StringBuilder();
358 for ( String line : boxedHeader.split( LINE_SEPARATOR + "" ) )
359 {
360 if ( StringUtils.isEmpty( line ) || line.contains( getProcessStartTag() ) ||
361 line.contains( getProcessEndTag() ) )
362 {
363
364 // not be unboxed, but just skipped
365 continue;
366 }
367 buffer.append( line ).append( LINE_SEPARATOR );
368 }
369 return buffer.toString();
370 }
371
372 public boolean isDescriptionEquals( FileHeader header1, FileHeader header2 )
373 {
374 return header1.getDescription().equals( header2.getDescription() );
375 }
376
377 public boolean isCopyrightEquals( FileHeader header1, FileHeader header2 )
378 {
379 return header1.getCopyright().equals( header2.getCopyright() );
380 }
381
382 public boolean isLicenseEquals( FileHeader header1, FileHeader header2 )
383 {
384 String license1 = removeSpaces( header1.getLicense() );
385 String license2 = removeSpaces( header2.getLicense() );
386 return license1.equals( license2 );
387 }
388
389 protected static final Pattern REMOVE_SPACE_PATTERN = Pattern.compile( "(\\s+)" );
390
391 protected String removeSpaces( String str )
392 {
393 Matcher matcher = REMOVE_SPACE_PATTERN.matcher( str );
394 String result;
395 if ( matcher.find() )
396 {
397 result = matcher.replaceAll( "" );
398 }
399 else
400 {
401 result = str;
402 }
403 return result;
404 }
405 }