de.rpgframework.character.LocalUserDatabase Maven / Gradle / Ivy
The newest version!
package de.rpgframework.character;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.nio.file.AccessDeniedException;
import java.nio.file.DirectoryStream;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;
import de.rpgframework.character.Attachment.Format;
import de.rpgframework.character.Attachment.Type;
import de.rpgframework.character.CharacterIOException.ErrorCode;
import de.rpgframework.core.RoleplayingSystem;
/**
*
*/
public class LocalUserDatabase implements IUserDatabase {
private final static Logger logger = System.getLogger(LocalUserDatabase.class.getPackageName());
private final static String INDEX = "metadata.properties";
private RoleplayingSystem rules;
private Map cache;
private Path localBaseDir;
private Path myselfPlayerDir;
//-------------------------------------------------------------------
public LocalUserDatabase(Path playerDir, RoleplayingSystem rules) throws CharacterIOException {
this.rules = rules;
cache = new HashMap();
localBaseDir = playerDir;
myselfPlayerDir = localBaseDir.resolve("myself");
logger.log(Level.INFO, "Expect player data at "+localBaseDir);
System.setProperty("chardir", myselfPlayerDir.resolve(rules.name().toLowerCase()).toString());
// Ensure that directory exists
try {
Files.createDirectories(localBaseDir);
Files.createDirectories(myselfPlayerDir);
} catch (IOException e) {
logger.log(Level.ERROR, "Could not create player directory: "+e);
throw new CharacterIOException(ErrorCode.FILESYSTEM_WRITE, null, "Could not create directories", localBaseDir.toString(), e);
}
}
//-------------------------------------------------------------------
/**
* Read character data from a directory containing:
* portrait.(gif|jpg|png|img) - a character image
* *.xml - a rulespecific characer representation. The filename (without suffix) is used as default character name
* *.pdf - a view-only characer representation
*/
private synchronized FileBasedCharacterHandle loadCharacter(RoleplayingSystem system, Path charDir) throws CharacterIOException {
logger.log(Level.TRACE, "ENTER loadCharacter({0}, {1})", system, charDir);
try {
// Try to read UUID from metadata
UUID uuid = UUID.randomUUID();
Path meta = charDir.resolve(INDEX);
Properties pro = new Properties();
try {
pro.load(new FileReader(meta.toFile()));
uuid = UUID.fromString(pro.getProperty(FileBasedCharacterHandle.UUID));
} catch (Exception e) {
throw new CharacterIOException(ErrorCode.FILESYSTEM_READ, "Metadata", e.getMessage(), meta.toString(), e);
}
FileBasedCharacterHandle handle = new FileBasedCharacterHandle(charDir, system, uuid);
handle.setProperties(pro);
handle.setLoadAttemptMade(true);
handle.setPath(charDir);
try {
handle.setLastModified(Date.from( Files.getLastModifiedTime(charDir).toInstant()) );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Read attachments timestamps
for (Attachment attach : handle.getAttachments()) {
try {
attach.setLastModified(Date.from( Files.getLastModifiedTime(attach.getLocalFile()).toInstant()) );
// logger.log(Level.INFO, "Timestamp of {0} is {1}", attach.getLocalFile(), attach.getLastModified());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return handle;
} finally {
logger.log(Level.TRACE, "LEAVE loadCharacter");
}
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#getCharacters()
*/
@Override
public List getCharacters() throws IOException {
logger.log(Level.DEBUG, "ENTER: getCharacters()");
List ret = new ArrayList<>();
try {
if (!cache.isEmpty()) {
ret.addAll(cache.values());
} else {
try {
DirectoryStream userDir = Files.newDirectoryStream(myselfPlayerDir);
for (Path systemDir : userDir) {
if (!Files.isDirectory(systemDir))
continue;
if (systemDir.getFileName().toString().endsWith(".git"))
continue;
RoleplayingSystem system = null;
try {
system = RoleplayingSystem.valueOf(systemDir.getFileName().toString().toUpperCase());
} catch (IllegalArgumentException e1) {
logger.log(Level.ERROR, "Found directory that does not match roleplaying system: "+systemDir);
continue;
}
logger.log(Level.DEBUG, "Found directory with "+system+" characters");
/*
* Expect each character within its own directory
*/
for (Path charDir : Files.newDirectoryStream(systemDir)) {
if (!Files.isDirectory(charDir))
continue;
String dirName = charDir.getFileName().toString();
try {
UUID uuid = null;
FileBasedCharacterHandle handle = null;
try { uuid = UUID.fromString(dirName); } catch (Exception e) {
logger.log(Level.ERROR, "Directory is not a UUID: {0}", charDir.getFileName());
uuid = UUID.randomUUID();
}
if (uuid!=null) {
handle = cache.get(uuid);
if (handle!=null) {
logger.log(Level.ERROR, "Char {0} found in cache", uuid);
}
}
if (handle==null) {
handle = loadCharacter(system, charDir);
}
ret.add(handle);
if (handle!=null && !cache.containsKey(uuid)) {
cache.put(uuid,handle);
logger.log(Level.INFO, "Added character to cache: "+handle.getName());
}
} catch (Exception e) {
logger.log(Level.ERROR, "Failed loading character in "+charDir,e);
e.printStackTrace();
}
}
}
} catch (Exception e) {
logger.log(Level.ERROR, "Failed loading characters",e);
}
}
// Sort
Collections.sort(ret, new Comparator() {
public int compare(CharacterHandle handle1, CharacterHandle handle2) {
if (handle1.getLastModified()==null && handle2.getLastModified()!=null) return 1;
if (handle2.getLastModified()==null && handle1.getLastModified()!=null) return -1;
if (handle1.getLastModified()==null && handle2.getLastModified()==null) return 0;
return handle1.getLastModified().compareTo(handle2.lastModified);
}
});
return ret;
} finally {
logger.log(Level.DEBUG, "LEAVE: getCharacters() returns {0} elements",ret.size());
}
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#storeCharacter(de.rpgframework.character.CharacterHandle)
*/
@Override
public void createCharacter(CharacterHandle rawHandle) throws IOException {
logger.log(Level.DEBUG, "ENTER: createCharacter()");
if (!(rawHandle instanceof FileBasedCharacterHandle))
throw new IllegalArgumentException("Must be FileBasedCharacterHandle");
FileBasedCharacterHandle handle = (FileBasedCharacterHandle)rawHandle;
try {
// Ensure rulesystem directory exists
Path systemDir = myselfPlayerDir.resolve(rules.name().toLowerCase());
if (Files.exists(systemDir)) {
logger.log(Level.DEBUG, "Create directory for {0} characters at {1}", rules, systemDir);
try {
Files.createDirectories(systemDir);
} catch (IOException e) {
throw new CharacterIOException(ErrorCode.FILESYSTEM_WRITE, "System directory", e.getMessage(), systemDir.toString(), e);
}
} else {
logger.log(Level.DEBUG, "Directory for {0} characters already exists at {1}", rules, systemDir);
}
// Create a character directory if necessary
Path charDir = systemDir.resolve(handle.getUUID().toString());
handle.setPath(charDir);
if (!Files.exists(charDir)) {
try {
Files.createDirectories(charDir);
} catch (AccessDeniedException e) {
logger.log(Level.ERROR, "Access denied to "+e.getFile());
throw new CharacterIOException(ErrorCode.FILESYSTEM_WRITE, "Character directory", e.getMessage(), charDir.toString(), e);
} catch (IOException e) {
throw new CharacterIOException(ErrorCode.FILESYSTEM_WRITE, "Character directory", e.getMessage(), charDir.toString(), e);
}
logger.log(Level.INFO, "Created character directory "+charDir);
}
modifyCharacter(handle);
} finally {
logger.log(Level.DEBUG, "LEAVE: createCharacter()");
}
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#modifyCharacter(de.rpgframework.character.CharacterHandle)
*/
@Override
public void modifyCharacter(CharacterHandle rawHandle) throws IOException {
logger.log(Level.DEBUG, "ENTER: modifyCharacter()");
if (!(rawHandle instanceof FileBasedCharacterHandle))
throw new IllegalArgumentException("Must be FileBasedCharacterHandle");
FileBasedCharacterHandle handle = (FileBasedCharacterHandle)rawHandle;
try {
Path charDir = handle.getPath();
if (!Files.exists(charDir)) {
logger.log(Level.ERROR, "Trying to modify a character in a non-existing directory");
throw new FileNotFoundException("Character directory does not exist: "+charDir);
}
// Write properties
Path meta = charDir.resolve(INDEX);
try {
FileBasedCharacterHandle.toProperties(handle, () -> {
try {
return getAttachments(handle);
} catch (IOException e) {
logger.log(Level.ERROR, "Error getting attachments",e);
return List.of();
}
})
.store(new FileWriter(meta.toFile()), "Do not edit");
} catch (IOException e) {
throw new CharacterIOException(ErrorCode.FILESYSTEM_WRITE, "Metadata", e.getMessage(), meta.toString(), e);
}
// Add character to cache
cache.put(handle.getUUID(), handle);
} finally {
logger.log(Level.DEBUG, "LEAVE: modifyCharacter()");
}
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#deleteCharacter(de.rpgframework.character.CharacterHandle)
*/
@Override
public void deleteCharacter(CharacterHandle rawHandle) throws IOException {
if (!(rawHandle instanceof FileBasedCharacterHandle))
throw new IllegalArgumentException("Must be FileBasedCharacterHandle");
logger.log(Level.INFO, "deleteCharacter: "+rawHandle);
FileBasedCharacterHandle handle = (FileBasedCharacterHandle)rawHandle;
Path charDir = handle.getPath();
logger.log(Level.INFO, "Need to delete "+charDir);
try {
Files.walkFileTree(charDir, new SimpleFileVisitor() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
if (e == null) {
Files.delete(dir);
return FileVisitResult.CONTINUE;
} else {
// directory iteration failed
throw e;
}
}
});
Files.deleteIfExists(charDir);
cache.remove(rawHandle.getUUID());
} catch (IOException e) {
logger.log(Level.ERROR, "");
}
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#retrieveCharacter(java.util.UUID)
*/
@Override
public CharacterHandle retrieveCharacter(UUID key) throws IOException {
// TODO Auto-generated method stub
return cache.get(key);
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#createAttachment(de.rpgframework.character.CharacterHandle, de.rpgframework.character.Attachment.Type, de.rpgframework.character.Attachment.Format, java.lang.String)
*/
@Override
public void createAttachment(CharacterHandle rawHandle, Attachment attach) throws IOException {
logger.log(Level.DEBUG, "ENTER: createAttachment({0}, {1}, {2} bytes)", rawHandle.getName(), attach.getFilename(), (attach.getData()!=null) ? attach.getData().length : 0);
try {
if (!(rawHandle instanceof FileBasedCharacterHandle))
throw new IllegalArgumentException("Must be FileBasedCharacterHandle");
FileBasedCharacterHandle handle = (FileBasedCharacterHandle)rawHandle;
byte[] data = attach.getData();
if (attach.getFilename()==null)
throw new NullPointerException("No filename set");
String filename = attach.getFilename();
handle.addAttachment(attach);
Path charDir = handle.getPath();
Path target = charDir.resolve(filename);
// logger.log(Level.DEBUG, "Target is "+target+" path was "+charDir);
// ((BaseCharacterHandle)handle).setPath(target);
attach.setLocalFile(target);
if (attach.getData()!=null) {
try {
logger.log(Level.DEBUG, "Write to {0}", target);
Files.write(target, data);
} catch (IOException e) {
throw new CharacterIOException(ErrorCode.FILESYSTEM_WRITE, "Character data: "+attach.getType(), e.toString(), target.toString(), e);
}
// if there is a modification time in the attachment, set it
if (attach.getLastModified()!=null) {
try {
logger.log(Level.INFO, "Set timestamp to {0}", attach.getLastModified());
Files.setLastModifiedTime(target, FileTime.fromMillis(attach.getLastModified().getTime()));
} catch (IOException e) {
logger.log(Level.WARNING, "Failed changing modification time of "+target, e);
}
} else
handle.setLastModified(new Date(System.currentTimeMillis()));
}
// Update index
try {
Path meta = handle.getPath().resolve(INDEX);
handle.getProperties().store(new FileWriter(meta.toFile()), "Do not edit");
} catch (Exception e) {
logger.log(Level.ERROR, "Failed creating "+INDEX,e);
}
} finally {
logger.log(Level.DEBUG, "LEAVE: createAttachment({0}, {1})", rawHandle.getName(), attach.getFilename());
}
}
//-------------------------------------------------------------------
private Attachment parseAttachment(FileBasedCharacterHandle handle, Path file) throws CharacterIOException {
String filename = file.getFileName().toString();
Type type = Type.CHARACTER;
byte[] data;
try {
data = Files.readAllBytes(file);
} catch (IOException e) {
throw new CharacterIOException(ErrorCode.FILESYSTEM_READ, "Read character data from disk", e.toString(), file.toString(), e);
}
Attachment attach = null;
if (filename.endsWith(".xml"))
attach = new Attachment(handle, UUID.randomUUID(), type, Format.RULESPECIFIC);
else if (filename.endsWith(".html"))
attach = new Attachment(handle, UUID.randomUUID(), type, Format.HTML);
else if (filename.endsWith(".txt"))
attach = new Attachment(handle, UUID.randomUUID(), type, Format.TEXT);
else if (filename.endsWith(".pdf"))
attach = new Attachment(handle, UUID.randomUUID(), type, Format.PDF);
else if (filename.endsWith(".img"))
attach = new Attachment(handle, UUID.randomUUID(), type, Format.IMAGE);
else if (filename.endsWith(".jpg") || filename.endsWith(".png"))
attach = new Attachment(handle, UUID.randomUUID(), type, Format.IMAGE);
else {
if (filename.endsWith("~")) {
logger.log(Level.WARNING, " Removed Emacs backup file: "+filename);
try {
Files.delete(file);
} catch (IOException e) {
logger.log(Level.WARNING, "Failed deleting file '{}' from disk", file, e);
}
return null;
} else {
logger.log(Level.WARNING, " Found an unsupported file format for character: "+filename);
attach = new Attachment(handle, UUID.randomUUID(), type, Format.RULESPECIFIC_EXTERNAL);
}
}
attach.setFilename(filename);
logger.log(Level.TRACE, " "+file+" is a "+type+" "+attach.getFormat());
attach.setData(data);
try {
attach.setLastModified(new Date(Files.getLastModifiedTime(file).toMillis()));
} catch (IOException e) {
logger.log(Level.WARNING, "Failed changing file time '{}' on disk", file, e);
}
logger.log(Level.DEBUG, " Parsed "+attach);
return attach;
}
//-------------------------------------------------------------------
private Attachment getFirstAttachment(FileBasedCharacterHandle handle, Type type, Format format) throws CharacterIOException {
for (Attachment attach : handle.getAttachments() ) {
if (attach.getType()==type && attach.getFormat()==format)
return attach;
}
return null;
}
//-------------------------------------------------------------------
private void detectAdditionalAttachments(FileBasedCharacterHandle fileHandle) throws CharacterIOException {
Path charDir = fileHandle.getPath();
// Search for more attachments
logger.log(Level.WARNING, "TODO: Check for attachments not in the metadata file");
List knownFilenames = new ArrayList<>();
for (Attachment attach : fileHandle.getAttachments()) {
logger.log(Level.DEBUG, " {0}: {1} \t{2} {3}",attach.getID(),attach.getFilename(),attach.getType(),attach.getFormat());
if (knownFilenames.contains(attach.getFilename())) {
logger.log(Level.WARNING, " Remove duplicate attachment ''{0}'' with UUID {1}", attach.getFilename(), attach.getID());
fileHandle.removeAttachment(attach);
// Write properties
Path meta = charDir.resolve(INDEX);
try {
fileHandle.getProperties().store(new FileWriter(meta.toFile()), "Do not edit");
} catch (IOException e) {
throw new CharacterIOException(ErrorCode.FILESYSTEM_WRITE, "Metadata", e.getMessage(), meta.toString(), e);
}
} else {
knownFilenames.add(attach.getFilename());
}
}
/*
* Interpret remaining files
*/
logger.log(Level.DEBUG, "-----Check remaining files-----------");
DirectoryStream dir = null;
try {
dir = Files.newDirectoryStream(charDir);
} catch (IOException e) {
throw new CharacterIOException(ErrorCode.FILESYSTEM_READ, "Character directory", e.toString(), charDir.toString(), e);
}
for (Path tmp : dir) {
if (!Files.isRegularFile(tmp))
continue;
if (tmp.getFileName().toString().equals("metadata.properties"))
continue;
if (tmp.getFileName().toString().equals(".git"))
continue;
if (tmp.getFileName().toString().endsWith("~"))
continue;
// Do we already know this?
boolean isNew = true;
for (Attachment entry : fileHandle.getAttachments() ) {
Path comp = charDir.resolve(entry.getFilename());
if (comp.equals(tmp)) {
// Already know this
isNew = false;
break;
}
}
if (isNew) {
Attachment attach = parseAttachment(fileHandle, tmp);
if (attach==null) {
continue;
}
/*
* Add files to index, except it is rulespecific character data. In this case
* check that it doesn't exist in index yet
*/
if (attach.getType()==Type.CHARACTER && attach.getFormat()==Format.RULESPECIFIC) {
// Found rulespecific character data
Attachment old = getFirstAttachment(fileHandle, Type.CHARACTER, Format.RULESPECIFIC);
if (old!=null) {
logger.log(Level.WARNING, "Found rulespecific character data in "+tmp+" but already use that from "+old.getFilename());
continue;
}
}
logger.log(Level.WARNING, "Add previously unknown file "+tmp+" as character attachment "+attach);
fileHandle.addAttachment(attach);
}
}
}
//-------------------------------------------------------------------
private void ensureMetadataLoaded(FileBasedCharacterHandle fileHandle) throws IOException {
if (fileHandle.isLoadAttemptMade())
return;
Path charDir = fileHandle.getPath();
logger.log(Level.DEBUG, " char dir in character handle: {0}", charDir);
if (charDir==null) {
logger.log(Level.ERROR, "Character directory not set for filehandle {0}", fileHandle.getName());
throw new NullPointerException("CharDir not set");
}
if (!Files.exists(charDir)) {
logger.log(Level.DEBUG, " character directory does not exist yet");
Files.createDirectory(charDir);
}
Path indexFile = charDir.resolve(INDEX);
if (Files.exists(indexFile)) {
Properties pro = new Properties();
try {
pro.load(new FileReader(indexFile.toFile()));
} catch (IOException e) {
throw new CharacterIOException(ErrorCode.FILESYSTEM_READ, "Metadata", e.toString(), indexFile.toString(), e);
}
FileBasedCharacterHandle.fromProperties(fileHandle, pro);
fileHandle.setLoadAttemptMade(true);
// handle.setProperties(pro);
logger.log(Level.DEBUG, "Found "+fileHandle.getAttachments().size()+" attachments for "+fileHandle.getName());
} else {
detectAdditionalAttachments(fileHandle);
try {
Path meta = fileHandle.getPath().resolve(INDEX);
fileHandle.getProperties().store(new FileWriter(meta.toFile()), "Do not edit");
} catch (Exception e) {
logger.log(Level.ERROR, "Failed creating "+INDEX,e);
}
}
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#getAttachments(de.rpgframework.character.CharacterHandle)
*/
@Override
public List getAttachments(CharacterHandle handle) throws IOException {
logger.log(Level.DEBUG, "ENTER: getAttachments({0})", handle.getName());
try {
if (!handle.getAttachments().isEmpty()) {
return new ArrayList<>(handle.getAttachments());
}
if (!(handle instanceof FileBasedCharacterHandle))
throw new IllegalArgumentException("Must be FileBasedCharacterHandle");
FileBasedCharacterHandle fileHandle = (FileBasedCharacterHandle)handle;
ensureMetadataLoaded(fileHandle);
return new ArrayList<>(fileHandle.getAttachments());
} finally {
logger.log(Level.DEBUG, "LEAVE: getAttachments({0})", handle.getName());
}
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#modifyAttachment(de.rpgframework.character.CharacterHandle, de.rpgframework.character.Attachment)
*/
@Override
public void modifyAttachment(CharacterHandle rawHandle, Attachment attach) throws IOException {
if (!(rawHandle instanceof FileBasedCharacterHandle))
throw new IllegalArgumentException("Must be FileBasedCharacterHandle");
FileBasedCharacterHandle handle = (FileBasedCharacterHandle)rawHandle;
byte[] data = attach.getData();
if (data==null)
throw new NullPointerException("No data in attachment");
if (attach.getFilename()==null)
throw new NullPointerException("No filename set");
String filename = attach.getFilename();
handle.addAttachment(attach);
Path charDir = handle.getPath();
Path target = charDir.resolve(filename);
// logger.log(Level.DEBUG, "Target is "+target+" path was "+charDir);
// ((BaseCharacterHandle)handle).setPath(target);
attach.setLocalFile(target);
try {
logger.log(Level.INFO, "Write to {0}", target);
Files.write(target, data);
} catch (IOException e) {
throw new CharacterIOException(ErrorCode.FILESYSTEM_WRITE, "Character data: "+attach.getType(), e.toString(), target.toString(), e);
}
// if there is a modification time in the attachment, set it
if (attach.getLastModified()!=null) {
try {
logger.log(Level.INFO, "Set timestamp to {0}", attach.getLastModified());
Files.setLastModifiedTime(target, FileTime.fromMillis(attach.getLastModified().getTime()));
} catch (IOException e) {
logger.log(Level.WARNING, "Failed changing modification time of "+target, e);
}
} else
handle.setLastModified(new Date(System.currentTimeMillis()));
// Update index
// Update index
try {
Path meta = handle.getPath().resolve(INDEX);
handle.getProperties().store(new FileWriter(meta.toFile()), "Do not edit");
} catch (Exception e) {
logger.log(Level.ERROR, "Failed creating "+INDEX,e);
}
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#modifyAttachmentData(de.rpgframework.character.CharacterHandle, de.rpgframework.character.Attachment)
*/
@Override
public void modifyAttachmentData(CharacterHandle rawHandle, Attachment attach) throws IOException {
// if (!(rawHandle instanceof FileBasedCharacterHandle))
// throw new IllegalArgumentException("Must be FileBasedCharacterHandle");
//
// FileBasedCharacterHandle handle = (FileBasedCharacterHandle)rawHandle;
if (attach.getLocalFile()==null)
throw new NullPointerException("No local file set");
byte[] data = attach.getData();
Files.write(attach.getLocalFile(), data);
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#getAttachmentData(de.rpgframework.character.CharacterHandle, de.rpgframework.character.Attachment)
*/
@Override
public byte[] getAttachmentData(CharacterHandle rawHandle, Attachment attach) throws IOException {
if (attach.getData()!=null)
return attach.getData();
if (attach.getLocalFile()==null)
throw new NullPointerException("No local file set");
byte[] data = Files.readAllBytes(attach.getLocalFile());
attach.setData(data);
return data;
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#deleteAttachment(de.rpgframework.character.CharacterHandle, de.rpgframework.character.Attachment)
*/
@Override
public void deleteAttachment(CharacterHandle rawHandle, Attachment attach) throws IOException {
if (!(rawHandle instanceof FileBasedCharacterHandle))
throw new IllegalArgumentException("Must be FileBasedCharacterHandle");
FileBasedCharacterHandle handle = (FileBasedCharacterHandle)rawHandle;
logger.log(Level.INFO, "deleteAttachment: "+handle+" = "+attach);
// Remove attachment from memory copy
handle.removeAttachment(attach);
// Remove file on disk
try {
Files.delete(attach.getLocalFile());
} catch (IOException e1) {
logger.log(Level.ERROR, "Failed deleting local file "+attach.getLocalFile(),e1);
}
// Write properties
Path charDir = handle.getPath();
Path meta = charDir.resolve(INDEX);
try {
handle.getProperties().store(new FileWriter(meta.toFile()), "Do not edit");
} catch (IOException e) {
throw new CharacterIOException(ErrorCode.FILESYSTEM_WRITE, "Metadata", e.getMessage(), meta.toString(), e);
}
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#retrieveAttachment(de.rpgframework.character.CharacterHandle, de.rpgframework.character.Attachment)
*/
@Override
public byte[] retrieveAttachment(CharacterHandle rawHandle, Attachment attach) throws IOException {
if (!(rawHandle instanceof FileBasedCharacterHandle))
throw new IllegalArgumentException("Must be FileBasedCharacterHandle");
FileBasedCharacterHandle handle = (FileBasedCharacterHandle)rawHandle;
Path path = handle.getPath();
attach.setData(Files.readAllBytes(path));
return attach.getData();
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#getDatasets()
*/
@Override
public List getDatasets() throws IOException {
// TODO Auto-generated method stub
return null;
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#storeDataset(de.rpgframework.character.DatasetDefinition)
*/
@Override
public void storeDataset(DatasetDefinition value) throws IOException {
// TODO Auto-generated method stub
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#deleteDataset(de.rpgframework.character.DatasetDefinition)
*/
@Override
public void deleteDataset(DatasetDefinition value) throws IOException {
// TODO Auto-generated method stub
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#getDatasetLocalization(de.rpgframework.character.DatasetDefinition, java.lang.String)
*/
@Override
public byte[] getDatasetLocalization(DatasetDefinition value, String lang) throws IOException {
// TODO Auto-generated method stub
return null;
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#storeDatasetLocalization(de.rpgframework.character.DatasetDefinition, java.lang.String, byte[])
*/
@Override
public void storeDatasetLocalization(DatasetDefinition value, String lang, byte[] data) throws IOException {
// TODO Auto-generated method stub
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#deleteDatasetLocalization(de.rpgframework.character.DatasetDefinition, java.lang.String)
*/
@Override
public void deleteDatasetLocalization(DatasetDefinition value, String lang) throws IOException {
// TODO Auto-generated method stub
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#getDatasetFile(de.rpgframework.character.DatasetDefinition, java.lang.String)
*/
@Override
public byte[] getDatasetFile(DatasetDefinition value, String name) throws IOException {
// TODO Auto-generated method stub
return null;
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#storeDatasetFile(de.rpgframework.character.DatasetDefinition, java.lang.String, byte[])
*/
@Override
public void storeDatasetFile(DatasetDefinition value, String name, byte[] data) throws IOException {
// TODO Auto-generated method stub
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.character.IUserDatabase#deleteDatasetFile(de.rpgframework.character.DatasetDefinition, java.lang.String)
*/
@Override
public void deleteDatasetFile(DatasetDefinition value, String name) throws IOException {
// TODO Auto-generated method stub
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy