/* * Copyright 2003-2010 Tufts University Licensed under the * Educational Community License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may * obtain a copy of the License at * * http://www.osedu.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS IS" * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing * permissions and limitations under the License. */ /* * AgentManager.java * * Created on October 22, 2003, 8:30 AM */ package tufts.oki.agent; import tufts.oki.*; import java.util.*; import java.io.*; import org.osid.shared.SharedException; /** * The Agent Manager allows creation and manipulation of Agent, and Group objects. * The manager maintains a list for all Ids, Agents, and Groups created. * <p> * Support is provided for persistance via readState() and writeState(). Note that the * persistance is done using serialization to a file, which is currently hard coded as * SERIALZIED_FILE_NAME. This either needs to be edited for the final installation, or * a better method of naming the file provided. * * @author Mark Norton */ public class AgentManager implements org.osid.agent.AgentManager { public static final String SERIALIZED_FILE_NAME = "c:/java/serialized/org_osid_agent_manager.sid"; private Vector ids = null; private Vector agents = null; private Vector groups = null; private org.osid.OsidContext context = null; // This private flag is used to keep track of the persistance state. private boolean restored = false; /** * Creates a new instance of SharedManager with no owner. * * @author Mark Norton */ public void osidVersion_2_0() { } public void assignConfiguration(java.util.Properties properties) { } public void assignOsidContext(org.osid.OsidContext context) { this.context = context; } public org.osid.OsidContext getOsidContext() { return this.context; } public AgentManager() { super(); agents = new Vector(100); groups = new Vector(100); } /** * Adds the new Agent to the internal agents list. * * @author Mark Norton * * @return An Agent with the name and type provided. */ public org.osid.agent.Agent createAgent(String name, org.osid.shared.Type agentType, org.osid.shared.Properties props) throws org.osid.agent.AgentException { org.osid.agent.Agent agent = new Agent (name, agentType); agents.add (agent); // Add it to the SharedManager agents list. return agent; } /** * Adds the Group to the internal groups list. * * @author Mark Norton * * @return A Group with the Id provided. */ public org.osid.agent.Group createGroup(String name, org.osid.shared.Type groupType, String description, org.osid.shared.Properties props) throws org.osid.agent.AgentException { org.osid.agent.Group group = new Group (name, groupType, description); groups.add (group); // Add it to the SharedManager agents list. return group; } /** * Delete the agent given by the Id passed. * * @author Mark Norton */ public void deleteAgent(org.osid.shared.Id id) throws org.osid.agent.AgentException { org.osid.agent.Agent ag = this.getAgent (id); agents.remove(ag); } /** * Delete the group given by the Id passed. Note that this implementation * currently checks to see if a group is empty before deleting it, raising an * exception if non-empty. There has been some discussion on SourceForge to * indidate that a group should be empty before deleting it. * * @author Mark Norton */ public void deleteGroup(org.osid.shared.Id id) throws org.osid.agent.AgentException { tufts.oki.agent.Group gp = (tufts.oki.agent.Group)this.getGroup (id); if (!gp.isEmpty()) { throw new org.osid.agent.AgentException ("Group is not empty."); } groups.remove(gp); } /** * Get the agent who's Id is equal to the one passed. * Note that if there is no agent with this id, an UNKNOWN_ID exception is thrown. * * @author Mark Norton * * @return An agent who's id is equal to the one passed. */ public org.osid.agent.Agent getAgent(org.osid.shared.Id id) throws org.osid.agent.AgentException { try { for (int i=0; i < ids.size(); i++) { org.osid.agent.Agent agent = (Agent) agents.elementAt (i); if ((agent.getId()).isEqual (id)) return agent; } } catch (Throwable t) { throw new org.osid.agent.AgentException(t.getMessage()); } throw new org.osid.agent.AgentException (osid.shared.SharedException.UNKNOWN_ID); } /** * Get the agent who's display name is equal to the one passed. * Note that if there is no agent with this id, an UNKNOWN_ID exception is thrown. * * @author Mark Norton * * @return An agent who's display name is equal to the one passed. */ public org.osid.agent.Agent getAgent(String name) throws org.osid.agent.AgentException { for (int i=0; i < agents.size(); i++) { org.osid.agent.Agent agent = (Agent) agents.elementAt (i); if (agent.getDisplayName().compareTo(name) == 0) return agent; } throw new org.osid.agent.AgentException ("Unknown Name"); } /** * Returns a interator which lists all known agent types. * <p> * This needs to be re-written as a pre-built list of supported Agent Types. * Searching for types in the agents list only returns types that have been * used, which is not the same as the list of supported agent types. * * @author Mark Norton * * @return An iterator which walks a list of unique agent types. */ public org.osid.shared.TypeIterator getAgentTypes() throws org.osid.agent.AgentException { /* Iterate over all agents, extract type, and add to a HashSet. */ HashSet type_set = new HashSet(); for (int i=0; i < ids.size(); i++) { Agent agent = (Agent) agents.elementAt (i); org.osid.shared.Type type = agent.getType(); type_set.add(type); } /* Create type vector from the type set. */ Vector type_vector = new Vector (type_set.size()); type_vector.addAll (type_set); /* Create and return a TypeIterator for the list of unique types. */ org.osid.shared.TypeIterator it = new tufts.oki.shared2.TypeIterator(type_vector); return it; } /** * Get a list of all agents. * * @author Mark Norton * * @return An AgentIterator which will interate over all known agents. */ public org.osid.agent.AgentIterator getAgents() { AgentIterator it = new AgentIterator (agents); return it; } /** * Get a list of all agents of a given type. * <p> * This method was introduced in rc6.1. * * @author Mark Norton * * @return An AgentIterator which lists out all agents of the type given. */ public org.osid.agent.AgentIterator getAgentsByType(org.osid.shared.Type agentType) throws org.osid.agent.AgentException { /* Iterate over all agents, extract type, and add to a HashSet. */ HashSet agent_set = new HashSet(); for (int i=0; i < ids.size(); i++) { Agent agent = (Agent) agents.elementAt (i); org.osid.shared.Type type = agent.getType(); if (type.isEqual(agentType)) agent_set.add(agent); } /* Create type vector from the agent set. */ Vector agent_vector = new Vector (agent_set.size()); agent_vector.addAll (agent_set); /* Create and return an AgentIterator for the list of agents of this type. */ AgentIterator it = new AgentIterator(agent_vector); return it; } /** * Get the group assoicated with the Id given. * Note that if there is no group with this id, an UNKNOWN_ID exception is thrown. * @author Mark Norton * * @return A group who's id is equal to the one passed. */ public org.osid.agent.Group getGroup(org.osid.shared.Id id) throws org.osid.agent.AgentException { try { for (int i=0; i < ids.size(); i++) { org.osid.agent.Group group = (Group) groups.elementAt (i); if ((group.getId()).isEqual (id)) return group; } } catch (Throwable t) { throw new org.osid.agent.AgentException(t.getMessage()); } throw new org.osid.agent.AgentException (osid.shared.SharedException.UNKNOWN_ID); } /** * Get a list of group types. * <p> * Again, this should be done from a list of supported types, not currently used * grouptypes. * * @author Mark Norton * * @return An iterator which walks a list of unique group types. */ public org.osid.shared.TypeIterator getGroupTypes() throws org.osid.agent.AgentException { /* Iterate over all agents, extract type, and add to a HashSet. */ HashSet type_set = new HashSet(); for (int i=0; i < ids.size(); i++) { Group group = (Group) groups.elementAt (i); org.osid.shared.Type type = group.getType(); type_set.add(type); } /* Create type vector from the type set. */ Vector type_vector = new Vector (type_set.size()); type_vector.addAll (type_set); /* Create and return a TypeIterator for the list of unique types. */ org.osid.shared.TypeIterator it = new tufts.oki.shared2.TypeIterator(type_vector); return it; } /** * Get a list of groups. * * @author Mark Norton * * @return An AgentIterator which will interate over all known groups. */ public org.osid.agent.AgentIterator getGroups() throws org.osid.agent.AgentException { AgentIterator it = new AgentIterator (groups); return it; } /** * Get a list of all groups of a given group type. * * @author Mark Norton * * @return An AgentIterator which lists out all groups of the type given. */ public org.osid.agent.AgentIterator getGroupsByType(org.osid.shared.Type groupType) throws org.osid.agent.AgentException { /* Iterate over all agents, extract type, and add to a HashSet. */ HashSet group_set = new HashSet(); for (int i=0; i < ids.size(); i++) { Group group = (Group) groups.elementAt (i); org.osid.shared.Type type = group.getType(); if (type.isEqual(groupType)) group_set.add(group); } /* Create type vector from the agent set. */ Vector group_vector = new Vector (group_set.size()); group_vector.addAll (group_set); /* Create and return an AgentIterator for the list of agents of this type. */ AgentIterator it = new AgentIterator(group_vector); return it; } public org.osid.agent.AgentIterator getAgentsBySearch(java.io.Serializable criteria, org.osid.shared.Type type) throws org.osid.agent.AgentException { throw new org.osid.agent.AgentException(org.osid.OsidException.UNIMPLEMENTED); } public org.osid.shared.TypeIterator getAgentSearchTypes() throws org.osid.agent.AgentException { throw new org.osid.agent.AgentException(org.osid.OsidException.UNIMPLEMENTED); } public org.osid.shared.TypeIterator getPropertyTypes() throws org.osid.agent.AgentException { throw new org.osid.agent.AgentException(org.osid.OsidException.UNIMPLEMENTED); } public org.osid.agent.AgentIterator getGroupsBySearch(java.io.Serializable criteria, org.osid.shared.Type type) throws org.osid.agent.AgentException { throw new org.osid.agent.AgentException(org.osid.OsidException.UNIMPLEMENTED); } public org.osid.shared.TypeIterator getGroupSearchTypes() throws org.osid.agent.AgentException { throw new org.osid.agent.AgentException(org.osid.OsidException.UNIMPLEMENTED); } /** * Write out the state of the SharedManager. Since the various OSID managers are * loaded on demand by OsidLoader, persistence of data has to happen in the various * managers after they have been loaded by OsidLoader. This method marshalls the * id, agent, and group lists into a file called "osid_shared_manager.ser". * <p> * While persistence of agents and groups seems useful, it is not clear that * persisting Ids is. Generally, I would expect Ids to be part of other objects * like Agent or Type and be persisted by those objects if needed. As such, the * persistence of Ids is commented out below. If desired, uncomment it. * * Note that this method is not defined by the osid.SharedManager interface. * * @author Mark Norton */ public void writeState() throws org.osid.agent.AgentException { try { FileOutputStream fout = new FileOutputStream (SERIALIZED_FILE_NAME); ObjectOutputStream oout = new ObjectOutputStream (fout); oout.writeObject (agents); oout.writeObject (groups); // oout.writeObject (ids); oout.close(); } catch (java.io.IOException ex) { throw new org.osid.agent.AgentException ("I/O error on writing state data out of SharedManager."); } } /** * Read in the state of the SharedManager. Since the various OSID managers are * loaded on demand by OsidLoader, persistence of data has to happen in the various * managers after they have been loaded by OsidLoader. This method un-marshalls the * id, agent, and group lists from a file called "osid_shared_manager.ser". This * method should be called immediately after loaded by OsidLoader. An attempt to * readState() to a modified SharedManager will result in an exception. * <p> * While persistence of agents and groups seems useful, it is not clear that * persisting Ids is. Generally, I would expect Ids to be part of other objects * like Agent or Type and be persisted by those objects if needed. As such, the * persistence of Ids is commented out below. If desired, uncomment it. * * Note that this method is not defined by the osid.SharedManager interface. * * @author Mark Norton */ public void readState() throws org.osid.agent.AgentException { if (this.isEmpty()) { // Open up the serilization file, if it exists. FileInputStream fin = null; try { fin = new FileInputStream (SERIALIZED_FILE_NAME); } catch (java.io.IOException exio) { // This error is most likely to be a file not found, which means // that there is not state to load. Just return. restored = true; return; } try { // Create an object stream from file stream. ObjectInputStream oin = new ObjectInputStream (fin); // Read the persistent data and cast it to objects. agents = (Vector)oin.readObject(); groups = (Vector)oin.readObject(); // Close in input stream. oin.close(); restored = true; } catch (java.io.IOException ex2) { throw new org.osid.agent.AgentException ("SharedManager exception: " + ex2.getMessage()); } catch (java.lang.ClassNotFoundException ex4) { throw new org.osid.agent.AgentException ("Class not found error on reading state data into SharedManager."); } } else throw new org.osid.agent.AgentException ("Attempt to read state into an modified SharedManager."); } /** * Check to see if the SharedManager is emtpy, meaning that no agents or groups are * currently defined. This is largely diagnostic in nature, thought it is used by * the persisence mechanism implemented by writeState() and readState(). * <p> * Note that this method is an extension to the OKI SharedManager interface. * * @author Mark Norton */ public boolean isEmpty() { return (agents.isEmpty() && groups.isEmpty()); } /** * Use this method to see if the state for the SharedManager has been restored * by readState(). * <p> * Note that this method is an extension to the OKI SharedManager interface. * * @author Mark Norton * * @return True if state data has been restored. */ public boolean isRestored() { return (restored); } }