/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.xwiki.store.filesystem.internal;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
* Internal class for providing static utilities used by multiple classes in this package.
*
* @version $Id: bb4d6368f8f6f3b1d19ead00484423be56b2b519 $
* @since 3.0M2
*/
final class GenericFileUtils
{
/**
* This must precede the version of a file. It has to be URL invalid so that it cannot collide with
* the name of another file. Also no other key can start with ~v because the name of the version
* might be anything. If the prefix was "~b" and a version was made called "ak" then it would collide
* with the DefaultFilesystemStoreTools.BACKUP_FILE_SUFFIX.
*/
private static final String FILE_VERSION_PREFIX = "~v";
/**
* The character set to use for encoding and decoding. This should always be UTF-8.
*/
private static final String CHARSET = "UTF-8";
/**
* Error message to give if CHARSET is unavailable.
*/
private static final String NO_CHARSET =
"UTF-8 not available, this Java VM is not standards compliant!";
/**
* Private constructor for utility class.
*/
private GenericFileUtils()
{
}
/**
* Get a URL encoded version of the string.
* same as URLEncoder.encode(toEncode, "UTF-8") but the checked exception is
* caught since UTF-8 is mandatory for all Java virtual machines.
*
* @param toEncode the string to URL encode.
* @return a URL encoded version of toEncode.
* @see #getURLDecoded(String)
*/
static String getURLEncoded(final String toEncode)
{
try {
return URLEncoder.encode(toEncode, CHARSET);
} catch (UnsupportedEncodingException ex) {
throw new RuntimeException(NO_CHARSET);
}
}
/**
* Get a URL decoded version of the string.
* same as URLEncoder.decode(toDecode, "UTF-8") but the checked exception is
* caught since UTF-8 is mandatory for all Java virtual machines.
*
* @param toDecode the string to URL decode.
* @return a URL decoded version of toDecode.
* @see #getURLEncoded(String)
*/
static String getURLDecoded(final String toDecode)
{
try {
return URLDecoder.decode(toDecode, CHARSET);
} catch (UnsupportedEncodingException ex) {
throw new RuntimeException(NO_CHARSET);
}
}
/**
* Get a version of a filename.
* The filename is URL encoded and the version has "~v" prepended so that it cannot be
* mistaken for part of the filename.
* If the filename contains one or more '.' characters then the version is inserted before
* the last '.' character. Otherwise it is appended to the end.
* This means a file such as:
* file.txt version 1.1 will become file~v1.1.txt and will still be recognized by a text editor
* A file with no extension such as myUnknownFile version 1.1 will become myUnknownFile~v1.1
* Because of URL encoding, a file named file~v1.3.txt of version 1.1 will become
* file%7Ev1.3~1.1.txt and thus will not collide with file.txt version 1.1.
*
* @param filename the name of the file to save. This will be URL encoded.
* @param versionName the name of the version of the file. This will also be URL encoded.
* @return a string representing the filename and version which is guaranteed not to collide
* with any other file gotten through DefaultFilesystemStoreTools.
*/
static String getVersionedFilename(final String filename, final String versionName)
{
final String attachFilename = getURLEncoded(filename);
final String version = getURLEncoded(versionName);
if (attachFilename.contains(".")) {
// file.txt version 1.1 --> file~v1.1.txt
return attachFilename.substring(0, attachFilename.lastIndexOf('.'))
+ FILE_VERSION_PREFIX + version
+ attachFilename.substring(attachFilename.lastIndexOf('.'));
}
// someFile version 2.2 --> someFile~v2.2
return attachFilename + FILE_VERSION_PREFIX + version;
}
}