/*
 * $Id: SimpleStoreKeeper.java,v 1.7 2007/11/05 08:53:45 marbobo Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 *
 * $Log: SimpleStoreKeeper.java,v $
 * Revision 1.7  2007/11/05 08:53:45  marbobo
 * + Bugfix (Statt List werden HashSet benutzt)
 *
 * Revision 1.6  2004/11/10 15:02:49  koppy
 * Projektweite Überarbeitung von Error-Logs, Stacktraces,..
 *
 * Revision 1.5  2003/11/21 14:47:36  koppy
 * Um die Möglichkeit, "Archivleichen" zu entfernen, erweitert
 *
 * Revision 1.4  2003/11/14 15:37:39  jonyp
 * *** empty log message ***
 *
 * Revision 1.3  2003/03/12 00:34:20  koppy
 * Möglichkeit den StoreKeeper dynamisch zu setzen
 *
 * Revision 1.2  2002/11/12 15:33:03  koppy
 * Behandlung von Streams hinzugefügt
 *
 * Revision 1.1  2002/10/21 14:36:15  bigmac
 * *** empty log message ***
 *
 * Revision 1.1  2002/04/05 15:35:21  koppy
 * initial revision
 *
 */
package vkc.server.archive;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.NoSuchElementException;

import vkc.misc.VKCLogManager;
import vkc.util.FileUtils;

/**
 * Die Klasse implementiert einen einfachen (Daten)Lagerverwalter,
 * wo alle Daten als Dateien in EINEM Verzeichnis verwaltet werden 
 * 
 * @author koppy
 */
public class SimpleStoreKeeper implements StoreKeeper {
    private File storageDir = null;
    
    private int modCount = 0;

    /**
     * Konstruktor
     *
     */
    public SimpleStoreKeeper() {
    }

    /**
     * Konstruktor
     *
     * @param storageDir
     */
    public SimpleStoreKeeper(File storageDir) {
        this.setStorageDir(storageDir);
    }

    /**
     * Setzt das Verzeichnis für diesen Datenverwalter
     * @param storageDir
     */
    public void setStorageDir(File storageDir) {
        this.storageDir = storageDir;
    }

    /**
     * Initialisierung
     * @throws IOException
     */
    public void init() throws IOException {
        if (storageDir == null) {
            throw new IOException("StorageDirUrl not set!");
        }
    }

    /**
     * Bindet Byte-Array an Datei mit Namen id
     *
     * @param data - Byte-Array
     * @param   id - Dateiname
     * @author koppy
     */
    public void insert(byte[] data, String id) throws IOException {
        FileUtils.saveByteArray(new File(storageDir, id), data, null, true);
        modCount++;
    }

    /**
     * Loescht die unter id gespeicherten Daten
     *
     * @param   id - Dateiname
     * @author koppy
     */
    public void delete(String id) throws IOException {
        new File(storageDir, id).delete();
        modCount++;
    }

    /**
     * Liefert das Verzeichnis, in welches id gehoert
     *
     * @param   id - Dateiname
     * @author koppy
     */
    public File getTargetDir(String id) {
        return this.storageDir;
    }

    /**
     * Sucht die unter id gespeicherten Daten
     *
     * @param   id - Dateiname
     * @return falls GEFUNDEN, Datei mit Namen id
     *         sonst Verzeichnis, in welches Datei mit Namen id gehört
     * @author koppy
     */
    public File search(String id) throws IOException {
        File dataFile = new File(storageDir, id);

        if (dataFile.exists()) {
            return dataFile;
        }

        return storageDir;
    }
	
	/**
	 * @see vkc.server.archive.StoreKeeper#iterator()
	 */
	public Iterator iterator() {	
		return new IdIterator();
	}    
    
    /**
     * Die Klasse implementiert einen Iterator für
     * alle verfügbaren IDs
     * 
     * @author koppy
     */
	private class IdIterator implements Iterator {
						 
			String current = null;
			int expectedModCount;
			int index = -1;
			File [] files = null;
			
			IdIterator() {					
							
				expectedModCount = modCount;
				if( storageDir != null ){
					files = storageDir.listFiles();	
				}	
				if( files != null && files.length > 0)
					index = 0;
				 			
			}			

			public boolean hasNext() {
				if( files == null )
					return false;			
				
				return index < files.length;
			}

			public Object next() { 
				if (modCount != expectedModCount)
					VKCLogManager.infoLog( this, "ConcurrentModificationException not thrown.");
					
				
				if ( files == null || index >= files.length) 
					throw new NoSuchElementException();
                				
				current = files[index].getName();
				index++;
				return current;
			}

			public void remove() {
				if (current == null)
					throw new IllegalStateException();
				if (modCount != expectedModCount)
					VKCLogManager.infoLog( this, "ConcurrentModificationException not thrown.");
					
								
				try {
					SimpleStoreKeeper.this.delete( current );
					expectedModCount = modCount;
					current = null;
				} catch (IOException e) {					
					VKCLogManager.errorLog(this, "", e.getMessage(),e);
				}				
			}

		}
	
}
