1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
|
/* -*- mode: c++ -*-
*/
/*
GIFT, a flexible content based image retrieval system.
Copyright (C) 1998, 1999, 2000, 2001, 2002, CUI University of Geneva
Copyright (C) 2003, 2004 Bayreuth University
2005 Bamberg University
This program 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 of the License, or
(at your option) any later version.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// -*- mode: c++ -*-
#ifndef _CSESSIONMANAGER
#define _CSESSIONMANAGER
#include "libMRML/include/uses-declarations.h"
#include <iostream>
#include <string>
#include <list>
#include <map>
#include "libMRML/include/CXMLElement.h"
#include "libMRML/include/CAccessorAdminCollection.h"
#include "libMRML/include/CI18nTranslator.h"
#include "libMRML/include/CAlgorithm.h"
#include "libMRML/include/CPropertySheetList.h"
#include "libMRML/include/CAccessorElement.h"
#include "libMRML/include/CAlgorithmCollection.h"
#include "libMRML/include/CQueryTreeBuilder.h"
#include "libMRML/include/CMutex.h" // multithreading
class CStaticQueryFactory;
class CAlgorithm;
class CSessionManager;
class CQueryTreeNode;
class CStaticQueryFactory;
/** A class containing a session.
* At present a session is just
* a quite rudimentary container
* for an algorithm.
*
* Later we hope to make sessions
* persistent (using blobs in
* msql, for example).
*
*
* ATTENTION MULTITHREADING:
* WHAT TO LOCK AND WHAT TO UNLOCK IS NOT ENTIRELY TRIVIAL
* THIS MIGHT BE A SOURCE OF MISTAKES
*
* @author Wolfgang Mller
*/
class CSession{
protected:
/** the language to be used in this session*/
string mPreferredLanguage;
/** the list of languages to be used */
typedef list<string> CLanguageList;
/** the list of languages to be used */
CLanguageList mLanguages;
/** the mutex for this session */
CMutex mMutexSession;
/** */
bool mIsOpen;
/** */
string mUser;
/** */
string mID;
/**
* the name of this session
*/
string mSessionName;
/** The algorithm used for the next query
* At present this fully describes a session
*/
CAlgorithm* mActiveAlgorithm;
/** The information about the current query tree */
pair<CQueryContainer*,CQueryTreeNode*> mQueryTree;
/** */
static CQueryTreeBuilder mQueryTreeBuilder;
public:
//--------------------------------------------------
/** Constructors */
CSession();
/**
*/
CSession(string inUser,
string inID,
string inSessionName,
CAlgorithm* inActiveAlgorithm
);
/**
destroys all members
*/
~CSession();
//--------------------------------------------------
/** Read the state */
ostream& write(ostream& outStream)const;
/** Write the state */
istream& read(istream& inStream);
//--------------------------------------------------
/** get user of this session */
string getUser()const;
/** set user of this session */
void setUser(const string& inUser);
/** set ID of this session */
string getID()const;
/** get ID of this session */
void setID(const string& inID);
/** get the displayname of this session */
string getSessionName()const;
/** set the displayname of this session */
void setSessionName(const string& inSessionName);
/** get the algorithm of this session */
CAlgorithm* getActiveAlgorithm();
/** set the algorithm of this session.
in fact this amounts to building a complete
query tree.
We also would like to do a bit of
tree matching to see, how much of the query
we can rescue after reconfiguration.
*/
bool setActiveAlgorithm(CAccessorAdminCollection& inCaller,
CAlgorithmCollection& inAlgorithmCollection,
CAlgorithm* inActiveAlgorithm,
CStaticQueryFactory& inBaseTypeFactory);
/** set the collection of this session */
//string getActiveCollection()const;
/** get the collection of this session */
// void setActiveCollection(const string& inCollection);
//--------------------------------------------------
/**
* performing a query
*
* Gets from the current algorithm the right inSubAlgorithm,
* from that the right CQuery and hands parameters through to it.
*/
CXMLElement* query(CSessionManager& inCaller,
const CXMLElement& inQuery);
//--------------------------------------------------
/** retrieving random images as seeds */
CXMLElement* getRandomImages(CSessionManager& inCaller,
const string& inAlgorithm,
int inResultSize);
//--------------------------------------------------
/** opening this session. This implements a lock, such that one
user can have several open session which do not interfere.
The return value tells the use if the open was successful (true)
*/
bool open();
//--------------------------------------------------
/** Closing this session
*/
bool close();
//--------------------------------------------------
/** Renaming this session
(calls setSessionName, at present)
*/
bool rename(const string& inName);
/** the list of preferred languages of this
is cleared */
void clearLanguages();
/** one language code is added at the back of the list
of preferred languages */
void addLanguage(string inLanguageCode);
/** commit the list of languages. That means, here the
actual language that will be used throughout the
translation is determined */
void commitLanguages(const CI18nTranslator& inTranslator);
/** get the preferred languages of this session */
list<string> getLanguages()const;
/** get the preferred languages of this session */
string getPreferredLanguage()const;
//--------------------------------------------------
/** generating XML output for configuration/shandshake */
string toXML(bool isPrivate)const;
};
/** This structure handles the sessions;
by this, it encapsulates
the current state of the server.
Basically, it hands all requests through to the
right sessions. It also handles the generation of
new sessions etc.. In short, it is the configuration
manager.
This class is now approaching what I would like it to be,
however, cleaning is always wellcome
ATTENTION MULTITHREADING:
WHAT TO LOCK AND WHAT TO UNLOCK IS NOT ENTIRELY TRIVIAL
THIS MIGHT BE A SOURCE OF MISTAKES
*/
class CSessionManager:public CAlgorithmCollection
//,public CAlgorithmIDListList
{
/** the mutex for this sessionmanager */
CMutex mMutexSessionManager;
protected:
/**
The accessor collection is needed for constructing queries
*/
CAccessorAdminCollection mAccessorAdminCollection;
/**
The Translator for this
*/
CI18nTranslator mI18nTranslator;
/**
point the user to all the sessions
*/
typedef map<string,list<CSession> > CUserToSessions;
/** */
typedef map<string,CSession*> CIDToSession;
/** */
mutable CUserToSessions mUserToSessions;
/** */
mutable CIDToSession mIDToSession;
/** These are the building blocks of
the property sheets to be generated
by *this.
*/
CPropertySheetList* mPropertySheetList;
/** The subtree from which the mPropertySheets
will be built */
CXMLElement* mPropertySheetSubtree;
/** The base type factory is a factory for query
base types */
CStaticQueryFactory* mBaseTypeFactory;
public:
/**
The session manager slurps in two XML files
and generates out of this its initial state.
*/
CSessionManager(string inSessions,
string inConfiguration,
string inI18nFileName);
//----------------------------------------
/**
*this CSessionManager has all the information
to make a query structure.
*/
CQuery* makeQuery(const string& inBaseType,
CAlgorithm& inAlgorithm);
//----------------------------------------
/** Initialization: read from a stream
*/
istream& read(istream&);
/** Write into a stream*/
ostream& write(ostream&);
//----------------------------------------
/** to be used by the Interface.
Not yet implemented.
*/
CXMLElement* openSession(string inUserName,
string inSessionID,
string inSessionName);
//----------------------------------------
/** to be used by the Interface.
Not yet implemented.
*/
CXMLElement* renameSession(string inSessionID,
string inSessionName);
/** to be used by the Interface.
Not yet implemented.*/
CXMLElement* deleteSession(string inSessionID);
/** Closes the session, but keeps it in memory.
FUTURE: put the state of the session into a
blob
*/
CXMLElement* closeSession(string inSessionID);
/** VeryImportantFunction:
This function looks for a CSession with CSession::mSessionID==inSessionID
and hands through the rest of the parameter list to CSession::query.
*/
CXMLElement* query(const string& inSessionID,
const CXMLElement& inRelevanceLevelList);
//--------------------------------------------------
/** retrieving random images (as seeds for subsequent searches)
*@param inSessionID The ID of the session in which the
* request was issued.
*@param inAlgorithm One would think this is not needed when
* retrieving random images. However, it is
* useful to know the collection involved,
* and if the random images we are retrieving
* will fit the algorithm used later.
*@param inCollection The collection from which random images will
* be retrieved.
*/
CXMLElement* getRandomImages(const string& inSessionID,
const string& inAlgorithm,
int inResultSize);
//--------------------------------------------------
/** retrieving the URLs of all images (for generating distance matrices) */
list<CAccessorElement>* getAllAccessorElements(const string& inSessionID,
const string& inAlgorithm
);
//--------------------------------------------------
/** retrieving the IDs of all images (for generating distance matrices) */
list<TID>* getAllIDs(const string& inSessionID,
const string& inAlgorithm
);
//----------------------------------------
/** set the algorithm used in this session
it will also lead to a new construction of
the query.
We have to perform some comparisons here
present version is probably a HACK
*/
bool setAlgorithm(const string& inSessionID,
CAlgorithm* inAlgorithm);
/** making a new session and returning its ID */
string newSession(const string& inUser,
const string& inSessionName);
/** making a new session and for a given ID, returnig the ID */
string newSession(const string& inID,
const string& inUser,
const string& inSessionName);
/** Set the name of the current session.
Presently not implemented or tested*/
void setSessionName(const string& inOldSessionName,
const string& inNewSessionName);
//----------------------------------------
/** turn this into a part of the welcome message
in fact, this generates standard property sheets out of the
collections and algorithms available
It means:
1. Make out of each algorithm in the collection a property sheet.
2. Make out of the algorithm-id-list-list a property sheet with
a parent node which does not send messages.
3. Make out of the collection list a choice of collections,
each having as a child a property sheet out of 2.
If we do things this way we are losing a bit of the flexibility
given in the property sheet specification. However, for the moment
I (WM) consider this loss nost as big compared to what we earn in
terms of configuration of the system. If necessary recode.
string convertPropertyToXML(bool isPrivate=false)const;
THIS IS DEPRECATED STUFF, SO IT'S DELETED NOW!
*/
//----------------------------------------
/** turn this into a part of the welcome message
THIS CODE IS TO LEAVE SOON
*/
string toXML(bool isPrivate=false)const;
/** The sessions for one user only.
*
*@param inUser the name of the user for which we want the session names.
*@param isPrivate send internal configuration information along?
* (distinction between messages for internet and config
* files)
*/
string toXMLSessions(const string& inUser,
bool isPrivate=false)const;
/** The sessions for everybody known to the system */
string toXMLSessionConfiguration()const;
/** this is almost the complete shandshake message */
pair<string,string> toXMLHandshake(const string& inUser);
/** Get the property sheet of the algorithm with ID inAlgorithmID.
We look for the attribute cui-property-sheet-id in the algorithm.
If this exsists, we look for the right property sheet id in the
CPropertySheetList.
*/
CXMLElement* getPropertySheet(string inSessionID,
string inAlgorithmID)const;
//----------------------------------------
/** Building a property sheet list
I consider building a list on a call by call basis as
tedious. So what I do is:
I first build a tree, and then I break down this tree
into our list.
This function makes a new tree
*/
void startPropertySheetSubtree();
/** This function gets us the current property sheet subtree.
*/
CXMLElement* getPropertySheetSubtree();
/** This function does the actual breaking down into a
CPropertySheetList.
*/
void endPropertySheetSubtree();
/** This function probably will quite soon be removed from this class,
and it will become part of a class containing the CSessionManager*/
CXMLElement* getCollections()const;
/** This function probably will quite soon be removed from this class,
and it will become part of a class containing the CSessionManager*/
CXMLElement* getAlgorithms()const;
/** i18n clear the preferred languages list of a given session */
bool clearSessionLanguages(const string& inSessionID);
/** i18n: add one language code to the list of preferred languages */
bool addSessionLanguage(const string& inSessionID,
const string& inLanguageCode);
/** commit the languages to be used for a session.*/
bool commitSessionLanguages(const string& inSessionID);
/** i18n: get the list of preferred languages of this session */
list<string> getSessionLanguages(const string& inSessionID)const;
/** i18n: get the list of preferred languages of this session */
void translate(string inSessionID,
CXMLElement& inoutToBeTranslated)const;
};
#endif
|