blob: 08228a5e7bca4ec353c7049e49964d202e2759ed [file] [log] [blame]
package org.apache.maven.archiva.repository.content;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.maven.archiva.common.utils.VersionUtil;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Generic Filename Parser for use with layout routines.
*
* @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
* @version $Id$
*/
public class FilenameParser
{
private String name;
private String extension;
private int offset;
private static final Pattern mavenPluginPattern = Pattern.compile( "(maven-.*-plugin)|(.*-maven-plugin)" );
private static final Pattern extensionPattern =
Pattern.compile( "(\\.tar\\.gz$)|(\\.tar\\.bz2$)|(\\.[\\-a-z0-9]*$)", Pattern.CASE_INSENSITIVE );
private static final Pattern SNAPSHOT_PATTERN = Pattern.compile( "^([0-9]{8}\\.[0-9]{6}-[0-9]+)(.*)$" );
private static final Pattern section = Pattern.compile( "([^-]*)" );
private Matcher matcher;
protected FilenameParser( String filename )
{
this.name = filename;
Matcher mat = extensionPattern.matcher( name );
if ( mat.find() )
{
extension = filename.substring( mat.start() + 1 );
name = name.substring( 0, name.length() - extension.length() - 1 );
}
matcher = section.matcher( name );
reset();
}
protected void reset()
{
offset = 0;
}
protected String next()
{
// Past the end of the string.
if ( offset > name.length() )
{
return null;
}
// Return the next section.
if ( matcher.find( offset ) )
{
// Return found section.
offset = matcher.end() + 1;
return matcher.group();
}
// Nothing to return.
return null;
}
protected String expect( String expected )
{
String value = null;
if ( name.startsWith( expected, offset ) )
{
value = expected;
}
else if ( VersionUtil.isGenericSnapshot( expected ) )
{
String version = name.substring( offset );
// check it starts with the same version up to the snapshot part
int leadingLength = expected.length() - 9;
if ( leadingLength > 0 && version.startsWith( expected.substring( 0, leadingLength ) ) &&
version.length() > leadingLength )
{
// If we expect a non-generic snapshot - look for the timestamp
Matcher m = SNAPSHOT_PATTERN.matcher( version.substring( leadingLength + 1 ) );
if ( m.matches() )
{
value = version.substring( 0, leadingLength + 1 ) + m.group( 1 );
}
}
}
if ( value != null )
{
// Potential hit. check for '.' or '-' at end of expected.
int seperatorOffset = offset + value.length();
// Test for "out of bounds" first.
if ( seperatorOffset >= name.length() )
{
offset = name.length();
return value;
}
// Test for seperator char.
char seperatorChar = name.charAt( seperatorOffset );
if ( ( seperatorChar == '-' ) || ( seperatorChar == '.' ) )
{
offset = seperatorOffset + 1;
return value;
}
}
return null;
}
/**
* Get the current seperator character.
*
* @return the seperator character (either '.' or '-'), or 0 if no seperator character available.
*/
protected char seperator()
{
// Past the end of the string?
if ( offset >= name.length() )
{
return 0;
}
// Before the start of the string?
if ( offset <= 0 )
{
return 0;
}
return name.charAt( offset - 1 );
}
protected String getName()
{
return name;
}
protected String getExtension()
{
return extension;
}
protected String remaining()
{
if ( offset >= name.length() )
{
return null;
}
String end = name.substring( offset );
offset = name.length();
return end;
}
protected String nextNonVersion()
{
boolean done = false;
StringBuffer ver = new StringBuffer();
// Any text upto the end of a special case is considered non-version.
Matcher specialMat = mavenPluginPattern.matcher( name );
if ( specialMat.find() )
{
ver.append( name.substring( offset, specialMat.end() ) );
offset = specialMat.end() + 1;
}
while ( !done )
{
int initialOffset = offset;
String section = next();
if ( section == null )
{
done = true;
}
else if ( !VersionUtil.isVersion( section ) )
{
if ( ver.length() > 0 )
{
ver.append( '-' );
}
ver.append( section );
}
else
{
offset = initialOffset;
done = true;
}
}
return ver.toString();
}
protected String nextVersion()
{
boolean done = false;
StringBuffer ver = new StringBuffer();
while ( !done )
{
int initialOffset = offset;
String section = next();
if ( section == null )
{
done = true;
}
else if ( VersionUtil.isVersion( section ) )
{
if ( ver.length() > 0 )
{
ver.append( '-' );
}
ver.append( section );
}
else
{
offset = initialOffset;
done = true;
}
}
return ver.toString();
}
}