This project has retired. For details please refer to its Attic page.
Source code
001package org.apache.archiva.repository.content.maven2;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.archiva.common.utils.VersionUtil;
023
024import java.util.regex.Matcher;
025import java.util.regex.Pattern;
026
027/**
028 * Generic Filename Parser for use with layout routines.
029 *
030 *
031 */
032public class FilenameParser
033{
034    private String name;
035
036    private String extension;
037
038    private int offset;
039
040    private static final Pattern mavenPluginPattern = Pattern.compile( "(maven-.*-plugin)|(.*-maven-plugin)" );
041
042    private static final Pattern extensionPattern =
043        Pattern.compile( "(\\.tar\\.gz$)|(\\.tar\\.bz2$)|(\\.[\\-a-z0-9]*$)", Pattern.CASE_INSENSITIVE );
044
045    private static final Pattern SNAPSHOT_PATTERN = Pattern.compile( "^([0-9]{8}\\.[0-9]{6}-[0-9]+)(.*)$" );
046
047    private static final Pattern section = Pattern.compile( "([^-]*)" );
048
049    private Matcher matcher;
050
051    public FilenameParser( String filename )
052    {
053        this.name = filename;
054
055        Matcher mat = extensionPattern.matcher( name );
056        if ( mat.find() )
057        {
058            extension = filename.substring( mat.start() + 1 );
059            name = name.substring( 0, name.length() - extension.length() - 1 );
060        }
061
062        matcher = section.matcher( name );
063
064        reset();
065    }
066
067    public void reset()
068    {
069        offset = 0;
070    }
071
072    public String next()
073    {
074        // Past the end of the string.
075        if ( offset > name.length() )
076        {
077            return null;
078        }
079
080        // Return the next section.
081        if ( matcher.find( offset ) )
082        {
083            // Return found section.
084            offset = matcher.end() + 1;
085            return matcher.group();
086        }
087
088        // Nothing to return.
089        return null;
090    }
091
092    protected String expect( String expected )
093    {
094        String value = null;
095
096        if ( name.startsWith( expected, offset ) )
097        {
098            value = expected;
099        }
100        else if ( VersionUtil.isGenericSnapshot( expected ) )
101        {
102            String version = name.substring( offset );
103
104            // check it starts with the same version up to the snapshot part
105            int leadingLength = expected.length() - 9;
106            if ( leadingLength > 0 && version.startsWith( expected.substring( 0, leadingLength ) ) &&
107                version.length() > leadingLength )
108            {
109                // If we expect a non-generic snapshot - look for the timestamp
110                Matcher m = SNAPSHOT_PATTERN.matcher( version.substring( leadingLength + 1 ) );
111                if ( m.matches() )
112                {
113                    value = version.substring( 0, leadingLength + 1 ) + m.group( 1 );
114                }
115            }
116        }
117
118        if ( value != null )
119        {
120            // Potential hit. check for '.' or '-' at end of expected.
121            int seperatorOffset = offset + value.length();
122
123            // Test for "out of bounds" first. 
124            if ( seperatorOffset >= name.length() )
125            {
126                offset = name.length();
127                return value;
128            }
129
130            // Test for seperator char.
131            char seperatorChar = name.charAt( seperatorOffset );
132            if ( ( seperatorChar == '-' ) || ( seperatorChar == '.' ) )
133            {
134                offset = seperatorOffset + 1;
135                return value;
136            }
137        }
138
139        return null;
140    }
141
142    /**
143     * Get the current seperator character.
144     *
145     * @return the seperator character (either '.' or '-'), or 0 if no seperator character available.
146     */
147    protected char seperator()
148    {
149        // Past the end of the string?
150        if ( offset >= name.length() )
151        {
152            return 0;
153        }
154
155        // Before the start of the string?
156        if ( offset <= 0 )
157        {
158            return 0;
159        }
160
161        return name.charAt( offset - 1 );
162    }
163
164    protected String getName()
165    {
166        return name;
167    }
168
169    public String getExtension()
170    {
171        return extension;
172    }
173
174    public String remaining()
175    {
176        if ( offset >= name.length() )
177        {
178            return null;
179        }
180
181        String end = name.substring( offset );
182        offset = name.length();
183        return end;
184    }
185
186    public String nextNonVersion()
187    {
188        boolean done = false;
189
190        StringBuilder ver = new StringBuilder();
191
192        // Any text upto the end of a special case is considered non-version. 
193        Matcher specialMat = mavenPluginPattern.matcher( name );
194        if ( specialMat.find() )
195        {
196            ver.append( name.substring( offset, specialMat.end() ) );
197            offset = specialMat.end() + 1;
198        }
199
200        while ( !done )
201        {
202            int initialOffset = offset;
203            String section = next();
204            if ( section == null )
205            {
206                done = true;
207            }
208            else if ( !VersionUtil.isVersion( section ) )
209            {
210                if ( ver.length() > 0 )
211                {
212                    ver.append( '-' );
213                }
214                ver.append( section );
215            }
216            else
217            {
218                offset = initialOffset;
219                done = true;
220            }
221        }
222
223        return ver.toString();
224    }
225
226    protected String nextVersion()
227    {
228        boolean done = false;
229
230        StringBuilder ver = new StringBuilder();
231
232        while ( !done )
233        {
234            int initialOffset = offset;
235            String section = next();
236            if ( section == null )
237            {
238                done = true;
239            }
240            else if ( VersionUtil.isVersion( section ) )
241            {
242                if ( ver.length() > 0 )
243                {
244                    ver.append( '-' );
245                }
246                ver.append( section );
247            }
248            else
249            {
250                offset = initialOffset;
251                done = true;
252            }
253        }
254
255        return ver.toString();
256    }
257
258
259}