All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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