/* PersistentMap.java -- The persistent object naming map
 Copyright (C) 2006 Free Software Foundation, Inc.

 This file is part of GNU Classpath.

 GNU Classpath is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.

 GNU Classpath is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with GNU Classpath; see the file COPYING.  If not, write to the
 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 02110-1301 USA.

 Linking this library statically or dynamically with other modules is
 making a combined work based on this library.  Thus, the terms and
 conditions of the GNU General Public License cover the whole
 combination.

 As a special exception, the copyright holders of this library give you
 permission to link this library with independent modules to produce an
 executable, regardless of the license terms of these independent
 modules, and to copy and distribute the resulting executable under
 terms of your choice, provided that you also meet, for each linked
 independent module, the terms and conditions of the license of that
 module.  An independent module is a module which is not derived from
 or based on this library.  If you modify this library, you may extend
 this exception to your version of the library, but you are not
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */


package gnu.classpath.tools.giop.nameservice;

import gnu.CORBA.NamingService.NamingMap;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Map;

import org.omg.CORBA.ORB;
import org.omg.CosNaming.NameComponent;
import org.omg.CosNaming.NamingContextPackage.AlreadyBound;
import org.omg.CosNaming.NamingContextPackage.InvalidName;

/**
 * The persistent object naming map for the persistent naming service. The
 * inherited (super.) naming map implementation is transient and is used as a
 * cache. During the normal work, the naming map does not read from the disk,
 * just stores the changes there. Map only reads from the disk when it starts.
 * 
 * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
 */
public class PersistentMap
    extends NamingMap
{
  /**
   * The data entry.
   */
  public static class Entry
  {
    String id;

    String kind;

    String ior;

    /**
     * Get the name component node.
     */
    public NameComponent getComponent()
    {
      return new NameComponent(id, kind);
    }

    /**
     * Write the naming map entry to the output stream.
     */
    public void write(OutputStream out) throws IOException
    {
      // Format: id.kind <eoln> ior <eoln><eoln>
      out.write(getKey(id, kind).getBytes());
      out.write('\n');
      out.write(ior.getBytes());
      out.write('\n');
      out.close();
    }

    /**
     * Read the name component from the input stream
     */
    public boolean read(BufferedReader in) throws IOException
    {
      String key = in.readLine();
      String xior = in.readLine();

      if (key != null && xior != null)
        {
          if (key.length() < 2)
            {
              // A single char key cannot have the kind part.
              id = key;
              kind = "";
            }
          else
            {
              // Search for the id/kind splitter, dot:
              int iks = - 1;
              for (int i = 1; i < key.length(); i++)
                {
                  if (key.charAt(i) == '.')
                    // The id is separated from kind by dot, unless preceeded by
                    // the
                    // escape character, \.
                    if (key.charAt(i - 1) != '\\')
                      {
                        iks = i;
                        break;
                      }
                }

              // May also end by dot, if the kind field is missing.
              if (iks < 0)
                {
                  id = key;
                  kind = "";
                }
              else if (iks == key.length() - 1)
                {
                  id = key.substring(0, key.length() - 1);
                  kind = "";
                }
              else
                {
                  id = key.substring(0, iks);
                  kind = key.substring(iks + 1);
                }
            }
          ior = xior;
          return true;
        }
      else
        return false;
    }

    /**
     * Get the key value from the name component.
     * 
     * @param id the component id
     * @param kind the component kind
     * @return the key value
     */
    public String getKey(String id, String kind)
    {
      StringBuffer b = new StringBuffer(id.length() + 8);
      appEscaping(b, id);
      b.append('.');
      if (kind != null && kind.length() > 0)
        appEscaping(b, kind);
      return b.toString();
    }

    /**
     * Append the contents of the string to this string buffer, inserting the
     * escape sequences, where required.
     * 
     * @param b a buffer to append the contents to.
     * @param s a string to append.
     */
    void appEscaping(StringBuffer b, String s)
    {
      char c;
      for (int i = 0; i < s.length(); i++)
        {
          c = s.charAt(i);
          switch (c)
            {
            case '.':
            case '/':
            case '\\':
              b.append('\\');
              b.append(c);
              break;

            default:
              b.append(c);
              break;
            }
        }
    }
  }

  /**
   * The file, where the persistent naming map stores the information. The
   * format of this file is n*(id LF kind LF ior LFLF).
   */
  public final File file;

  /**
   * The naming service ORB, used to obtain and produce the object stringified
   * references.
   */
  ORB orb;
  
  /**
   * If true, all existing data on the file system are discarded.
   */
  boolean reset;

  /**
   * Create the persistent map that stores information in the given file.
   * 
   * @param an_orb the naming service ORB, used to obtain and produce the object
   *          stringified references.
   * @param mapFile the file, where the persistent information is stored.
   * @param a_reset if true, the previous naming data are discarded. If false
   *          (normally expected), they are loaded from the persistent memory to
   *          provide the persistence.
   */
  public PersistentMap(ORB an_orb, File mapFile, boolean a_reset)
  {
    super();
    orb = an_orb;
    file = mapFile;
    reset = a_reset;

    // Initialise the persistent map with existing data.
    if (file.exists() && ! reset)
      {

        BufferedReader in;
        try
          {
            FileInputStream fin = new FileInputStream(file);
            in = new BufferedReader(new InputStreamReader(fin));
            Entry e = new Entry();
            boolean ok;

            while (e.read(in))
              {
                org.omg.CORBA .Object object = string_to_object(e.ior);
                orb.connect(object);
                map.put(e.getComponent(), object);
              }
          }
        catch (Exception ex)
          {
            InternalError ierr = new InternalError(file.getAbsolutePath());
            ierr.initCause(ex);
            throw ierr;
          }
      }
  }
  
  /**
   * Restore object from its string description.
   * 
   * @param description the string, describing the object
   * 
   * @return the object.
   */
  protected org.omg.CORBA.Object string_to_object(String description)
  {
    return orb.string_to_object(description);
  }
  
  /**
   * Convert the object to its string description
   * 
   * @param object the object to convert
   * @return the string description of the object
   */
  protected String object_to_string(org.omg.CORBA .Object object)
  {
      return orb.object_to_string(object);    
  }

  /**
   * Put the given GIOP object, specifying the given name as a key. If the entry
   * with the given name already exists, or if the given object is already
   * mapped under another name, the {@link AlreadyBound} exception will be
   * thrown.
   * 
   * @param name the name
   * @param object the object
   */
  public void bind(NameComponent name, org.omg.CORBA.Object object)
      throws AlreadyBound, InvalidName
  {
    if (!containsKey(name))
      {
        super.bind(name, object);
        register(name, object);
      }
    else
      throw new AlreadyBound(name.id + "." + name.kind);
  }

  /**
   * Put the given CORBA object, specifying the given name as a key. Remove all
   * pre - existing mappings for the given name and object.
   * 
   * @param name the name.
   * @param object the object
   */
  public void rebind(NameComponent name, org.omg.CORBA.Object object)
      throws InvalidName
  {
    if (containsKey(name))
      {
        org.omg.CORBA.Object existing = get(name);
        String ior = object_to_string(object);
        String xior = object_to_string(existing);
        
        // Same name and same ior - nothing to do.
        if (ior.equals(xior))
          return;
        else
          remove(name);
      }

    Iterator iter = entries().iterator();
    Map.Entry item;

    // Remove the existing mapping for the given object, if present.
    while (iter.hasNext())
      {
        item = (Map.Entry) iter.next();
        if (item.getValue().equals(object))
          iter.remove();
      }

    map.put(name, object);
    register(name, object);
  }

  /**
   * Removes the given name, if present.
   * 
   * @param name a name to remove.
   */
  public void remove(NameComponent name)
  {
    super.remove(name);
    unregister(name);
  }

  /**
   * Register this name - object pair in the persistent storage.
   * 
   * @param name the name.
   * @param object the object
   */
  public void register(NameComponent name, org.omg.CORBA.Object object)
  {
    // If this key is already known, and this is the same object,
    // then return without action.
    String ior = object_to_string(object);

    synchronized (file)
      {
        try
          {
            FileOutputStream fou;

            if (! file.exists())
              fou = new FileOutputStream(file);
            else
              fou = new FileOutputStream(file, true);

            Entry e = new Entry();
            e.id = name.id;
            e.kind = name.kind;
            e.ior = ior;
            e.write(fou);
            fou.close();
          }
        catch (Exception e)
          {
            InternalError ierr = new InternalError(file.getAbsolutePath());
            ierr.initCause(e);
            throw ierr;
          }
      }
  }

  /**
   * Remove this name from the persistent storage.
   * 
   * @param name the name to remove
   */
  public void unregister(NameComponent name)
  {
    synchronized (file)
      {
        try
          {
            File nf = new File(file.getParent(), file.getName() + "_t");
            FileInputStream fin = new FileInputStream(file);
            FileOutputStream fou = new FileOutputStream(nf);
            BufferedOutputStream ou = new BufferedOutputStream(fou);

            BufferedReader in = new BufferedReader(new InputStreamReader(fin));
            String s;
            String nk = name.kind;
            if (nk == null)
              nk = "";

            Entry e = new Entry();

            while (e.read(in))
              {
                if (e.id.equals(name.id) && e.kind.equals(nk))
                  {
                    // Do nothing - skip.
                  }
                else
                  {
                    e.write(ou);
                  }
              }

            File deleteIt = new File(file.getParent(), file.getName() + "_d");
            if (deleteIt.exists())
              deleteIt.delete();

            if (! file.renameTo(deleteIt))
              throw new IOException(file.getAbsolutePath() + " rename failed");

            if (! nf.renameTo(file))
              throw new IOException(file.getAbsolutePath() + " rename failed");
          }
        catch (Exception e)
          {
            InternalError ierr = new InternalError(file.getAbsolutePath());
            ierr.initCause(e);
            throw ierr;
          }
      }
  }
}
