2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
23 // $TOG: MMDB_Factory.C /main/15 1998/04/17 11:42:43 mgreess $
26 # include "UAS_Exceptions.hh"
27 # include "MMDB_Factory.hh"
28 # include "UAS_Exceptions.hh"
29 # include "MMDB_EmbeddedObject.hh"
30 # include "MMDB_Library.hh"
31 # include "MMDB_BookCase.hh"
32 # include "MMDB_Section.hh"
33 # include "UAS_Collection.hh"
35 #include "Managers/CatMgr.hh"
36 #include "Registration.hh"
38 OLIAS_DB *MMDB_Factory::fOLIASDB = 0;
40 static MMDB_Factory the_mmdb_factory; // instantiation
42 MMDB_Factory::MMDB_Factory ()
44 UAS_Factory::register_factory("mmdb", this);
47 MMDB_Factory::~MMDB_Factory ()
50 UAS_Factory::unregister_factory("mmdb");
54 MMDB_Factory::olias_db () {
56 fOLIASDB = new OLIAS_DB ();
62 MMDB_Factory::createMMDB (const UAS_String &infoLibPath) {
65 // The MMDB leaks memory if we try to create an infolib
66 // with a bogus path. This routine is called often with
67 // infoLibPath == "", so we'll trap that case now
69 if (infoLibPath.length()) {
70 if (!olias_db().validInfoLibPath(infoLibPath)) {
73 (void) sprintf (buf, CATGETS(Set_UAS_MMDB, 2,
74 "Invalid Infolib path: %s"),
75 (char *) infoLibPath);
76 badPath.fErrorMsg = buf;
77 UAS_Common::send_message (badPath);
81 rval = new MMDB (infoLibPath);
82 fMMDBList.append (rval);
86 (void) sprintf (buf, CATGETS(Set_UAS_MMDB, 3,
87 "Ignoring invalid Infolib path: %s"),
88 (char *) infoLibPath);
89 UAS_ErrorMsg theError;
90 theError.fErrorMsg = buf;
91 UAS_Common::send_message (theError);
99 // check to make sure duplicate infolibs are not added.
100 // for a duplicate infolib, just return a pointer to
101 // the already-existing infolib.
102 // (Duplicate infolib means infolibs with the same lid (uid))
104 MMDB_Factory::getMMDB (const UAS_String &infoLibPath) {
106 UAS_String uid(fOLIASDB->getInfoLibUid((char*)infoLibPath));
107 for (i = 0; i < fMMDBList.numItems(); i ++) {
108 if (uid == fMMDBList[i]->infoLibUid())
111 for (i = 0; i < fDeadMMDBList.numItems(); i ++) {
112 if (uid == fDeadMMDBList[i]->infoLibUid())
113 return fDeadMMDBList[i];
115 return createMMDB (infoLibPath);
119 MMDB_Factory::resolveLocator (const UAS_String &loc,
121 info_base *&returnInfoBase) {
124 for (int i = 0; i < fMMDBList.numItems(); i ++) {
125 if (returnInfoBase = fMMDBList[i]->infolib()->
126 getInfobaseByComponent(loc, info_lib::LOC)) {
127 returnMMDB = fMMDBList[i];
134 MMDB_Factory::getMMDBFromObject (UAS_Pointer<UAS_Common> theDoc) {
135 if (theDoc->implementation_type() != "mmdb")
137 switch (theDoc->type()) {
139 MMDB_Library *l = (MMDB_Library *) ((UAS_Common *) theDoc);
143 MMDB_BookCase *c = (MMDB_BookCase *) ((UAS_Common *) theDoc);
148 MMDB_Section *s = (MMDB_Section *) ((UAS_Common *) theDoc);
156 UAS_Pointer<UAS_Common>
157 MMDB_Factory::create_object (const UAS_String &locator) {
159 curURL.locator (locator);
160 MMDB *theMMDB = getMMDB (curURL.fInfoLib);
161 info_base *theInfoBase = 0;
163 if (curURL.fLocator != "") {
164 resolveLocator (curURL.fLocator, theMMDB, theInfoBase);
166 throw (CASTEXCEPT Exception());
168 UAS_Pointer<UAS_Common> rval =
169 new MMDB_Section (*theMMDB, curURL.fLocator);
170 if (curURL.fType == "collection")
171 return new UAS_Collection (rval);
177 if (theMMDB && curURL.fLocator != "") {
178 UAS_Pointer<UAS_Common> rval =
179 new MMDB_Section (*theMMDB, curURL.fLocator);
180 if (curURL.fType == "collection")
181 return new UAS_Collection (rval);
183 } else if (theMMDB && curURL.fInfoBase != "") {
184 return new UAS_Collection(new MMDB_BookCase(*theMMDB,curURL.fInfoBase));
185 } else if (theMMDB && curURL.fInfoLib != "") {
186 return new UAS_Collection (new MMDB_Library(*theMMDB));
188 throw (CASTEXCEPT Exception());
192 UAS_Pointer<UAS_Common>
193 MMDB_Factory::create_relative_object (const UAS_String &locator,
194 UAS_Pointer<UAS_Common> theDoc) {
197 // First, try to get the object by using the current
198 // MMDB information library.
200 MMDB *theMMDB = getMMDBFromObject (theDoc);
202 info_base *ib = theMMDB->infolib()->
203 getInfobaseByComponent(locator, info_lib::LOC);
205 // need to pass precise id to the constructor
206 return new MMDB_Section (*theMMDB, locator);
211 // Couldn't find it in theDoc's infolib. Try all the infolibs
214 for (int i = 0; i < fMMDBList.numItems(); i ++) {
215 info_base *ib = fMMDBList[i]->infolib()->
216 getInfobaseByComponent(locator, info_lib::LOC);
218 // need to pass precise id to the constructor
219 return new MMDB_Section(*(fMMDBList[i]), locator);
223 return UAS_Pointer<UAS_Common>(NULL);
226 UAS_Pointer<UAS_EmbeddedObject>
227 MMDB_Factory::create_embedded_object (const UAS_String &locator) {
228 for (int i = 0; i < fMMDBList.numItems(); i ++) {
229 info_base *ib = fMMDBList[i]->infolib()->
230 getInfobaseByComponent(locator, info_lib::GRA);
232 return new MMDB_EmbeddedObject (*fMMDBList[i], ib, locator);
235 throw (CASTEXCEPT Exception());
238 UAS_Pointer<UAS_EmbeddedObject>
239 MMDB_Factory::create_relative_embedded_object (const UAS_String &locator,
240 UAS_Pointer<UAS_Common> theDoc) {
242 // First try resolving to theDoc's infolib
244 MMDB *theMMDB = getMMDBFromObject (theDoc);
246 info_base *ib = theMMDB->infolib()->
247 getInfobaseByComponent(locator, info_lib::GRA);
249 return new MMDB_EmbeddedObject (*theMMDB, ib, locator);
254 // Cross-infolib link. Iterate through the list of infolibs.
256 for (int i = 0; i < fMMDBList.numItems(); i ++) {
257 info_base *ib = fMMDBList[i]->infolib()->
258 getInfobaseByComponent(locator, info_lib::GRA);
260 return new MMDB_EmbeddedObject (*(fMMDBList[i]), ib, locator);
263 throw (CASTEXCEPT Exception());
267 MMDB_Factory::initializeFactory (UAS_List<UAS_String>& libs) {
269 // Take DTINFO_INFOLIB_PATH and split out the colon-separated
270 // paths. Create an MMDB object for each path and, if creation
271 // was successful, add it to our list of infolibs. Send messages
274 //char *libenv = getenv ("DTINFO_INFOLIB_PATH");
278 //UAS_String libstr (libenv);
279 //UAS_List<UAS_String> fields = libstr.splitFields (':');
280 //for (int i = 0; i < fields.length(); i ++) {
281 //(void) getMMDB (*(UAS_String*)fields[i]);
283 for (int i = 0; i < libs.length(); i ++) {
284 // If this call doesn't create a new MMDB, it sends
285 // an error message to the application.
286 (void) getMMDB (*(UAS_String*)libs[i]);
291 MMDB_Factory::finalizeFactory () {
292 while (fMMDBList.numItems() > 0) {
293 MMDB *dead = fMMDBList[0];
294 fMMDBList.remove(dead);
297 while (fDeadMMDBList.numItems() > 0) {
298 MMDB *deaddead = fDeadMMDBList[0];
299 fDeadMMDBList.remove(deaddead);
307 MMDB_Factory::rootLocators () {
309 // CHANGE THIS TO BE UAS_ObjList...
311 UAS_List<UAS_String> rval;
312 for (int i = 0; i < fMMDBList.numItems(); i ++) {
314 cur.fType = "collection";
315 cur.fInfoLib = fMMDBList[i]->infoLibPath();
316 rval.insert_item (new UAS_String (cur.locator()));
322 MMDB_Factory::destroy_root_object (UAS_Pointer<UAS_Common> theRoot) {
323 if (theRoot->implementation_type() != "mmdb" ||
324 theRoot->type() != UAS_LIBRARY)
325 throw(CASTEXCEPT Exception());
326 MMDB_Library *theLib = (MMDB_Library *) (UAS_Common *) theRoot;
327 MMDB *deadMMDB = &(theLib->mmdb());
329 for (i = 0; i < fMMDBList.numItems(); i ++)
330 if (fMMDBList[i] == deadMMDB)
332 if (i >= fMMDBList.numItems())
333 throw(CASTEXCEPT Exception());
335 // remove deadMMDB before sending msg because the user
336 // can possibly inquire mmdb list on the thread.
337 fMMDBList.remove (deadMMDB);
339 // Give the user a chance to blow away all objects associated
340 // with this library.
342 UAS_LibraryDestroyedMsg theMsg (theRoot);
343 UAS_Common::send_message (theMsg);
345 // Do the final damage.
350 MMDB_Factory::genInfolibName () {
351 static int counter = 0;
353 (void) sprintf (buf, CATGETS(Set_UAS_MMDB, 4, "DtMmdb Library %d"), ++counter);
354 return UAS_String (buf);
357 ///////////////////////////////////////////////////////////////////////////////
358 ///////////////////////////////////////////////////////////////////////////////
362 ///////////////////////////////////////////////////////////////////////////////
363 ///////////////////////////////////////////////////////////////////////////////
365 MMDB_URL::MMDB_URL () {
369 MMDB_URL::locator () {
370 UAS_String rval = "mmdb:";
372 if (fInfoLib != "") {
373 rval = rval + "INFOLIB=" + fInfoLib;
376 if (fInfoBase != "") {
379 rval = rval + "BOOKCASE=" + fInfoBase;
382 if (fLocator != "") {
385 rval = rval + "LOCATOR=" + fLocator;
389 fType = "collection"; // default value
393 rval = rval + "TYPE=" + fType;
400 MMDB_URL::installPair (const UAS_String &key, const UAS_String &value) {
401 if (key == "INFOLIB") {
403 } else if (key == "BOOKCASE") {
405 } else if (key == "TYPE") {
407 } else if (key == "LOCATOR") {
413 MMDB_URL::locator (const UAS_String &in) {
414 UAS_String access, rest;
415 in.split (':', access, rest);
416 UAS_List<UAS_String> pairs = rest.splitFields ('&');
417 for (int i = 0; i < pairs.length(); i ++) {
418 UAS_String key, value;
419 pairs[i]->split ('=', key, value);
420 installPair (key, value);