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

unimountgen.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 "unimountgen.h"
00008 #include "wvmoniker.h"
00009 
00010 /***** UniMountGen *****/
00011 
00012 WvString UniMountGen::get(const UniConfKey &key)
00013 {
00014     UniGenMount *found = findmount(key);
00015     if (!found)
00016         return WvString::null;
00017 
00018     return found->gen->get(trimkey(found->key, key));
00019 }
00020 
00021 
00022 void UniMountGen::set(const UniConfKey &key, WvStringParm value)
00023 {
00024     UniGenMount *found = findmount(key);
00025     if (!found)
00026         return;
00027 
00028     found->gen->set(trimkey(found->key, key), value);
00029 }
00030 
00031 
00032 bool UniMountGen::exists(const UniConfKey &key)
00033 {
00034     UniGenMount *found = findmount(key);
00035     if (!found)
00036         return false;
00037 
00038     return found->gen->exists(trimkey(found->key, key));
00039 }
00040 
00041 
00042 bool UniMountGen::haschildren(const UniConfKey &key)
00043 {
00044     UniGenMount *found = findmount(key);
00045     if (!found)
00046         return false;
00047 
00048     if (found->gen->haschildren(trimkey(found->key, key)))
00049         return true;
00050 
00051     // if we get here, the generator we used didn't have a subkey.  We want
00052     // to see if there's anyone mounted at a subkey of the requested key; if
00053     // so, then we definitely have a subkey.
00054     MountList::Iter i(mounts);
00055     for (i.rewind(); i.next(); )
00056     {
00057         if (key.suborsame(i->key))
00058             return true;
00059 
00060         // the list is sorted innermost-first.  So if we find the key
00061         // we started with, we've finished searching all children of it.
00062         if (i->gen == found->gen)
00063             break;
00064     }
00065 
00066     return false;
00067 }
00068 
00069 
00070 bool UniMountGen::refresh()
00071 {
00072     hold_delta();
00073 
00074     bool result = true;
00075 
00076     MountList::Iter i(mounts);
00077     for (i.rewind(); i.next(); )
00078         result = result && i->gen->refresh();
00079 
00080     unhold_delta();
00081     return result;
00082 }
00083 
00084 
00085 void UniMountGen::commit()
00086 {
00087     hold_delta();
00088 
00089     MountList::Iter i(mounts);
00090     for (i.rewind(); i.next();)
00091         i->gen->commit();
00092 
00093     unhold_delta();
00094 }
00095 
00096 
00097 UniConfGen *UniMountGen::mount(const UniConfKey &key,
00098                                WvStringParm moniker, bool refresh)
00099 {
00100     UniConfGen *gen = wvcreate<UniConfGen>(moniker);
00101     if (gen)
00102         mountgen(key, gen, refresh); // assume always succeeds for now
00103 
00104     assert(gen && "Moniker doesn't get us a generator!");
00105     return gen;
00106 }
00107 
00108 
00109 UniConfGen *UniMountGen::mountgen(const UniConfKey &key,
00110                                   UniConfGen *gen, bool refresh)
00111 {
00112     if (!gen)
00113         return NULL;
00114     
00115     UniGenMount *newgen = new UniGenMount(gen, key);
00116     gen->setcallback(UniConfGenCallback(this,
00117                                 &UniMountGen::gencallback), &newgen->key);
00118 
00119     hold_delta();
00120     delta(key, WvString());
00121 
00122     makemount(key);
00123 
00124     if (gen && refresh)
00125         gen->refresh();
00126 
00127     mounts.prepend(newgen, true);
00128     
00129     delta(key, get(key));
00130     unhold_delta();
00131     return gen;
00132 }
00133 
00134 
00135 void UniMountGen::unmount(UniConfGen *gen, bool commit)
00136 {
00137     if (!gen)
00138         return;
00139     
00140     MountList::Iter i(mounts);
00141 
00142     for (i.rewind(); i.next() && i->gen != gen; )
00143         ;
00144 
00145     if (i->gen != gen)
00146         return;
00147 
00148     hold_delta();
00149     
00150     if (commit)
00151         gen->commit();
00152     gen->setcallback(UniConfGenCallback(), NULL);
00153 
00154     UniConfKey key(i->key);
00155     UniConfGen *next = NULL;
00156 
00157     delta(key, WvString());
00158 
00159     // Find the first generator mounted past the one we're removing (if
00160     // any). This way we can make sure that each generator still has keys
00161     // leading up to it (in case they lost their mountpoint due to the
00162     // unmounted generator)
00163     i.xunlink();
00164     if (i.next())
00165         next = i->gen;
00166 
00167     for (i.rewind(); i.next() && i->gen != next; )
00168     {
00169         if (key.suborsame(i->key) && key != i->key)
00170         {
00171             makemount(i->key);
00172             delta(i->key, get(i->key));
00173         }
00174     } 
00175 
00176     unhold_delta();
00177 }
00178 
00179 
00180 UniConfGen *UniMountGen::whichmount(const UniConfKey &key,
00181                                     UniConfKey *mountpoint)
00182 {
00183     MountList::Iter i(mounts);
00184 
00185     for (i.rewind(); i.next(); )
00186     {
00187         if (i->key.suborsame(key))
00188         {
00189             if (mountpoint)
00190                 *mountpoint = key;
00191             return i->gen;
00192         }
00193     }
00194 
00195     return NULL;
00196 }
00197 
00198 
00199 bool UniMountGen::ismountpoint(const UniConfKey &key)
00200 {
00201     MountList::Iter i(mounts);
00202 
00203     for (i.rewind(); i.next(); )
00204     {
00205         if (i->key == key)
00206             return true;
00207     }
00208 
00209     return false;
00210 }
00211 
00212 
00213 UniMountGen::Iter *UniMountGen::iterator(const UniConfKey &key)
00214 {
00215     UniGenMount *found = findmount(key);
00216     if (found)
00217         return found->gen->iterator(trimkey(found->key, key));
00218     return new NullIter;
00219 }
00220 
00221 
00222 UniMountGen::UniGenMount *UniMountGen::findmount(const UniConfKey &key)
00223 {
00224     // Find the needed generator and keep it as a lastfound
00225     MountList::Iter i(mounts);
00226     for (i.rewind(); i.next(); )
00227     {
00228         if (i->key.suborsame(key))
00229             return i.ptr();
00230     } 
00231 
00232     return NULL;
00233 }
00234 
00235 
00236 void UniMountGen::gencallback(const UniConfKey &key, WvStringParm value,
00237                                   void *userdata)
00238 {
00239     UniConfKey *base = static_cast<UniConfKey*>(userdata);
00240     delta(UniConfKey(*base, key), value);
00241 }
00242 
00243 
00244 void UniMountGen::makemount(const UniConfKey &key)
00245 {
00246     // Create any keys needed leading up to the mount generator so that the
00247     // mountpoint exists
00248     UniConfKey::Iter i(key);
00249     UniConfKey points;
00250 
00251     for (i.rewind(); i.next(); )
00252     {
00253         points.append(*i);
00254         if (get(points).isnull())
00255             set(points, "");
00256     }
00257 
00258     // Set the mountpoint in the sub generator instead of on the generator
00259     // itself (since set will set it on the generator, instead of making the
00260     // mountpoint)
00261     UniGenMount *found = findmount(points.removelast());
00262     if (!found)
00263         return;
00264 
00265     if (found->gen->get(trimkey(found->key, key)).isnull())
00266         found->gen->set(trimkey(found->key, key), "");
00267 }

Generated on Sat Feb 21 21:05:21 2004 for WvStreams by doxygen 1.3.5