1 package org.apache.maven.wagon.observers;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import org.apache.maven.wagon.events.TransferEvent;
23 import org.apache.maven.wagon.events.TransferListener;
24
25 import java.security.MessageDigest;
26 import java.security.NoSuchAlgorithmException;
27
28 /**
29 * TransferListeners which computes MD5 checksum on the fly when files are transfered.
30 *
31 * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
32 *
33 */
34 public class ChecksumObserver
35 implements TransferListener
36 {
37 private MessageDigest digester = null;
38
39 private String actualChecksum;
40
41 public ChecksumObserver()
42 throws NoSuchAlgorithmException
43 {
44 this( "MD5" );
45 }
46
47 /**
48 * @param algorithm One of the algorithms supported by JDK: MD5, MD2 or SHA-1
49 */
50 public ChecksumObserver( String algorithm )
51 throws NoSuchAlgorithmException
52 {
53 digester = MessageDigest.getInstance( algorithm );
54 }
55
56 public void transferInitiated( TransferEvent transferEvent )
57 {
58 // This space left intentionally blank
59 }
60
61 /**
62 * @see org.apache.maven.wagon.events.TransferListener#transferStarted(org.apache.maven.wagon.events.TransferEvent)
63 */
64 public void transferStarted( TransferEvent transferEvent )
65 {
66 actualChecksum = null;
67
68 digester.reset();
69 }
70
71 /**
72 * @see org.apache.maven.wagon.events.TransferListener#transferProgress(org.apache.maven.wagon.events.TransferEvent, byte[], int)
73 */
74 public void transferProgress( TransferEvent transferEvent, byte[] buffer, int length )
75 {
76 digester.update( buffer, 0, length );
77 }
78
79 public void transferCompleted( TransferEvent transferEvent )
80 {
81 actualChecksum = encode( digester.digest() );
82 }
83
84 public void transferError( TransferEvent transferEvent )
85 {
86 digester.reset();
87
88 actualChecksum = null;
89 }
90
91 public void debug( String message )
92 {
93 // left intentionally blank
94 }
95
96 /**
97 * Returns md5 checksum which was computed during transfer
98 *
99 * @return
100 */
101 public String getActualChecksum()
102 {
103 return actualChecksum;
104 }
105
106 /**
107 * Encodes a 128 bit or 160-bit byte array into a String.
108 *
109 * @param binaryData Array containing the digest
110 * @return Encoded hex string, or null if encoding failed
111 */
112 protected String encode( byte[] binaryData )
113 {
114 if ( binaryData.length != 16 && binaryData.length != 20 )
115 {
116 int bitLength = binaryData.length * 8;
117 throw new IllegalArgumentException( "Unrecognised length for binary data: " + bitLength + " bits" );
118 }
119
120 StringBuilder retValue = new StringBuilder();
121
122 for ( int i = 0; i < binaryData.length; i++ )
123 {
124 String t = Integer.toHexString( binaryData[i] & 0xff );
125
126 if ( t.length() == 1 )
127 {
128 retValue.append( '0' ).append( t );
129 }
130 else
131 {
132 retValue.append( t );
133 }
134 }
135
136 return retValue.toString().trim();
137 }
138
139
140 }