001/* 002 * Syncany, www.syncany.org 003 * Copyright (C) 2011-2016 Philipp C. Heckel <philipp.heckel@gmail.com> 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU General Public License as published by 007 * the Free Software Foundation, either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU General Public License for more details. 014 * 015 * You should have received a copy of the GNU General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018package org.syncany.plugins.transfer.files; 019 020import java.util.regex.Matcher; 021import java.util.regex.Pattern; 022 023import org.syncany.database.MultiChunkEntry.MultiChunkId; 024import org.syncany.plugins.transfer.StorageException; 025import org.syncany.util.StringUtil; 026 027/** 028 * The multichunk file represents a multichunk on the remote storage. 029 * 030 * <p><b>Name pattern:</b> The name pattern of a multichunk file is 031 * <b>multichunk-<multichunkid></b>. Initializing an 032 * instance with a non-matching name will throw an exception. 033 * 034 * @author Philipp C. Heckel (philipp.heckel@gmail.com) 035 */ 036public class MultichunkRemoteFile extends RemoteFile { 037 private static final Pattern NAME_PATTERN = Pattern.compile("multichunk-([a-f0-9]+)"); 038 private static final String NAME_FORMAT = "multichunk-%s"; 039 040 private byte[] multiChunkId; 041 042 /** 043 * Initializes a new multichunk file, given a name. This constructor might 044 * be called by the {@link RemoteFile#createRemoteFile(String, Class) createRemoteFile()} 045 * method of the {@link RemoteFile}. 046 * 047 * <p>If the pattern matches, the multichunk identifier is set and can be 048 * queried by {@link #getMultiChunkId()}. 049 * 050 * @param name Multichunk file name; <b>must</b> always match the {@link #NAME_PATTERN} 051 * @throws StorageException If the name is not match the name pattern 052 */ 053 public MultichunkRemoteFile(String name) throws StorageException { 054 super(name); 055 } 056 057 /** 058 * Initializes a new multichunk file, given a multichunk identifier 059 * 060 * @param multiChunkId The identifier of the multichunk 061 * @throws StorageException Never throws an exception 062 */ 063 public MultichunkRemoteFile(MultiChunkId multiChunkId) throws StorageException { 064 super(String.format(NAME_FORMAT, multiChunkId.toString())); 065 } 066 067 /** 068 * Returns the multichunk identifier 069 */ 070 public byte[] getMultiChunkId() { 071 return multiChunkId; 072 } 073 074 @Override 075 protected String validateName(String name) throws StorageException { 076 Matcher matcher = NAME_PATTERN.matcher(name); 077 078 if (!matcher.matches()) { 079 throw new StorageException(name + ": remote filename pattern does not match: " + NAME_PATTERN.pattern() + " expected."); 080 } 081 082 try { 083 multiChunkId = StringUtil.fromHex(matcher.group(1)); 084 } 085 catch (Exception e) { 086 throw new StorageException(name + ": remote filename pattern does not match (invalid hex): " + NAME_PATTERN.pattern() + " expected."); 087 } 088 089 return name; 090 } 091}