Applied-Energistics-2-tiler.../src/main/java/appeng/services/version/VersionParser.java

140 lines
3.8 KiB
Java

package appeng.services.version;
import java.util.Scanner;
import java.util.regex.Pattern;
/**
* can parse a version in form of rv2-beta-8 or rv2.beta.8
*/
public final class VersionParser
{
private static final Pattern PATTERN_DOT = Pattern.compile( "\\." );
private static final Pattern PATTERN_DASH = Pattern.compile( "-" );
private static final Pattern PATTERN_REVISION = Pattern.compile( "[^0-9]+" );
private static final Pattern PATTERN_BUILD = Pattern.compile( "[^0-9]+" );
private static final Pattern PATTERN_NATURAL = Pattern.compile( "[0-9]+" );
private static final Pattern PATTERN_VALID_REVISION = Pattern.compile( "^rv\\d+$" );
/**
* Parses the {@link Version} out of a String
*
* @param raw String in form of rv2-beta-8 or rv2.beta.8
*
* @return {@link Version} encoded in the raw String
*
* @throws AssertionError if raw String does not match pattern of a {@link Version}
*/
public Version parse( String raw )
{
final String transformed = this.transformDelimiter( raw );
final String[] split = transformed.split( "_" );
return this.parseVersion( split );
}
/**
* Replaces all "." and "-" into "_" to make them uniform
*
* @param raw raw version string containing "." or "-"
*
* @return transformed raw, where "." and "-" are replaced by "_"
*/
private String transformDelimiter( String raw )
{
assert raw.contains( "." ) || raw.contains( "-" );
final String withoutDot = PATTERN_DOT.matcher( raw ).replaceAll( "_" );
final String withoutDash = PATTERN_DASH.matcher( withoutDot ).replaceAll( "_" );
return withoutDash;
}
/**
* parses the {@link Version} out of the split.
* The split must have a length of 3,
* representing revision, channel and build.
*
* @param splitRaw raw version split with length of 3
*
* @return {@link Version} represented by the splitRaw
*/
private Version parseVersion( String[] splitRaw )
{
assert splitRaw.length == 3;
final String rawRevision = splitRaw[0];
final String rawChannel = splitRaw[1];
final String rawBuild = splitRaw[2];
final int revision = this.parseRevision( rawRevision );
final Channel channel = this.parseChannel( rawChannel );
final int build = this.parseBuild( rawBuild );
return new DefaultVersion( revision, channel, build );
}
/**
* A revision starts with the keyword "rv", followed by a natural number
*
* @param rawRevision String containing the revision number
*
* @return revision number
*/
private int parseRevision( String rawRevision )
{
assert PATTERN_VALID_REVISION.matcher( rawRevision ).matches();
final Scanner scanner = new Scanner( rawRevision );
final int revision = scanner.useDelimiter( PATTERN_REVISION ).nextInt();
scanner.close();
return revision;
}
/**
* A channel is atm either one of {@link Channel#Alpha}, {@link Channel#Beta} or {@link Channel#Release}
*
* @param rawChannel String containing the channel
*
* @return matching {@link Channel} to the String
*/
private Channel parseChannel( String rawChannel )
{
assert rawChannel.equalsIgnoreCase( Channel.Alpha.name() ) || rawChannel.equalsIgnoreCase( Channel.Beta.name() ) || rawChannel.equalsIgnoreCase( Channel.Release.name() );
for( Channel channel : Channel.values() )
{
if( channel.name().equalsIgnoreCase( rawChannel ) )
{
return channel;
}
}
throw new IllegalArgumentException( "Raw channel " + rawChannel + " did not contain any of the pre-programmed types." );
}
/**
* A build is just a natural number
*
* @param rawBuild String containing the build number
*
* @return build number
*/
private int parseBuild( String rawBuild )
{
assert PATTERN_NATURAL.matcher( rawBuild ).matches();
final Scanner scanner = new Scanner( rawBuild );
final int build = scanner.useDelimiter( PATTERN_BUILD ).nextInt();
scanner.close();
return build;
}
}