package server; import java.util.*; import shared.*; import shared.remotecall.*; /** * A object of this class encapsulates the whole calendar database on the server side. * This class is used for getting/modifying and adding/removing of calendar events. * @author buetow * */ public final class CalendarDatabase { private Vector vecCategories; private HashMap mapEvents; private HashMap mapCategories; /** * Simple constructur. Creates a calendar database. * @param vecCategories Specifies the vector of CalendarCategory objects for initial database content. */ public CalendarDatabase(Vector vecCategories) { this.vecCategories = vecCategories; initializeMaps(); } /** * Initializes a private hash map so that the server can access events by their id numbers very fast. */ private void initializeMaps() { this.mapEvents = new HashMap(); this.mapCategories = new HashMap(); Enumeration enumCategory = vecCategories.elements(); while (enumCategory.hasMoreElements()) { CalendarCategory category = (CalendarCategory) enumCategory.nextElement(); mapCategories.put(category.getName(), category); Vector vecEvents = category.getEvents(); Enumeration enumEvents = vecEvents.elements(); while (enumEvents.hasMoreElements()) { CalendarEvent event = (CalendarEvent) enumEvents.nextElement(); mapEvents.put(new Integer(event.getEventID()), event); } } } /** * Returns a specific calendar event using fast hash lookup. * @param iEventID Specifies the ID of the calendar event to lookup. * @return Returns the requested calendar event. */ public CalendarEvent getEvent(int iEventID) { return (CalendarEvent) mapEvents.get(new Integer(iEventID)); } /** * Returns a specific calendar category using fast hash lookup. * @param sCategoryName Specifies the name of the calendar category to lookup. * @return Returns the requested calendar category. */ public CalendarCategory getCategory(String sCategoryName) { return (CalendarCategory) mapCategories.get(sCategoryName); } /** * Gets all calendar categories. * @return Returns a Vector of all available CalendarCategory objects. */ public Vector getCategories() { return vecCategories; } /** * This method returns a Vector of all available calendar events. * @return Returns all available CalendarEvent objects of the database. */ public Vector getAllEvents() { MyVector vecAllEvents = new MyVector(); Enumeration enumCategories = vecCategories.elements(); while (enumCategories.hasMoreElements()) { CalendarCategory category = (CalendarCategory) enumCategories.nextElement(); vecAllEvents.appendVector(category.getEvents()); } return vecAllEvents; } /** * This method looks for all calendar events which match the a given client request. * @param clientRequest Specifies the client request sent by the calendar client. * @return Returns a Vector of all matching CalendarEvent objects. */ public Vector getMatchingEvents(ClientRequest clientRequest) { MyVector vecEvents = new MyVector(); int iNumEventsToRequest = clientRequest.getNumEventsToRequest(); Enumeration enumCategories = vecCategories.elements(); while (enumCategories.hasMoreElements()) { CalendarCategory category = (CalendarCategory) enumCategories.nextElement(); Vector vecNewEvents = category.getMatchingEvents(clientRequest); vecEvents.appendVector(vecNewEvents); if (iNumEventsToRequest > -1) { if (iNumEventsToRequest == vecEvents.size()) break; } else { clientRequest.setNumEventsToRequest(iNumEventsToRequest - vecNewEvents.size()); } } return vecEvents; } /** * This method adds a calendar event to the calendar database. * @param clientRequest Specifies the client request sent by the netcalendar client. Its containing the new event to add. */ public void addEvent(ClientRequest clientRequest) { CalendarEvent event = clientRequest.getEvent(); String sCategoryName = event.getCategoryName(); CalendarCategory category = getCategory(sCategoryName); // Check if the have to create a new category if (category == null) { category = new CalendarCategory(sCategoryName); mapCategories.put(sCategoryName, category); vecCategories.add(category); } category.addEvent(event); category.setHasChanged(true); event.setCategory(category); mapEvents.put(new Integer(event.getEventID()), event); } /** * This method modifies an calendar event of the calendar database. * @param clientRequest Specifies the client request sent by the calendar client. */ public void modifyEvent(ClientRequest clientRequest) { CalendarEvent newEvent = clientRequest.getEvent(); CalendarEvent orgEvent = getEvent(newEvent.getEventID()); // If the event doesnt exist any more, recreate it if (orgEvent == null) { clientRequest.setEvent(newEvent); addEvent(clientRequest); return; } orgEvent.setDate(newEvent.getDate()); orgEvent.setYearly(newEvent.isYearly()); orgEvent.setDescription(newEvent.getDescription()); orgEvent.setPlace(newEvent.getPlace()); // Modify the events category if (!orgEvent.getCategoryName().equals(newEvent.getCategoryName())) { String sNewCategoryName = newEvent.getCategoryName(); // First remove the event from its current category orgEvent.removeFromCurrentCategory(); CalendarCategory category = getCategory(sNewCategoryName); if (category == null) { category = new CalendarCategory(sNewCategoryName); mapCategories.put(sNewCategoryName, category); vecCategories.add(category); } category.addEvent(orgEvent); category.setHasChanged(true); orgEvent.setCategory(category); } else { orgEvent.getCategory().setHasChanged(true); } } /** * This method deletes a calendar event of the calendar database. If the specified calendar event doesnt * exist eny more, nothing will be changed. * @param clientRequest Specifies the client request sent by the netcalendar client. */ public void deleteEvent(ClientRequest clientRequest) { // Get the server side reference of the calendar event CalendarEvent event = getEvent(clientRequest.getEvent().getEventID()); if (event != null) { event.getCategory().setHasChanged(true); event.removeFromCurrentCategory(); mapEvents.remove(new Integer(event.getEventID())); } } /** * This method renames a calendar category. * @param clientRequest Specifies the client request sent by the netcalendar client. */ public void renameCategory(ClientRequest clientRequest) { String sOldCategoryName = clientRequest.getEvent().getCategoryName(); CalendarCategory category = getCategory(sOldCategoryName); if (category == null) return; String sNewCategoryName = clientRequest.getString(); if (sOldCategoryName.equals(sNewCategoryName)) return; mapCategories.remove(sOldCategoryName); category.setName(sNewCategoryName); Vector vecEvents = category.getEvents(); Enumeration enumEvents = vecEvents.elements(); while (enumEvents.hasMoreElements()) { CalendarEvent event = (CalendarEvent) enumEvents.nextElement(); event.setCategoryName(sNewCategoryName); } // Check if the category exists already CalendarCategory categoryExists = getCategory(sNewCategoryName); if (categoryExists == null) { mapCategories.put(category.getName(), category); } else { vecCategories.remove(category); categoryExists.merge(category); } } /** * This method daletes a calendar category. * @param clientRequest Specifies the client request sent by the netcalendar client. */ public void deleteCategory(ClientRequest clientRequest) { String sCategoryName = clientRequest.getEvent().getCategoryName(); CalendarCategory category = getCategory(sCategoryName); if (category == null) return; mapCategories.remove(sCategoryName); vecCategories.remove(category); category.deleteDatabaseFile(); } /** * This method flushes all the changed calendar categories of the calendar database to the filesystem. */ public void flush() { Enumeration enumCategories = vecCategories.elements(); while (enumCategories.hasMoreElements()) { CalendarCategory category = (CalendarCategory) enumCategories.nextElement(); if (category.hasChanged()) category.flush(); } Main.execExternalCommand(Config.getStringValue("server_updatedb_command")); } }