Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

unimounttreegen.cc

Go to the documentation of this file.
00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  * 
00005  * Defines a UniConfGen that manages a tree of UniConfGen instances.
00006  */
00007 #include "unimounttreegen.h"
00008 #include "wvmoniker.h"
00009 
00010 /***** UniMountTreeGen *****/
00011 
00012 UniMountTreeGen::UniMountTreeGen()
00013 {
00014     mounts = new UniMountTree(NULL, UniConfKey::EMPTY);
00015 }
00016 
00017 
00018 UniMountTreeGen::~UniMountTreeGen()
00019 {
00020     // destroys all generators
00021     delete mounts;
00022 }
00023 
00024 
00025 WvString UniMountTreeGen::get(const UniConfKey &key)
00026 {
00027     // consult the generators
00028     hold_delta();
00029     UniMountTree::GenIter it(*mounts, key);
00030     for (it.rewind(); it.next(); )
00031     {
00032         UniConfGen *gen = it.ptr();
00033         WvString result = gen->get(it.tail());
00034         if (!result.isnull())
00035         {
00036             unhold_delta();
00037             return result;
00038         }
00039     }
00040     unhold_delta();
00041     
00042     // ensure key exists if it is in the path of a mountpoint
00043     UniMountTree *node = mounts->find(key);
00044     if (node)
00045         return ""; // fake read-only key not provided by anyone
00046 
00047     // no matches
00048     return WvString::null;
00049 }
00050 
00051 
00052 void UniMountTreeGen::set(const UniConfKey &key, WvStringParm value)
00053 {
00054     // update the generator that defines the key, if any
00055     UniConfKey mountpoint;
00056     UniConfGen *provider = whichmount(key, &mountpoint);
00057     if (provider)
00058         provider->set(mountpoint, value);
00059 }
00060 
00061 
00062 bool UniMountTreeGen::exists(const UniConfKey &key)
00063 {
00064     // ensure key exists if it is in the path of a mountpoint
00065     UniMountTree *node = mounts->find(key);
00066     if (node)
00067         return true;
00068     
00069     // otherwise consult the generators
00070     hold_delta();
00071     UniMountTree::GenIter it(*mounts, key);
00072     for (it.rewind(); it.next(); )
00073     {
00074         UniConfGen *gen = it.ptr();
00075         if (gen->exists(it.tail()))
00076         {
00077             unhold_delta();
00078             return true;
00079         }
00080     }
00081     unhold_delta();
00082 
00083     // no match
00084     return false;
00085 }
00086 
00087 
00088 bool UniMountTreeGen::haschildren(const UniConfKey &key)
00089 {
00090     hold_delta();
00091     UniMountTree *node = mounts->find(key);
00092     bool result = node && node->haschildren();
00093     if (! result)
00094     {
00095         UniMountTree::GenIter it(*mounts, key);
00096         for (it.rewind(); it.next(); )
00097         {
00098             UniConfGen *gen = it.ptr();
00099             if (gen->haschildren(it.tail()))
00100             {
00101                 result = true;
00102                 break;
00103             }
00104         }
00105     }
00106     unhold_delta();
00107     return result;
00108 }
00109 
00110 
00111 bool UniMountTreeGen::refresh()
00112 {
00113     hold_delta();
00114     bool result = true;
00115 
00116     UniConfGenList::Iter i(mounts->generators);
00117     for (i.rewind(); i.next();)
00118         result = result && i->refresh();
00119 
00120     unhold_delta();
00121     return result;
00122 }
00123 
00124 
00125 void UniMountTreeGen::commit()
00126 {
00127     hold_delta();
00128 
00129     UniConfGenList::Iter i(mounts->generators);
00130     for (i.rewind(); i.next();)
00131         i->commit();
00132 
00133     unhold_delta();
00134 }
00135 
00136 
00137 UniConfGen *UniMountTreeGen::mount(const UniConfKey &key,
00138     WvStringParm moniker, bool refresh)
00139 {
00140     UniConfGen *gen = wvcreate<UniConfGen>(moniker);
00141     if (gen)
00142         mountgen(key, gen, refresh); // assume always succeeds for now
00143     assert(gen && "Moniker doesn't get us a generator!");
00144     return gen;
00145 }
00146 
00147 
00148 UniConfGen *UniMountTreeGen::mountgen(const UniConfKey &key,
00149     UniConfGen *gen, bool refresh)
00150 {
00151     UniMountTree *node = mounts->findormake(key);
00152     node->generators.append(gen, true);
00153     
00154     hold_delta();
00155     
00156     gen->setcallback(UniConfGenCallback(this,
00157         &UniMountTreeGen::gencallback), node);
00158     if (gen && refresh)
00159         gen->refresh();
00160     
00161     unhold_delta();
00162     return gen;
00163 }
00164 
00165 
00166 void UniMountTreeGen::unmount(const UniConfKey &key,
00167     UniConfGen *gen, bool commit)
00168 {
00169     UniMountTree *node = mounts->find(key);
00170     if (!node)
00171         return;
00172 
00173     UniConfGenList::Iter genit(node->generators);
00174     if (! genit.find(gen))
00175         return;
00176 
00177     hold_delta();
00178     
00179     if (commit)
00180         gen->commit();
00181     gen->setcallback(UniConfGenCallback(), NULL);
00182 
00183     node->generators.unlink(gen);
00184     
00185     unhold_delta();
00186 }
00187 
00188 
00189 UniConfGen *UniMountTreeGen::whichmount(const UniConfKey &key,
00190     UniConfKey *mountpoint)
00191 {
00192     hold_delta();
00193     
00194     // see if a generator acknowledges the key
00195     UniMountTree::GenIter it(*mounts, key);
00196     for (it.rewind(); it.next(); )
00197     {
00198         UniConfGen *gen = it.ptr();
00199         if (gen->exists(it.tail()))
00200             goto found;
00201     }
00202     // find the generator that would be used to set the value
00203     it.rewind();
00204     if (! it.next())
00205     {
00206         unhold_delta();
00207         return NULL;
00208     }
00209 
00210 found:
00211     if (mountpoint)
00212         *mountpoint = it.tail();
00213     unhold_delta();
00214     return it.ptr();
00215 }
00216 
00217 
00218 bool UniMountTreeGen::ismountpoint(const UniConfKey &key)
00219 {
00220     UniMountTree *node = mounts->find(key);
00221     return node && ! node->generators.isempty();
00222 }
00223 
00224 
00225 UniMountTreeGen::Iter *UniMountTreeGen::iterator(const UniConfKey &key)
00226 {
00227     return new KeyIter(*this, key);
00228 }
00229 
00230 
00231 void UniMountTreeGen::prune(UniMountTree *node)
00232 {
00233     while (node != mounts && !node->isessential())
00234     {
00235         UniMountTree *next = node->parent();
00236         delete node;
00237         node = next;
00238     }
00239 }
00240 
00241 
00242 void UniMountTreeGen::gencallback(const UniConfKey &key, WvStringParm value,
00243                                   void *userdata)
00244 {
00245     UniMountTree *node = static_cast<UniMountTree*>(userdata);
00246     delta(UniConfKey(node->fullkey(), key), value);
00247 }
00248 
00249 
00250 
00251 /***** UniMountTreeGen::KeyIter *****/
00252 
00253 UniMountTreeGen::KeyIter::KeyIter(UniMountTreeGen &root, const UniConfKey &key) 
00254     : xroot(&root), xkey(key), genit(*root.mounts, key),
00255         hack(71), hackit(hack)
00256 {
00257 }
00258 
00259 
00260 void UniMountTreeGen::KeyIter::rewind()
00261 {
00262     xroot->hold_delta();
00263     hack.zap();
00264 
00265     // find nodes provided by the root of any mount points.
00266     // (if we want to iterate over /foo, then mounts directly on /foo/blah and
00267     // /foo/snoo must be included)
00268     UniMountTree *node = xroot->mounts->find(xkey);
00269     if (node)
00270     {
00271         UniMountTree::Iter nodeit(*node);
00272         for (nodeit.rewind(); nodeit.next(); )
00273             hack.add(new WvString(nodeit->key()), true);
00274     }
00275 
00276     // walk through *all* generators and add any appropriate sub-keys
00277     // provided by each generator.
00278     for (genit.rewind(); genit.next(); )
00279     {
00280         UniConfGen *gen = genit.ptr();
00281         UniConfGen::Iter *keyit = gen->iterator(genit.tail());
00282         for (keyit->rewind(); keyit->next(); )
00283             hack.add(new WvString(keyit->key()), true);
00284         delete keyit;
00285     }
00286 
00287     hackit.rewind();
00288     xroot->unhold_delta();
00289 }
00290 
00291 
00292 bool UniMountTreeGen::KeyIter::next()
00293 {
00294     return hackit.next();
00295 }
00296 
00297 
00298 UniConfKey UniMountTreeGen::KeyIter::key() const
00299 {
00300     return UniConfKey(hackit());
00301 }
00302 
00303 
00304 
00305 /***** UniMountTree *****/
00306 
00307 UniMountTree::UniMountTree(UniMountTree *parent,
00308     const UniConfKey &key) :
00309     UniConfTree<UniMountTree>(parent, key)
00310 {
00311 }
00312 
00313 
00314 UniMountTree::~UniMountTree()
00315 {
00316 }
00317 
00318 
00319 UniMountTree *UniMountTree::findnearest(const UniConfKey &key,
00320     int &split)
00321 {
00322     split = 0;
00323     UniMountTree *node = this;
00324     UniConfKey::Iter it(key);
00325     for (it.rewind(); it.next(); split++)
00326     {
00327         UniMountTree *next = node->findchild(it());
00328         if (!next)
00329             break;
00330         node = next;
00331     }
00332     return node;
00333 }
00334 
00335 
00336 UniMountTree *UniMountTree::findormake(const UniConfKey &key)
00337 {
00338     UniMountTree *node = this;
00339     UniConfKey::Iter it(key);
00340     for (it.rewind(); it.next(); )
00341     {
00342         UniMountTree *prev = node;
00343         node = prev->findchild(it());
00344         if (!node)
00345             node = new UniMountTree(prev, it());
00346     }
00347     return node;
00348 }
00349 
00350 
00351 
00352 /***** UniMountTree::MountIter *****/
00353 
00354 UniMountTree::MountIter::MountIter(UniMountTree &root,
00355     const UniConfKey &key)
00356     : xkey(key)
00357 {
00358     bestnode = root.findnearest(key, bestsplit);
00359 }
00360 
00361 
00362 void UniMountTree::MountIter::rewind()
00363 {
00364     xnode = NULL;
00365 }
00366 
00367 
00368 bool UniMountTree::MountIter::next()
00369 {
00370     if (! xnode)
00371     {
00372         xsplit = bestsplit;
00373         xnode = bestnode;
00374     }
00375     else if (xsplit != 0)
00376     {
00377         xsplit -= 1;
00378         xnode = xnode->parent();
00379     }
00380     else
00381         return false;
00382     return true;
00383 }
00384 
00385 
00386 
00387 /***** UniMountTree::GenIter *****/
00388 
00389 UniMountTree::GenIter::GenIter(UniMountTree &root,
00390     const UniConfKey &key) :
00391     UniMountTree::MountIter(root, key),
00392     genit(NULL)
00393 {
00394 }
00395 
00396 
00397 UniMountTree::GenIter::~GenIter()
00398 {
00399     delete genit;
00400 }
00401 
00402 
00403 void UniMountTree::GenIter::rewind()
00404 {
00405     if (genit)
00406     {
00407         delete genit;
00408         genit = NULL;
00409     }
00410     UniMountTree::MountIter::rewind();
00411 }
00412 
00413 
00414 bool UniMountTree::GenIter::next()
00415 {
00416     for (;;)
00417     {
00418         if (genit && genit->next())
00419             return true;
00420         if (! UniMountTree::MountIter::next())
00421             return false;
00422 
00423         genit = new UniConfGenList::Iter(node()->generators);
00424         genit->rewind();
00425     }
00426     return false;
00427 }

Generated on Sat Mar 13 14:55:24 2004 for WvStreams by doxygen 1.3.6-20040222