SimpleDirectoryPersistentCache.java
- /**
- *
- * Copyright © 2011-2019 Florian Schmaus
- *
- * Licensed 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.
- */
- package org.jivesoftware.smackx.caps.cache;
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.util.logging.Level;
- import java.util.logging.Logger;
- import org.jivesoftware.smack.util.PacketParserUtils;
- import org.jivesoftware.smack.util.stringencoder.Base32;
- import org.jivesoftware.smack.util.stringencoder.StringEncoder;
- import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
- /**
- * Simple implementation of an EntityCapsPersistentCache that uses a directory
- * to store the Caps information for every known node. Every node is represented
- * by a file.
- *
- * @author Florian Schmaus
- *
- */
- public class SimpleDirectoryPersistentCache implements EntityCapsPersistentCache {
- private static final Logger LOGGER = Logger.getLogger(SimpleDirectoryPersistentCache.class.getName());
- private final File cacheDir;
- private final StringEncoder<String> filenameEncoder;
- /**
- * Creates a new SimpleDirectoryPersistentCache Object. Make sure that the
- * cacheDir exists and that it's an directory.
- * <p>
- * Default filename encoder {@link Base32}, as this will work on all
- * file systems, both case sensitive and case insensitive. It does however
- * produce longer filenames.
- *
- * @param cacheDir TODO javadoc me please
- */
- public SimpleDirectoryPersistentCache(File cacheDir) {
- this(cacheDir, Base32.getStringEncoder());
- }
- /**
- * Creates a new SimpleDirectoryPersistentCache Object. Make sure that the
- * cacheDir exists and that it's an directory.
- *
- * If your cacheDir is case insensitive then make sure to set the
- * StringEncoder to {@link Base32} (which is the default).
- *
- * @param cacheDir The directory where the cache will be stored.
- * @param filenameEncoder Encodes the node string into a filename.
- */
- public SimpleDirectoryPersistentCache(File cacheDir, StringEncoder<String> filenameEncoder) {
- if (!cacheDir.exists())
- throw new IllegalStateException("Cache directory \"" + cacheDir + "\" does not exist");
- if (!cacheDir.isDirectory())
- throw new IllegalStateException("Cache directory \"" + cacheDir + "\" is not a directory");
- this.cacheDir = cacheDir;
- this.filenameEncoder = filenameEncoder;
- }
- @Override
- public void addDiscoverInfoByNodePersistent(String nodeVer, DiscoverInfo info) {
- File nodeFile = getFileFor(nodeVer);
- try {
- if (nodeFile.createNewFile())
- writeInfoToFile(nodeFile, info);
- } catch (IOException e) {
- LOGGER.log(Level.SEVERE, "Failed to write disco info to file", e);
- }
- }
- @Override
- public DiscoverInfo lookup(String nodeVer) {
- File nodeFile = getFileFor(nodeVer);
- if (!nodeFile.isFile()) {
- return null;
- }
- DiscoverInfo info = null;
- try {
- info = restoreInfoFromFile(nodeFile);
- }
- catch (Exception e) {
- LOGGER.log(Level.WARNING, "Coud not restore info from file", e);
- }
- return info;
- }
- private File getFileFor(String nodeVer) {
- String filename = filenameEncoder.encode(nodeVer);
- return new File(cacheDir, filename);
- }
- @Override
- public void emptyCache() {
- File[] files = cacheDir.listFiles();
- if (files == null) {
- return;
- }
- for (File f : files) {
- f.delete();
- }
- }
- /**
- * Writes the DiscoverInfo stanza to an file
- *
- * @param file TODO javadoc me please
- * @param info TODO javadoc me please
- * @throws IOException if an I/O error occurred.
- */
- private static void writeInfoToFile(File file, DiscoverInfo info) throws IOException {
- try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(file))) {
- dos.writeUTF(info.toXML().toString());
- }
- }
- /**
- * Tries to restore an DiscoverInfo stanza from a file.
- *
- * @param file TODO javadoc me please
- * @return the restored DiscoverInfo
- * @throws Exception if an exception occurs.
- */
- private static DiscoverInfo restoreInfoFromFile(File file) throws Exception {
- String fileContent;
- try (DataInputStream dis = new DataInputStream(new FileInputStream(file))) {
- fileContent = dis.readUTF();
- }
- if (fileContent == null) {
- return null;
- }
- return PacketParserUtils.parseStanza(fileContent);
- }
- }