Skip to content
This repository was archived by the owner on Dec 4, 2024. It is now read-only.

Commit b0b0674

Browse files
author
joakime
committed
* Adding ChecksumFile component to aide in common checksum creation and validation routines.
* Adding .getFilenameExtension() to digesters (by popular demand)
1 parent 83124c7 commit b0b0674

File tree

9 files changed

+210
-0
lines changed

9 files changed

+210
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package org.codehaus.plexus.digest;
2+
3+
/*
4+
* Copyright 2001-2007 The Codehaus.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
import org.codehaus.plexus.util.FileUtils;
20+
import org.codehaus.plexus.util.StringUtils;
21+
22+
import java.io.File;
23+
import java.io.FileNotFoundException;
24+
import java.io.IOException;
25+
26+
/**
27+
* ChecksumFile
28+
*
29+
* @author <a href="mailto:[email protected]">Joakim Erdfelt</a>
30+
* @version $Id$
31+
*
32+
* @plexus.component role="org.codehaus.plexus.digest.ChecksumFile"
33+
*/
34+
public class ChecksumFile
35+
{
36+
/**
37+
* @plexus.requirement role-hint="sha1"
38+
*/
39+
private Digester digestSha1;
40+
41+
/**
42+
* @plexus.requirement role-hint="md5";
43+
*/
44+
private Digester digestMd5;
45+
46+
/**
47+
* <p>
48+
* Given a checksum file, check to see if the file it represents is valid according to the checksum.
49+
* </p>
50+
*
51+
* <dl>
52+
* <lh>Terminology:</lh>
53+
* <dt>Checksum File</dt>
54+
* <dd>The file that contains the previously calculated checksum value for the reference file.
55+
* This is a text file with the extension ".sha1" or ".md5", and contains a single entry
56+
* consisting of an optional reference filename, and a checksum string.
57+
* </dd>
58+
* <dt>Reference File</dt>
59+
* <dd>The file that is being referenced in the checksum file.</dd>
60+
* </dl>
61+
*
62+
* <p>
63+
* NOTE: Only supports single file checksums of type MD5 or SHA1.
64+
* </p>
65+
*
66+
* @param checksumFile the checksum file (must end in ".sha1" or ".md5")
67+
* @return true if the checksum is valid for the file it represents.
68+
* @throws DigesterException if there is a digester problem during the check of the reference file.
69+
* @throws FileNotFoundException if the checksumFile itself or the file it refers to is not found.
70+
* @throws IOException if the reading of the checksumFile or the file it refers to fails.
71+
*/
72+
public boolean isValidChecksum( File checksumFile ) throws DigesterException, FileNotFoundException, IOException
73+
{
74+
if ( !checksumFile.exists() )
75+
{
76+
throw new FileNotFoundException( "Unable to find checksum file " + checksumFile.getAbsolutePath() );
77+
}
78+
79+
if ( !checksumFile.isFile() )
80+
{
81+
throw new IOException( "Unable to load checksum from non-file " + checksumFile.getAbsolutePath() );
82+
}
83+
84+
String path = checksumFile.getAbsolutePath();
85+
Digester digester = null;
86+
87+
if ( path.endsWith( digestMd5.getFilenameExtension() ) )
88+
{
89+
digester = digestMd5;
90+
}
91+
else if ( path.endsWith( digestSha1.getFilenameExtension() ) )
92+
{
93+
digester = digestSha1;
94+
}
95+
// TODO: Add more digester implementations here.
96+
97+
if ( digester == null )
98+
{
99+
throw new DigesterException( "Unable to determine digester type from filename " + path );
100+
}
101+
102+
File referenceFile = new File( path.substring( 0, path.length() - digester.getFilenameExtension().length() ) );
103+
104+
String rawChecksum = FileUtils.fileRead( checksumFile );
105+
String expectedChecksum = DigestUtils.cleanChecksum( rawChecksum, digester, referenceFile.getName() );
106+
107+
String actualChecksum = digester.calc( referenceFile );
108+
109+
return StringUtils.equalsIgnoreCase( expectedChecksum, actualChecksum );
110+
}
111+
112+
/**
113+
* Creates a checksum file of the provided referenceFile.
114+
*
115+
* @param referenceFile the file to checksum.
116+
* @param digester the digester to use.
117+
* @return the checksum File that was created.
118+
* @throws DigesterException if there was a problem calculating the checksum of the referenceFile.
119+
* @throws IOException if there was a problem either reading the referenceFile, or writing the checksum file.
120+
*/
121+
public File createChecksum( File referenceFile, Digester digester ) throws DigesterException, IOException
122+
{
123+
File checksumFile = new File( referenceFile.getAbsolutePath() + digester.getFilenameExtension() );
124+
String checksum = digester.calc( checksumFile );
125+
FileUtils.fileWrite( checksumFile.getAbsolutePath(), checksum + " " + referenceFile.getName() );
126+
return checksumFile;
127+
}
128+
}

src/main/java/org/codehaus/plexus/digest/DigestUtils.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,20 @@ private DigestUtils()
3030
{
3131
// don't create this class
3232
}
33+
34+
/**
35+
* Take a raw checksum string and verify that it matches the expectedFilename and digester, then
36+
* return the trimmed checksum string.
37+
*
38+
* @param rawChecksum the raw checksum string that may include the filename.
39+
* @param digester the expected digester for this checksum string.
40+
* @return the trimmed checksum string (no filename portion)
41+
* @throws DigesterException if there was a problem verifying the checksum string.
42+
*/
43+
public static String cleanChecksum( String rawChecksum, Digester digester, String expectedFilename ) throws DigesterException
44+
{
45+
return cleanChecksum( rawChecksum, digester.getAlgorithm(), expectedFilename );
46+
}
3347

3448
public static String cleanChecksum( String checksum, String algorithm, String path )
3549
throws DigesterException

src/main/java/org/codehaus/plexus/digest/Digester.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ public interface Digester
3333
* @return the algorithm
3434
*/
3535
String getAlgorithm();
36+
37+
/**
38+
* The filename extension for this digester.
39+
*
40+
* @return the filename extension.
41+
*/
42+
String getFilenameExtension();
3643

3744
/**
3845
* Calculate a checksum for a file.

src/main/java/org/codehaus/plexus/digest/Md5Digester.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
public class Md5Digester
2525
extends AbstractDigester
2626
{
27+
public String getFilenameExtension()
28+
{
29+
return ".md5";
30+
}
31+
2732
public Md5Digester()
2833
{
2934
super( new StreamingMd5Digester() );

src/main/java/org/codehaus/plexus/digest/Sha1Digester.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
public class Sha1Digester
2525
extends AbstractDigester
2626
{
27+
public String getFilenameExtension()
28+
{
29+
return ".sha1";
30+
}
31+
2732
public Sha1Digester()
2833
{
2934
super( new StreamingSha1Digester() );
3.98 KB
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
f42047fe2e177ac04d0df7aa44d408be redback-authz-open.jar
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2bb14b388973351b0a4dfe11d171965f59cc61a1 redback-authz-open.jar
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.codehaus.plexus.digest;
2+
3+
/*
4+
* Copyright 2001-2007 The Codehaus.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
import org.codehaus.plexus.PlexusTestCase;
20+
21+
import java.io.File;
22+
import java.io.FileNotFoundException;
23+
import java.io.IOException;
24+
25+
/**
26+
* ChecksumFileTest
27+
*
28+
* @author <a href="mailto:[email protected]">Joakim Erdfelt</a>
29+
* @version $Id$
30+
*/
31+
public class ChecksumFileTest extends PlexusTestCase
32+
{
33+
private ChecksumFile checksum;
34+
35+
protected void setUp() throws Exception
36+
{
37+
super.setUp();
38+
39+
checksum = (ChecksumFile) lookup( ChecksumFile.class.getName() );
40+
}
41+
42+
public void testChecksum() throws FileNotFoundException, DigesterException, IOException
43+
{
44+
File exampleDir = new File( getBasedir(), "src/test/examples" );
45+
46+
assertTrue( checksum.isValidChecksum( new File( exampleDir, "redback-authz-open.jar.md5" ) ) );
47+
assertTrue( checksum.isValidChecksum( new File( exampleDir, "redback-authz-open.jar.sha1" ) ) );
48+
}
49+
}

0 commit comments

Comments
 (0)