no message

buko [2002-06-18 12:39:03]
no message
Filename
server/ces/Event.java
server/ces/EventDispatcher.java
server/ces/EventHandlerMultiMap.java
server/ces/EventService.java
server/ces/elvin/ElvinEvent.java
server/scs/ws/event/EventConstants.java
server/scs/ws/event/WorldEntryEvent.java
server/scs/ws/event/WorldEntryFailureEvent.java
server/scs/ws/event/WorldEntrySuccessEvent.java
server/scs/ws/event/WorldEvent.java
server/scs/ws/event/WorldEventMapper.java
server/scs/ws/event/WorldLoginEvent.java
server/scs/ws/event/WorldLoginFailureEvent.java
server/scs/ws/event/WorldLoginSuccessEvent.java
server/scs/ws/view/image/ImageInfo.java
diff --git a/server/ces/Event.java b/server/ces/Event.java
index f50ed77..9073ecb 100644
--- a/server/ces/Event.java
+++ b/server/ces/Event.java
@@ -1,6 +1,7 @@
 package psl.chime4.server.ces;

 import java.io.Serializable;
+import java.util.*;

 /**
  * Defines a basic event. This represents either a change in the state of
@@ -183,4 +184,11 @@ public abstract class Event implements Serializable
     * @param key the value is mapped to in the event
     **/
    public abstract  void remove(String key);
+
+   /**
+    * Get an enumeration over all the keys in this event.
+    *
+    * @return enumeration all the keys in this event
+    **/
+   public abstract Enumeration keys();
 }
diff --git a/server/ces/EventDispatcher.java b/server/ces/EventDispatcher.java
index b5c7c47..9c120fb 100644
--- a/server/ces/EventDispatcher.java
+++ b/server/ces/EventDispatcher.java
@@ -21,16 +21,16 @@ class EventDispatcher extends Thread
    /**
     * Construct a new EventDispatcher.
     *
-    * @param eventQueue queue containing incoming events
-    * @param handlerMap multimap containing event handlers
+    * @param eventQueue      queue containing incoming events
+    * @param handlerMultiMap multimap containing event handlers
     * @throws IllegalArgumentException
     *         if any parameter is <code>null</code>
     **/
    public EventDispatcher(EventQueue eventQueue,
-                          EventHandlerMultiMap handlerMap)
+                          EventHandlerMultiMap handlerMultiMap)
    {
       // check for null
-      if ((eventQueue == null) || (handlerMap == null))
+      if ((eventQueue == null) || (handlerMultiMap == null))
       {
          String msg = "no parameter may be null";
          throw new IllegalArgumentException(msg);
@@ -70,18 +70,23 @@ class EventDispatcher extends Thread
             // remove the next incoming events
             Event event = incomingEvents.getEvent();

+            //System.out.println("ED: got event: " + event);
+
             // get the routing information
             String topic = event.getTopic();
             String host = event.getEventServerHost();
             int port = event.getEventServerPort();

+            //System.out.println("ED: topic=" + topic + ",host=" + host +
+             //  ",port=" + port);
+
             // make sure the routing information was set
             if ((topic == null) || (host == null) || (port <= 0))
             {
                String msg = "event contained no routing information " + event;
                throw new IllegalStateException(msg);
             }
-
+
             // get the correct handler
             EventHandler handler =
                handlerMultiMap.getEventHandler(host, port, topic);
diff --git a/server/ces/EventHandlerMultiMap.java b/server/ces/EventHandlerMultiMap.java
index 58a4bf1..8923151 100644
--- a/server/ces/EventHandlerMultiMap.java
+++ b/server/ces/EventHandlerMultiMap.java
@@ -91,7 +91,6 @@ class EventHandlerMultiMap
                                                     String topic)
    {
       Object key = makeKey(host, port, topic);
-
       return (EventHandler) handlerMap.get(key);
    }

@@ -152,7 +151,7 @@ class EventHandlerMultiMap
     * @throws IllegalArgumentException
     *         if any parameter is <code>null</code>
     **/
-   public boolean isActive(String host, int port, String topic)
+   public synchronized boolean isActive(String host, int port, String topic)
    {
       // check for null
       if ((host == null) || (topic == null))
@@ -190,6 +189,11 @@ class EventHandlerMultiMap

       return buf.toString();
    }
+
+   public String toString()
+   {
+      return getClass() + "[handlerMap=" + handlerMap + "]";
+   }
 }


diff --git a/server/ces/EventService.java b/server/ces/EventService.java
index 6b7ec22..63e0b68 100644
--- a/server/ces/EventService.java
+++ b/server/ces/EventService.java
@@ -1,6 +1,8 @@
 package psl.chime4.server.ces;

 import psl.chime4.server.util.CounterMap;
+import psl.chime4.server.scs.service.*;
+import psl.chime4.server.scs.log.*;

 import java.util.Map;
 import java.util.HashMap;
@@ -12,13 +14,13 @@ import java.util.HashMap;
  * @author Azubuko Obele
  * @version 0.1
  **/
-public abstract class EventService
+public abstract class EventService extends AbstractService
 {
    /** counter map stores the connection count to different servers **/
    private CounterMap connectionCount = new CounterMap();

    /** map for the event handlers **/
-   private EventHandlerMultiMap handlerMultiMap = new EventHandlerMultiMap();
+   private EventHandlerMultiMap handlerMultiMap;

    /** queue for incoming events **/
    private EventQueue eventQueue = new EventQueue();
@@ -29,12 +31,26 @@ public abstract class EventService
    /** event dispatcher for passing incoming events **/
    private EventDispatcher eventDispatcher;

+   /** Logging service **/
+   private LoggingService logService;
+
    /**
     * Construct the basic event service.
     **/
    protected EventService()
    {
-      eventDispatcher = new EventDispatcher(eventQueue, handlerMultiMap);
+
+   }
+
+   /**
+    * Override initialization of this service to start the event service.
+    *
+    * @param params no params need to be passed
+    **/
+   public void initialize(ServiceParamMap params) throws ServiceException
+   {
+      startup();
+      System.out.println("ES: Event Service Started");
    }

    /**
@@ -43,6 +59,8 @@ public abstract class EventService
     **/
    public void startup()
    {
+      handlerMultiMap = new EventHandlerMultiMap();
+      eventDispatcher = new EventDispatcher(eventQueue, handlerMultiMap);
       // start the event dispatcher thread
       eventDispatcher.startup();
       serviceStarted = true;
@@ -288,6 +306,8 @@ public abstract class EventService
       event.setEventServerHost(host);
       event.setEventServerPort(port);

+      System.out.println("[ES] Sending Event: " + event);
+
       // send the event
       sendEvent(host, port, topic, event);
    }
diff --git a/server/ces/elvin/ElvinEvent.java b/server/ces/elvin/ElvinEvent.java
index 24c911c..b248bba 100644
--- a/server/ces/elvin/ElvinEvent.java
+++ b/server/ces/elvin/ElvinEvent.java
@@ -4,6 +4,8 @@ import psl.chime4.server.ces.Event;

 import org.elvin.je4.Notification;

+import java.util.*;
+
 /**
  * Makes an Elvin notification look like a CES Event.
  *
@@ -123,4 +125,19 @@ class ElvinEvent extends Event
     {
         return notif;
     }
+
+    /**
+     * Get an iterator all the keys in this event.
+     *
+     * @return iterator all the keys in this event
+     */
+    public Enumeration keys()
+    {
+       return notif.keys();
+    }
+
+    public String toString()
+    {
+       return notif.toString();
+    }
 }
\ No newline at end of file
diff --git a/server/scs/ws/event/EventConstants.java b/server/scs/ws/event/EventConstants.java
new file mode 100644
index 0000000..cdcef8a
--- /dev/null
+++ b/server/scs/ws/event/EventConstants.java
@@ -0,0 +1,32 @@
+package psl.chime4.server.scs.ws.event;
+
+/**
+ * This interface contains several constants used for defining events.
+ *
+ * @author Azubuko Obele
+ * @version 0.1
+ **/
+public interface EventConstants
+{
+   public static final int WorldLogin = 3000;
+   public static final String WorldLoginUri = "chime:event:world_login";
+
+   public static final int WorldLoginSuccess = 3001;
+   public static final String WorldLoginSuccessUri =
+      "chime:event:world_login_success";
+
+   public static final int WorldLoginFailure = 3002;
+   public static final String WorldLoginFailureUri =
+      "chime:event:world_login_failure";
+
+   public static final int WorldEntry = 3100;
+   public static final String WorldEntryUri = "chime:event:world_entry";
+
+   public static final int WorldEntrySuccess = 3101;
+   public static final String WorldEntrySuccessUri =
+      "chime:event:world_entry_success";
+
+   public static final int WorldEntryFailure = 3102;
+   public static final String WorldEntryFailureUri =
+      "chime:event:world_entry_failure";
+}
\ No newline at end of file
diff --git a/server/scs/ws/event/WorldEntryEvent.java b/server/scs/ws/event/WorldEntryEvent.java
new file mode 100644
index 0000000..fd1e2ce
--- /dev/null
+++ b/server/scs/ws/event/WorldEntryEvent.java
@@ -0,0 +1,54 @@
+package psl.chime4.server.scs.ws.event;
+
+import psl.chime4.server.ces.*;
+
+/**
+ * A request by the Client to the World Service to enter the world.
+ *
+ * @author Azubuko Obele
+ * @version 0.1
+ **/
+public class WorldEntryEvent extends WorldEvent
+{
+   /** username of the client requesting entry **/
+   public String Username;
+
+   /**
+    * Construct the event with the passed parameters.
+    *
+    * @param username name of the user sending the event
+    * @throws IllegalArgumentException
+    *         if <code>username</code> is <code>null</code>
+    **/
+   public WorldEntryEvent(String username)
+   {
+      super(EventConstants.WorldEntry, EventConstants.WorldEntryUri);
+
+      if (username == null)
+      {
+         String msg = "username cannot be null";
+         throw new IllegalArgumentException(msg);
+      }
+
+      this.Username = username;
+   }
+
+   /**
+    * Construct the event from a Ces Event.
+    *
+    * @param event event containing the info
+    **/
+   public WorldEntryEvent(Event event)
+   {
+      super(event);
+
+      this.Username = event.getString("client.name");
+   }
+
+   public Event toCesEvent(Event event)
+   {
+      event = super.toCesEvent(event);
+      event.put("client.name", Username);
+      return event;
+   }
+}
\ No newline at end of file
diff --git a/server/scs/ws/event/WorldEntryFailureEvent.java b/server/scs/ws/event/WorldEntryFailureEvent.java
new file mode 100644
index 0000000..ca3e2c3
--- /dev/null
+++ b/server/scs/ws/event/WorldEntryFailureEvent.java
@@ -0,0 +1,63 @@
+package psl.chime4.server.scs.ws.event;
+
+import psl.chime4.server.ces.*;
+
+/**
+ * Sent by the World Service to the Client indicating that she may not enter
+ * the world.
+ *
+ * @author Azubuko Obele
+ * @version 0.1
+ **/
+public class WorldEntryFailureEvent extends WorldEvent
+{
+   /** name of the world that rejected entry **/
+   public String WorldName;
+
+   /** reason entry was rejected **/
+   public String Reason;
+
+   /**
+    * Construct the event from the passed parameters.
+    *
+    * @param worldName name of the world denying entry
+    * @param reason    reason the world is being denied entry
+    * @throws IllegalArgumentException
+    *         if <code>worldName</code> is <code>null</code>
+    **/
+   public WorldEntryFailureEvent(String worldName, String reason)
+   {
+      super(EventConstants.WorldEntryFailure,
+            EventConstants.WorldEntryFailureUri);
+
+      if (worldName == null)
+      {
+         String msg = "worldName cannot be null";
+         throw new IllegalArgumentException(msg);
+      }
+
+      this.WorldName = worldName;
+      this.Reason = reason;
+   }
+
+   /**
+    * Construct the event from the passed Ces event.
+    *
+    * @param event event containing the info
+    **/
+   public WorldEntryFailureEvent(Event event)
+   {
+      super(event);
+
+      this.WorldName = event.getString("world.name");
+      this.Reason = event.getString("reason");
+   }
+
+   public Event toCesEvent(Event event)
+   {
+      event = super.toCesEvent(event);
+      event.put("world.name", WorldName);
+      event.put("reason", Reason);
+      return event;
+   }
+}
\ No newline at end of file
diff --git a/server/scs/ws/event/WorldEntrySuccessEvent.java b/server/scs/ws/event/WorldEntrySuccessEvent.java
new file mode 100644
index 0000000..faefb8c
--- /dev/null
+++ b/server/scs/ws/event/WorldEntrySuccessEvent.java
@@ -0,0 +1,71 @@
+package psl.chime4.server.scs.ws.event;
+
+import psl.chime4.server.ces.*;
+
+/**
+ * Sent by the world to the client to indicate that they may enter the world
+ * through a specific door and into a specific room.
+ *
+ * @author Azubuko Obele
+ * @version 0.1
+ **/
+public class WorldEntrySuccessEvent extends WorldEvent
+{
+   /** name of the world sending the event **/
+   public String WorldName;
+
+   /** id of the room the client may enter **/
+   public int RoomID;
+
+   /** id of the door the client should pass through **/
+   public int DoorID;
+
+   /**
+    * Construct the event from the passed parameters.
+    *
+    * @param worldName name of the world that accepted the entry request
+    * @param roomID    room the client should enter
+    * @param doorID    door the client should pass through
+    * @throws IllegalArgumentException
+    *         if <code>worldName</code> is <code>null</code>
+    **/
+   public WorldEntrySuccessEvent(String worldName, int roomID, int doorID)
+   {
+      super(EventConstants.WorldEntrySuccess,
+            EventConstants.WorldEntrySuccessUri);
+
+      if (worldName == null)
+      {
+         String msg = "worldName cannot be null";
+         throw new IllegalArgumentException(msg);
+      }
+
+      this.WorldName = worldName;
+      this.RoomID = roomID;
+      this.DoorID = doorID;
+   }
+
+   /**
+    * Construct the event from a Ces Event.
+    *
+    * @param event Ces Event containing the info
+    **/
+   public WorldEntrySuccessEvent(Event event)
+   {
+      super(event);
+
+      this.WorldName = event.getString("world.name");
+      this.RoomID = event.getInteger("room.id");
+      this.DoorID = event.getInteger("door.id");
+   }
+
+   public Event toCesEvent(Event event)
+   {
+      event = super.toCesEvent(event);
+
+      event.put("world.name", WorldName);
+      event.put("room.id" , RoomID);
+      event.put("door.id", DoorID);
+      return event;
+   }
+}
\ No newline at end of file
diff --git a/server/scs/ws/event/WorldEvent.java b/server/scs/ws/event/WorldEvent.java
new file mode 100644
index 0000000..67b38d1
--- /dev/null
+++ b/server/scs/ws/event/WorldEvent.java
@@ -0,0 +1,66 @@
+package psl.chime4.server.scs.ws.event;
+
+import psl.chime4.server.ces.*;
+
+/**
+ * Superclass for all events handled by the World Service.
+ *
+ * @author Azubuko Obele
+ * @version 0.1
+ **/
+public abstract class WorldEvent
+{
+   /** unique code for the event **/
+   public int EventCode;
+
+   /** unique uri for the event **/
+   public String EventUri;
+
+   /**
+    * Construct the WorldEvent from a Ces Event.
+    *
+    * @param code the event code
+    * @param uri  uri for the event
+    * @throws IllegalArgumentException
+    *         if <code>uri</code> is <code>null</code>
+    **/
+   protected WorldEvent(int code, String uri)
+   {
+      this.EventCode = code;
+      this.EventUri = uri;
+   }
+
+   /**
+    * Initialized this event from the passed Ces Event.
+    *
+    * @param event Ces event containing the information
+    * @throws IllegalArgumentException
+    *         if <code>event</code> is <code>null</code>
+    **/
+   protected WorldEvent(Event event)
+   {
+      if (event == null)
+      {
+         String msg = "event cannot be null";
+         throw new IllegalArgumentException(msg);
+      }
+
+      this.EventCode = event.getInteger("event.code");
+      this.EventUri = event.getString("event.uri");
+   }
+
+
+   /**
+    * Convert the this WorldEvent into a Ces Event suitable for
+    * transport.
+    *
+    * @param event Event into which to store the information
+    * @return Ces Event equivalent to this World Event
+    **/
+   public Event toCesEvent(Event event)
+   {
+      event.put("event.code", EventCode);
+      event.put("event.uri", EventUri);
+      return event;
+   }
+}
\ No newline at end of file
diff --git a/server/scs/ws/event/WorldEventMapper.java b/server/scs/ws/event/WorldEventMapper.java
new file mode 100644
index 0000000..7d32277
--- /dev/null
+++ b/server/scs/ws/event/WorldEventMapper.java
@@ -0,0 +1,58 @@
+package psl.chime4.server.scs.ws.event;
+
+import psl.chime4.server.ces.*;
+
+/**
+ * Provides the mapping between CES Events and WorldEvents.
+ *
+ * @author Azubuko Obele
+ * @version 0.1
+ **/
+public abstract class WorldEventMapper
+{
+   /**
+    * Map a CES Event into a WorldEvent.
+    *
+    * @param event CES event containing information
+    * @return WorldEvent equivalent to <code>event</code>
+    * @throws IllegalArgumentException
+    *         if <code>event</code> is <code>null</code> or it is an
+    *         unrecognized event
+    **/
+   public static WorldEvent cesToWorld(Event event)
+   {
+      if (event == null)
+      {
+         String msg = "event cannot be null";
+         throw new IllegalArgumentException(msg);
+      }
+
+      int eventCode = event.getInteger("event.code");
+
+      switch (eventCode)
+      {
+         case EventConstants.WorldLogin:
+            return new WorldLoginEvent(event);
+
+         case EventConstants.WorldLoginSuccess:
+            return new WorldLoginSuccessEvent(event);
+
+         case EventConstants.WorldLoginFailure:
+            return new WorldLoginFailureEvent(event);
+
+         case EventConstants.WorldEntry:
+            return new WorldEntryEvent(event);
+
+         case EventConstants.WorldEntrySuccess:
+            return new WorldEntrySuccessEvent(event);
+
+         case EventConstants.WorldEntryFailure:
+            return new WorldEntryFailureEvent(event);
+
+         default:
+            String msg = "unrecognized event: " + event;
+            throw new IllegalArgumentException(msg);
+      }
+   }
+}
+
diff --git a/server/scs/ws/event/WorldLoginEvent.java b/server/scs/ws/event/WorldLoginEvent.java
new file mode 100644
index 0000000..db84cb7
--- /dev/null
+++ b/server/scs/ws/event/WorldLoginEvent.java
@@ -0,0 +1,73 @@
+package psl.chime4.server.scs.ws.event;
+
+import psl.chime4.server.ces.*;
+
+/**
+ * A WorldLoginEvent sent by the client to the world to login. Once a client
+ * has logged into the world they are not yet part of the world; instead they
+ * can now use any service exported by that world service.
+ *
+ * @author Azubuko Obele
+ * @version 0.1
+ **/
+public class WorldLoginEvent extends WorldEvent
+{
+   /** username of the client logging in **/
+   public String Username;
+
+   /** client's ticket; proof of the client's identity **/
+   public byte[] Ticket;
+
+   /** unique topic; this is how the world service responds to the login **/
+   public String UniqueTopic;
+
+   /**
+    * Basic constructor to initialize all fields.
+    *
+    * @param username name of the client logging in
+    * @param ticket   proof of the client's identity
+    * @param topic    unique topic that the client is listening to
+    * @throws IllegalArgumentException
+    *         if any parameter is <code>null</code>
+    **/
+   public WorldLoginEvent(String username, byte[] ticket, String topic)
+   {
+      super(EventConstants.WorldLogin, EventConstants.WorldLoginUri);
+
+      if ((username == null) || (ticket == null) || (topic == null))
+      {
+         String msg = "no param can be null";
+         throw new IllegalArgumentException(msg);
+      }
+
+      this.Username = username;
+      this.Ticket = ticket;
+      this.UniqueTopic = topic;
+   }
+
+   /**
+    * Initialize the WorldLoginEvent from a Ces Event.
+    *
+    * @param event Ces Event storing the information
+    * @throws IllegalArgumentException
+    *         if <code>event</code> is <code>null</code>
+    **/
+   public WorldLoginEvent(Event event)
+   {
+      super(event);
+
+      this.Username = event.getString("client.name");
+      this.Ticket = event.getByteArray("client.ticket");
+      this.UniqueTopic = event.getString("client.uniqueTopic");
+   }
+
+   public Event toCesEvent(Event event)
+   {
+      event = super.toCesEvent(event);
+
+      event.put("client.name", Username);
+      event.put("client.ticket", Ticket);
+      event.put("client.uniqueTopic", UniqueTopic);
+      return event;
+   }
+}
diff --git a/server/scs/ws/event/WorldLoginFailureEvent.java b/server/scs/ws/event/WorldLoginFailureEvent.java
new file mode 100644
index 0000000..5d0bde5
--- /dev/null
+++ b/server/scs/ws/event/WorldLoginFailureEvent.java
@@ -0,0 +1,63 @@
+package psl.chime4.server.scs.ws.event;
+
+import psl.chime4.server.ces.*;
+
+/**
+ * Event sent by the World to the Client indicating that she cannot login
+ * into the world service.
+ *
+ * @author Azubuko Obele
+ * @version 0.1
+ **/
+public class WorldLoginFailureEvent extends WorldEvent
+{
+   /** name of the world that reject the login request **/
+   public String WorldName;
+
+   /** reason login failed **/
+   public String Reason;
+
+   /**
+    * Construct a WorldLoginFailureEvent with the passed parameters.
+    *
+    * @param worldName name of the world rejecting the login
+    * @param reason    reason the login failed
+    * @throws IllegalArgumentException
+    *         if <code>worldName</code> is <code>false</code>
+    **/
+   public WorldLoginFailureEvent(String worldName, String reason)
+   {
+      super(EventConstants.WorldLoginFailure,
+            EventConstants.WorldLoginFailureUri);
+
+      if (worldName == null)
+      {
+         String msg = "world name cannot be null";
+         throw new IllegalArgumentException(msg);
+      }
+
+      this.WorldName = worldName;
+      this.Reason = reason;
+   }
+
+   /**
+    * Construct a WorldLoginFailureEvent from the passed Ces Event.
+    *
+    * @param event Event containing the event info
+    **/
+   public WorldLoginFailureEvent(Event event)
+   {
+      super(event);
+
+      this.WorldName = event.getString("world.name");
+      this.Reason = event.getString("reason");
+   }
+
+   public Event toCesEvent(Event event)
+   {
+      event = super.toCesEvent(event);
+      event.put("world.name", WorldName);
+      event.put("reason", Reason);
+      return event;
+   }
+}
\ No newline at end of file
diff --git a/server/scs/ws/event/WorldLoginSuccessEvent.java b/server/scs/ws/event/WorldLoginSuccessEvent.java
new file mode 100644
index 0000000..28e2195
--- /dev/null
+++ b/server/scs/ws/event/WorldLoginSuccessEvent.java
@@ -0,0 +1,56 @@
+package psl.chime4.server.scs.ws.event;
+
+import psl.chime4.server.ces.*;
+
+/**
+ * Event sent by the WorldService to the client when they have successfully
+ * logged into the world.
+ *
+ * @author Azubuko Obele
+ * @version 0.1
+ **/
+public class WorldLoginSuccessEvent extends WorldEvent
+{
+   /** username of the world that has granted login privs **/
+   public String WorldName;
+
+   /**
+    * Construct a WorldLoginSuccessEvent.
+    *
+    * @param worldName name of the world sending the event
+    * @throws IllegalArgumentException
+    *         if <code>worldName</code> is <code>null</code>
+    **/
+   public WorldLoginSuccessEvent(String worldName)
+   {
+      super(EventConstants.WorldLoginSuccess,
+            EventConstants.WorldLoginSuccessUri);
+
+      if (worldName == null)
+      {
+         String msg = "worldName cannot be null";
+         throw new IllegalArgumentException(msg);
+      }
+
+      this.WorldName = worldName;
+   }
+
+   /**
+    * Construct a WorldLoginSuccessEvent from a Ces Event.
+    *
+    * @param event Ces Event containing the event info
+    **/
+   public WorldLoginSuccessEvent(Event event)
+   {
+      super(event);
+
+      this.WorldName = event.getString("world.name");
+   }
+
+   public Event toCesEvent(Event event)
+   {
+      event = super.toCesEvent(event);
+      event.put("world.name", WorldName);
+      return event;
+   }
+}
diff --git a/server/scs/ws/view/image/ImageInfo.java b/server/scs/ws/view/image/ImageInfo.java
new file mode 100644
index 0000000..fc323af
--- /dev/null
+++ b/server/scs/ws/view/image/ImageInfo.java
@@ -0,0 +1,15 @@
+package psl.chime4.server.scs.ws.view.image;
+
+import psl.chime4.server.scs.persist.*;
+
+/**
+ * Defines a specific image file in the universe. This class can describe
+ * either a 2D image (used for textures and billboards) and a 3D model file
+ * (used for objects).
+ *
+ * @author Azubuko Obele
+ * @version 0.1
+ **/
+public final class ImageInfo extends PersistentObject
+{
+}
\ No newline at end of file