Package anvil.session.net

Source Code of anvil.session.net.ClientSessionContainer$SessionCleaner

/*
* $Id: ClientSessionContainer.java,v 1.6 2002/09/16 08:05:07 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.session.net;

import java.util.Enumeration;
import java.net.Socket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.io.IOException;
import java.io.PrintStream;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.io.BufferedOutputStream;

import anvil.server.Zone;
import anvil.server.ConfigurationError;
import anvil.server.SessionContainerPreferences;
import anvil.session.AbstractSessionEventHandler;
import anvil.session.SessionContainer;
import anvil.session.Session;
import anvil.java.io.GenericInputStream;
import anvil.java.util.Hashlist;
import anvil.java.util.BindingEnumeration;
import anvil.core.Any;
import anvil.core.Serialization;
import anvil.core.UnserializationException;
import anvil.util.Conversions;

/**
* interface ClientSessionContainer
*
* @author: Jani Lehtim�ki
*/
public class ClientSessionContainer extends AbstractSessionEventHandler implements SessionContainer
{

  protected InetAddress _address;
  protected int _port;
  protected Socket _socket;
  protected GenericInputStream _input;
  protected PrintStream _output;
  protected Object _lock = new Object();
  protected Hashlist _sessions = new Hashlist();
  protected SessionCleaner _cleaner;

  public ClientSessionContainer()
  {
  }


  public void initialize(Zone zone)
  {
    super.initialize(zone);
    SessionContainerPreferences prefs = zone.getSessionContainerPreferences();
    String hostname = prefs.getPreference("host", "localhost").toString();
    try {
      _address = InetAddress.getByName(hostname);
    } catch (UnknownHostException e) {
       throw new ConfigurationError("Unknown host '"+hostname+"'");
    }
    _port = prefs.getIntPreference("port", 9000);
    _cleaner = new SessionCleaner("Cleaner-"+_port, prefs.getCheckoutFrequency());
    _cleaner.setDaemon(true);
    _cleaner.start();
    _zone.log().info("SessionContainer " + this + " initialized");
  }


  public void stop()
  {
    closeConnection();
    _cleaner.stop();
    _cleaner = null;
    super.stop()
    _zone.log().info("SessionContainer " + this + " stopped");
  }


  protected synchronized void openConnection()
  {
    if (_input != null) {
      return;
    }
    try {
      _socket = new Socket(_address, _port);
      _input = new GenericInputStream(_socket.getInputStream());
      _output = new PrintStream(new BufferedOutputStream(_socket.getOutputStream()));
    } catch (IOException e) {
      closeConnection();
      throw new RuntimeException("Couldn't establish connection to remote session container: "+e);
    }
  }
 
 
  protected synchronized void closeConnection()
  {
    try {
      if (_output != null) {
        _output.close();
      }
    } catch (Throwable t) {
    }
    try {
      if (_input != null) {
        _input.close();
      }
    } catch (Throwable t) {
    }
    try {
      if (_socket != null) {
        _socket.close();
      }
    } catch (Throwable t) {
    }
    _input = null;
    _output = null;
    _socket = null;
  }
 

  protected void flush()
  {
    _output.flush();
    if (_output.checkError()) {
      closeConnection();
      throw new RuntimeException("IO error while writing to remote session container");
    }
  }
 

  protected void writeLine(String line)
  {
    _output.println(line);
    if (_output.checkError()) {
      closeConnection();
      throw new RuntimeException("IO error while writing to remote session container");
    }
  }
 

  protected String readLine()
  {
    try {
      String line = _input.readLine();
      if (line == null) {
        throw new RuntimeException("IO error while reading to remote session container");
      }
      return line;
    } catch (IOException e) {
      closeConnection();
      throw new RuntimeException("IO error while reading to remote session container: "+e);
   
  }

  protected long readLong()
  {
    try {
      String line = _input.readLine();
      if (line != null) {
        try {
          return Long.parseLong(line);
        } catch (NumberFormatException e) {
        }
      }
    } catch (IOException e) {
      closeConnection();
      throw new RuntimeException("IO error while reading to remote session container: "+e);
    }
    return 0;
  }
   
 

  public void invalidateSessions()
  {
    //operation not allowed
  }


  public Session getSession(String id)
  {
    ClientSession session = null;
    synchronized(_lock) {
      session = (ClientSession)_sessions.get(id);
      if (session != null) {
        if (!session.validate()) {
          session = null;
        }
       
      } else {
        openConnection();
        writeLine("get,"+id);
        flush();
        String status = readLine();
        if (status.equals("ok")) {
          readLine();
          long created = readLong();
          long accessed = readLong();
          session = new ClientSession(id, created, accessed);
          _sessions.put(id, session);
        }
      }
    }
    return session;
  }
 
 
  public void removeSession(Session session)
  {
    synchronized(_lock) {
      String id = session.getId();
      _sessions.remove(id);
      writeLine("invalidate,"+id);
      flush();
      readLine();
    }
  }

 
  public Session createSession(int lifetime, int timeout)
  {
    synchronized(_lock) {
      openConnection();
      writeLine("create,"+lifetime+","+timeout);
      flush();
      String id = readLine();
      long created = readLong();
      long accessed = readLong();
      System.out.println("client-create-id:"+id);
      ClientSession session = new ClientSession(id, created, accessed);
      _sessions.put(id, session);
      System.out.println("client-create:"+session);
      return session;
     
    }
  }
 
 
  public Session[] getSessions()
  {
    synchronized(_lock) {
      openConnection();
      writeLine("list");
      flush();
      int size = (int)readLong();
      Session[] sessions = new Session[size];
      for(int i=0; i<size; i++) {
        String id = readLine();
        long created = readLong();
        long accessed = readLong();
        ClientSession session = (ClientSession)_sessions.get(id);
        if (session == null) {
          session = new ClientSession(id, created, accessed);
          _sessions.put(id, session);
        }
        sessions[i] = session;
      }
      return sessions;
    }
  }


  public class ClientSession implements Session
  {
    protected String _id;
    protected long _created;
    protected long _accessed;
 
    public ClientSession(String id, long created, long accessed)
    {
      _id = id;
      _created = created;
      _accessed = accessed;
    }
   
    public String toString()
    {
      return _id;
    }
   
    public String getId()
    {
      return _id;
    }
   
    public void removeAttribute(String name)
    {
      synchronized(_lock) {
        openConnection();
        writeLine("dispose,"+_id+","+Conversions.URLEncode(name));
        flush();
        readLine();
      }
    }

    public void setAttribute(String name, Object value)
    {
      synchronized(_lock) {
        openConnection();
        writeLine("store,"+_id+","+Conversions.URLEncode(name));
        Any data = Any.create(value);
        try {
          Serialization.serialize(null, data, _output);
          flush();
        } catch (IOException e) {
          closeConnection();
          throw new RuntimeException("IO error while writing to remote session container: "+e);
        }
        readLine();
      }
    }

    public Object getAttribute(String name)
    {
      synchronized(_lock) {
        openConnection();
        writeLine("fetch,"+_id+","+Conversions.URLEncode(name));
        flush();
        if (readLine().equals("ok")) {
          try {
            return Serialization.unserialize(null, _input);
          } catch (IOException e) {
            closeConnection();
            throw new RuntimeException("IO error while reading from remote session container: "+e);
          } catch (UnserializationException e) {
          }
        }
      }
      return null;
    }

    public BindingEnumeration enumeration()
    {
      synchronized(_lock) {
        openConnection();
        writeLine("names,"+_id);
        flush();
        if (readLine().equals("ok")) {
          int size = (int)readLong();
          String[] names = new String[size];
          for(int i=0; i<size; i++) {
            names[i] = readLine();
          }
          return new AttributeEnumeration(names);
        }
      }
      return BindingEnumeration.EMPTY;
    }

    public long getCreationTime()
    {
      return _created;
    }

    public long getLastAccessTime()
    {
      return _accessed;
    }


    public String getCitizen()
    {
      synchronized(_lock) {
        openConnection();
        writeLine("getcitizen,"+_id);
        flush();
        if (readLine().equals("ok")) {
          String citizen = readLine();
          if (citizen.length() > 0) {
            return citizen;
          }
        }
      }
      return null;
    }

   
    public void setCitizen(String citizen)
    {
      synchronized(_lock) {
        openConnection();
        writeLine("setcitizen,"+_id+","+Conversions.URLEncode(citizen));
        flush();
        readLine();
      }
    }
   

    public void touch()
    {
      synchronized(_lock) {
        openConnection();
        writeLine("touch,"+_id);
        flush();
        readLine();
      }
    }

    public void invalidate()
    {
      removeSession(this);
    }


    public boolean validate()
    {
      synchronized(_lock) {
        openConnection();
        writeLine("validate,"+_id);
        flush();
        return readLine().equals("valid");
      }     
    }

    public class AttributeEnumeration implements  BindingEnumeration
    {
      protected String[] _names;
      protected int _index = 0;
     
      public AttributeEnumeration(String[] names)
      {
        _names = names;
      }
     
      public boolean hasMoreElements()
      {
        return _index < _names.length;
      }
     
      public Object nextKey()
      {
        return _names[_index];
      }
     
      public Object nextElement()
      {
        return getAttribute(_names[_index++]);
      }
    }

  }
 

  public class SessionCleaner extends Thread
  {

    protected int _checkout = 5 * 1000;
    protected boolean _running = true;

    public SessionCleaner(String name, int checkout)
    {
      super(name);
      _checkout = checkout * 1000;
    }


    public void shutdown()
    {
      _running = false;
      this.interrupt();
    }


    public void run() {
      _zone.log().info("Starting...");
      while(_running) {
        try {
          sleep(_checkout);
        } catch (InterruptedException e) {
        }
        if (!_running) {
          break;
        }
        synchronized(_lock) {
          Enumeration enum = _sessions.elements();
          while(enum.hasMoreElements()) {
            ClientSession session = (ClientSession)enum.nextElement();
          }
          enum = null;
        }
      }
      _zone.log().info("Shutting down...");
    }
  }

 
}
TOP

Related Classes of anvil.session.net.ClientSessionContainer$SessionCleaner

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.