package org.infinispan.lucene; import java.util.regex.Pattern; import org.infinispan.lucene.logging.Log; import org.infinispan.persistence.keymappers.TwoWayKey2StringMapper; import org.infinispan.util.logging.LogFactory; /** * To configure a JdbcStringBasedCacheStoreConfig for the Lucene Directory, use this * Key2StringMapper implementation. * * @see org.infinispan.persistence.jdbc.configuration.JdbcStringBasedStoreConfigurationBuilder#key2StringMapper(String) * * @author Sanne Grinovero * @since 4.1 */ @SuppressWarnings("unchecked") public final class LuceneKey2StringMapper implements TwoWayKey2StringMapper { /** * The pipe character was chosen as it's illegal to have a pipe in a filename, so we * don't have to escape the filenames generated by Lucene. */ static final Pattern singlePipePattern = Pattern.compile("\\|"); private static final Log log = LogFactory.getLog(LuceneKey2StringMapper.class, Log.class); @Override public boolean isSupportedType(Class<?> keyType) { return (keyType == ChunkCacheKey.class || keyType == FileCacheKey.class || keyType == FileListCacheKey.class || keyType == FileReadLockKey.class); } @Override public String getStringMapping(Object key) { return key.toString(); } /** * This method has to perform the inverse transformation of the keys used in the Lucene * Directory from String to object. So this implementation is strongly coupled to the * toString method of each key type. * * @see ChunkCacheKey#toString() * @see FileCacheKey#toString() * @see FileListCacheKey#toString() * @see FileReadLockKey#toString() */ @Override public Object getKeyMapping(String key) { if (key == null) { throw new IllegalArgumentException("Not supporting null keys"); } // ChunkCacheKey: "C|" + fileName + "|" + chunkId + "|" + bufferSize "|" + indexName + "|" + affinitySegmentId; // FileCacheKey : "M|" + fileName + "|"+ indexName + "|" + affinitySegmentId; // FileListCacheKey : "*|" + indexName + "|" + affinitySegmentId; // FileReadLockKey : "RL|" + fileName + "|"+ indexName + "|" + affinitySegmentId; String[] split = singlePipePattern.split(key); switch (split[0]) { case "C": { if (split.length != 6) { throw log.keyMappperUnexpectedStringFormat(key); } final String indexName = split[4]; final String fileName = split[1]; final int chunkId = toInt(split[2], key); final int bufferSize = toInt(split[3], key); final int affinitySegmentId = toInt(split[5], key); return new ChunkCacheKey(indexName, fileName, chunkId, bufferSize, affinitySegmentId); } case "M": { if (split.length != 4) throw log.keyMappperUnexpectedStringFormat(key); final String indexName = split[2]; final String fileName = split[1]; final int affinitySegmentId = toInt(split[3], key); return new FileCacheKey(indexName, fileName, affinitySegmentId); } case "*": { if (split.length != 3) throw log.keyMappperUnexpectedStringFormat(key); final String indexName = split[1]; final int affinitySegmentId = toInt(split[2], key); return new FileListCacheKey(indexName, affinitySegmentId); } case "RL": { if (split.length != 4) throw log.keyMappperUnexpectedStringFormat(key); final String indexName = split[2]; final String fileName = split[1]; final int affinitySegmentId = toInt(split[3], key); return new FileReadLockKey(indexName, fileName, affinitySegmentId); } default: throw log.keyMappperUnexpectedStringFormat(key); } } private int toInt(String token, String fullInput) { try { return Integer.parseInt(token); } catch (NumberFormatException nfe) { throw log.keyMappperUnexpectedStringFormat(fullInput); } } }