View Javadoc

1   package org.apache.maven.changelog;
2   
3   /* ====================================================================
4    *   Licensed to the Apache Software Foundation (ASF) under one or more
5    *   contributor license agreements.  See the NOTICE file distributed with
6    *   this work for additional information regarding copyright ownership.
7    *   The ASF licenses this file to You under the Apache License, Version 2.0
8    *   (the "License"); you may not use this file except in compliance with
9    *   the License.  You may obtain a copy of the License at
10   *
11   *       http://www.apache.org/licenses/LICENSE-2.0
12   *
13   *   Unless required by applicable law or agreed to in writing, software
14   *   distributed under the License is distributed on an "AS IS" BASIS,
15   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   *   See the License for the specific language governing permissions and
17   *   limitations under the License.
18   * ====================================================================
19   */
20  
21  import java.text.SimpleDateFormat;
22  
23  import java.util.Date;
24  import java.util.Enumeration;
25  import java.util.Vector;
26  
27  /**
28   * Change Log Entry - holds details about revisions to a file.
29   *
30   * @task add time of change to the entry
31   * @task investigate betwixt for toXML method
32   * @author <a href="mailto:dion@multitask.com.au">dIon Gillard</a>
33   * @version $Id: ChangeLogEntry.java 532339 2007-04-25 12:28:56Z ltheussl $
34   */
35  public class ChangeLogEntry
36  {
37      /**
38       * Escaped <code>&lt;</code> entity
39       */
40      public static final String LESS_THAN_ENTITY = "&lt;";
41  
42      /**
43       * Escaped <code>&gt;</code> entity
44       */
45      public static final String GREATER_THAN_ENTITY = "&gt;";
46  
47      /**
48       * Escaped <code>&amp;</code> entity
49       */
50      public static final String AMPERSAND_ENTITY = "&amp;";
51  
52      /**
53       * Escaped <code>'</code> entity
54       */
55      public static final String APOSTROPHE_ENTITY = "&apos;";
56  
57      /**
58       * Escaped <code>"</code> entity
59       */
60      public static final String QUOTE_ENTITY = "&quot;";
61  
62      /**
63       * Formatter used by the getDateFormatted method.
64       */
65      private static final SimpleDateFormat DATE_FORMAT =
66          new SimpleDateFormat( "yyyy-MM-dd" );
67  
68      /**
69       * Formatter used by the getTimeFormatted method.
70       */
71      private static final SimpleDateFormat TIME_FORMAT =
72          new SimpleDateFormat( "HH:mm:ss" );
73  
74      /** Date the changes were committed */
75      private Date date;
76  
77      /** User who made changes */
78      private String author;
79  
80      /** comment provided at commit time */
81      private String comment = "";
82  
83      /** ChangeLogFiles committed on the date, by the author, with comment*/
84      private Vector files = new Vector();
85  
86      /**
87       * Constructor used when attributes aren't available until later
88       */
89      public ChangeLogEntry()
90      {
91      }
92  
93      /**
94       * Adds a file to the list for this entry
95       * @param file a {@link ChangeLogFile}
96       */
97      public void addFile( ChangeLogFile file )
98      {
99          files.addElement( file );
100     }
101 
102     /**
103      * Adds a feature to the File attribute of the Entry object.
104      * @param file the file name committed
105      * @param revision the revision of the latest change
106      */
107     public void addFile( String file, String revision )
108     {
109         files.addElement( new ChangeLogFile( file, revision ) );
110     }
111 
112     /**
113      * @return a string representation of the entry
114      */
115     public String toString()
116     {
117         return author + "\n" + date + "\n" + files + "\n" + comment;
118     }
119 
120     /**
121      * Provide the changelog entry as an XML snippet.
122      *
123      * @task make sure comment doesn't contain CDATA tags - MAVEN114
124      * @return a changelog-entry in xml format
125      */
126     public String toXML()
127     {
128         StringBuffer buffer = new StringBuffer();
129 
130         buffer.append( "\t<changelog-entry>\n" ).append( "\t\t<date>" )
131               .append( getDateFormatted() ).append( "</date>\n" )
132               .append( "\t\t<time>" ).append( getTimeFormatted() )
133               .append( "</time>\n" ).append( "\t\t<author><![CDATA[" )
134               .append( author ).append( "]]></author>\n" );
135 
136         for ( Enumeration e = files.elements(); e.hasMoreElements(); )
137         {
138             ChangeLogFile file = (ChangeLogFile) e.nextElement();
139 
140             buffer.append( "\t\t<file>\n" ).append( "\t\t\t<name>" )
141                   .append( escapeValue( file.getName() ) ).append( "</name>\n" )
142                   .append( "\t\t\t<revision>" ).append( file.getRevision() )
143                   .append( "</revision>\n" );
144             buffer.append( "\t\t</file>\n" );
145         }
146 
147         buffer.append( "\t\t<msg><![CDATA[" ).append( removeCDataEnd( comment ) )
148               .append( "]]></msg>\n" );
149         buffer.append( "\t</changelog-entry>\n" );
150 
151         return buffer.toString();
152     }
153 
154     /**
155      * Getter for property author.
156      * @return Value of property author.
157      */
158     public String getAuthor()
159     {
160         return author;
161     }
162 
163     /**
164      * Setter for property author.
165      * @param author New value of property author.
166      */
167     public void setAuthor( String author )
168     {
169         this.author = author;
170     }
171 
172     /**
173      * Getter for property comment.
174      * @return Value of property comment.
175      */
176     public String getComment()
177     {
178         return comment;
179     }
180 
181     /**
182      * Setter for property comment.
183      * @param comment New value of property comment.
184      */
185     public void setComment( String comment )
186     {
187         this.comment = comment;
188     }
189 
190     /**
191      * Getter for property date.
192      * @return Value of property date.
193      */
194     public Date getDate()
195     {
196         return (Date) date.clone();
197     }
198 
199     /**
200      * Setter for property date.
201      * @param date New value of property date.
202      */
203     public void setDate( Date date )
204     {
205         this.date = new Date( date.getTime() );
206     }
207 
208     /**
209      * @return date in yyyy-mm-dd format
210      */
211     public String getDateFormatted()
212     {
213         return DATE_FORMAT.format( getDate() );
214     }
215 
216     /**
217      * @return time in HH:mm:ss format
218      */
219     public String getTimeFormatted()
220     {
221         return TIME_FORMAT.format( getDate() );
222     }
223 
224     /**
225      * remove a <code>]]></code> from comments (replace it with <code>] ] ></code>).
226      * @param message
227      * @return
228      */
229     private String removeCDataEnd( String message )
230     {
231         // check for invalid sequence ]]>
232         int endCdata;
233 
234         while ( ( message != null )
235             && ( ( endCdata = message.indexOf( "]]>" ) ) > -1 ) )
236         {
237             message =
238                 message.substring( 0, endCdata ) + "] ] >"
239                 + message.substring( endCdata + 3, message.length() );
240         }
241 
242         return message;
243     }
244 
245     /**
246      * <p>Escape the <code>toString</code> of the given object.
247      * For use in an attribute value.</p>
248      *
249      * swiped from jakarta-commons/betwixt -- XMLUtils.java
250      *
251      * @param value escape <code>value.toString()</code>
252      * @return text with characters restricted (for use in attributes) escaped
253      */
254     public static final String escapeValue( Object value )
255     {
256         StringBuffer buffer = new StringBuffer( value.toString() );
257 
258         for ( int i = 0, size = buffer.length(); i < size; i++ )
259         {
260             switch ( buffer.charAt( i ) )
261             {
262             case '<' :
263                 buffer.replace( i, i + 1, LESS_THAN_ENTITY );
264                 size += 3;
265                 i += 3;
266 
267                 break;
268 
269             case '>' :
270                 buffer.replace( i, i + 1, GREATER_THAN_ENTITY );
271                 size += 3;
272                 i += 3;
273 
274                 break;
275 
276             case '&' :
277                 buffer.replace( i, i + 1, AMPERSAND_ENTITY );
278                 size += 4;
279                 i += 4;
280 
281                 break;
282 
283             case '\'' :
284                 buffer.replace( i, i + 1, APOSTROPHE_ENTITY );
285                 size += 4;
286                 i += 4;
287 
288                 break;
289 
290             case '\"' :
291                 buffer.replace( i, i + 1, QUOTE_ENTITY );
292                 size += 5;
293                 i += 5;
294 
295                 break;
296             }
297         }
298 
299         return buffer.toString();
300     }
301 }