home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / modules / rdf / src / scook.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  10.3 KB  |  442 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. /* 
  20.    This file implements Super Cookie support for the rdf data model.
  21.    For more information on this file, contact rjc or guha 
  22.    For more information on RDF, look at the RDF section of www.mozilla.org
  23. */
  24.  
  25. #include "rdf-int.h"
  26. #include "scook.h"
  27. #include "glue.h"
  28. #include "remstore.h"
  29.  
  30.  
  31.     /* externs */
  32. extern char* profileDirURL;
  33.  
  34.  
  35.  
  36. char *
  37. makeSCookPathname(char* name)
  38. {
  39.   char        *ans ;
  40.   size_t        s;
  41.  
  42.   if ((ans = (char*) getMem(strlen(profileDirURL) + strlen(name) + 8)) != NULL) {
  43.     s = strlen(profileDirURL);
  44.     memcpy(ans, profileDirURL, s);
  45.     if (ans[s-1] != '/') {
  46.       ans[s++] = '/';
  47.     }
  48.     memcpy(&ans[s], "SCook/", 5);
  49.     s = s + 5;
  50.  
  51. #ifdef    XP_WIN
  52.     if (ans[9] == '|') ans[9] = ':';
  53. #endif
  54.  
  55.     CallPRMkDirUsingFileURL(ans, 00700);  
  56.     memcpy(&ans[s], name, strlen(name));
  57.   }
  58.   return(ans);
  59. }
  60.  
  61.  
  62.  
  63. PRBool
  64. SCookAssert1 (RDFT mcf,   RDF_Resource u, RDF_Resource s, void* v, 
  65.              RDF_ValueType type, PRBool tv)
  66. {
  67.     return 0;
  68. }
  69.  
  70.  
  71.  
  72. PRBool
  73. SCookAssert3 (RDFT mcf,   RDF_Resource u, RDF_Resource s, void* v, 
  74.              RDF_ValueType type, PRBool tv)
  75. {
  76.     return (SCookAssert(mcf, u, s, v, type, tv) != NULL);
  77. }
  78.  
  79.  
  80.  
  81. PRBool
  82. SCookAssert2 (RDFFile  file, RDFT mcf,  RDF_Resource u, RDF_Resource s, void* v, 
  83.              RDF_ValueType type, PRBool tv)
  84. {
  85.   Assertion as = SCookAssert(mcf , u, s, v, type, tv);
  86.   if (as != NULL) {
  87.     void addToAssertionList (RDFFile f, Assertion as) ;
  88.     addToAssertionList(file, as);
  89.     return 1;
  90.   } else return 0;
  91. }
  92.  
  93.  
  94.  
  95. Assertion
  96. SCookAssert (RDFT mcf, RDF_Resource u, RDF_Resource s, void* v, 
  97.               RDF_ValueType type, PRBool tv)
  98. {
  99.   Assertion nextAs, prevAs, newAs; 
  100.   nextAs = prevAs = getArg1(mcf, u);
  101.   while (nextAs != null) {
  102.     if (asEqual(nextAs, u, s, v, type)) return null;
  103.     prevAs = nextAs;
  104.     nextAs = nextAs->next;
  105.   }
  106.   newAs = makeNewAssertion(u, s, v, type, tv);
  107.   if (prevAs == null) {
  108.     setArg1(mcf, u, newAs);
  109.   } else {
  110.     prevAs->next = newAs;
  111.   }
  112.   if (type == RDF_RESOURCE_TYPE) {
  113.     nextAs = prevAs = getArg2(mcf, (RDF_Resource)v);
  114.     while (nextAs != null) {
  115.       prevAs = nextAs;
  116.       nextAs = nextAs->invNext;
  117.     }
  118.     if (prevAs == null) {
  119.       setArg2(mcf,  ((RDF_Resource)v), newAs);
  120.     } else {
  121.       prevAs->invNext = newAs;
  122.     }
  123.   }
  124.   /* XXX have to mark the entire subtree XXX */  
  125.   sendNotifications2(mcf, RDF_ASSERT_NOTIFY, u, s, v, type, tv);
  126.   return newAs;
  127. }
  128.  
  129.  
  130.  
  131. PRBool
  132. SCookUnassert (RDFT mcf, RDF_Resource u, RDF_Resource s, void* v, 
  133.                RDF_ValueType type)
  134. {
  135.   Assertion as = SCookRemove(mcf, u, s, v, type);
  136.   freeMem(as);
  137.   return (as != NULL);
  138. }
  139.  
  140.  
  141.  
  142. Assertion
  143. SCookRemove (RDFT mcf, RDF_Resource u, RDF_Resource s, 
  144.                  void* v, RDF_ValueType type)
  145. {
  146.   Assertion nextAs, prevAs, ans;
  147.   PRBool found = false;
  148.   nextAs = prevAs = getArg1(mcf, u);
  149.   while (nextAs != null) {
  150.     if (asEqual(nextAs, u, s, v, type)) {
  151.       if (prevAs == nextAs) {
  152.     setArg1(mcf, u, nextAs->next);
  153.       } else {
  154.     prevAs->next = nextAs->next;
  155.       }
  156.       found = true;
  157.       ans = nextAs;
  158.       break;
  159.     }
  160.     prevAs = nextAs;
  161.     nextAs = nextAs->next; 
  162.   }
  163.   if (found == false) return null;
  164.   if (type == RDF_RESOURCE_TYPE) {
  165.     nextAs = prevAs = getArg2(mcf, (RDF_Resource)v);
  166.     while (nextAs != null) {
  167.       if (nextAs == ans) {
  168.     if (prevAs == nextAs) {
  169.       setArg2(mcf, ((RDF_Resource)v), nextAs->invNext);
  170.     } else {
  171.       prevAs->invNext = nextAs->invNext;
  172.     }
  173.       }
  174.       prevAs = nextAs;
  175.       nextAs = nextAs->invNext;
  176.     }
  177.   }
  178.   /* Need to make sure that if something is removed from the bookmark tree,
  179.      the type is updated */
  180.   sendNotifications2(mcf, RDF_DELETE_NOTIFY, u, s, v, type, ans->tv);
  181.   return ans;
  182. }
  183.  
  184.  
  185.  
  186. PRBool
  187. SCookHasAssertion (RDFT mcf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv)
  188. {
  189.   Assertion nextAs;
  190.   nextAs = getArg1(mcf, u);
  191.   while (nextAs != null) {
  192.     if (asEqual(nextAs, u, s, v, type) && (nextAs->tv == tv)) return true;
  193.     nextAs = nextAs->next;
  194.   }
  195.   possiblyAccessSCookFile(mcf, u, s, 0);
  196.   return false;
  197. }
  198.  
  199.  
  200.  
  201. void *
  202. SCookGetSlotValue (RDFT mcf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep,  PRBool tv)
  203. {
  204.   Assertion nextAs;
  205.   nextAs = (inversep ? getArg2(mcf, u) : getArg1(mcf, u));
  206.   while (nextAs != null) {
  207.     if ((nextAs->s == s) && (nextAs->tv == tv) && (nextAs->type == type)) {
  208.       return (inversep ? nextAs->u : nextAs->value);
  209.     }
  210.     nextAs = (inversep ? nextAs->invNext : nextAs->next);
  211.   }
  212.    possiblyAccessSCookFile(mcf, u, s, inversep);
  213.   return null;
  214. }
  215.  
  216.  
  217.  
  218. RDF_Cursor
  219. SCookGetSlotValues (RDFT mcf, RDF_Resource u, RDF_Resource s, RDF_ValueType type,  PRBool inversep, PRBool tv)
  220. {
  221. Assertion as = (inversep ? getArg2(mcf, u) : getArg1(mcf, u));
  222.   RDF_Cursor c;
  223.   if (as == null) {
  224.     possiblyAccessSCookFile(mcf, u, s, inversep);
  225.     as = (inversep ? getArg2(mcf, u) : getArg1(mcf, u));
  226.     if (as == NULL) return null;
  227.   }      
  228.   c = (RDF_Cursor)getMem(sizeof(struct RDF_CursorStruct));
  229.   c->u = u;
  230.   c->s = s;
  231.   c->type = type;
  232.   c->inversep = inversep;
  233.   c->tv = tv;
  234.   c->count = 0;
  235.   c->pdata = as;
  236.   return c;
  237. }
  238.  
  239.  
  240.  
  241. void *
  242. SCookNextValue (RDFT mcf, RDF_Cursor c)
  243. {
  244.   while (c->pdata != null) {
  245.     Assertion as = (Assertion) c->pdata;
  246.     if ((as->s == c->s) && (as->tv == c->tv) && (c->type == as->type)) {
  247.       if (c->s == gCoreVocab->RDF_slotsHere) {
  248.     c->value = as->s;
  249.       } else { 
  250.     c->value = (c->inversep ? as->u : as->value);
  251.       }
  252.       c->pdata = (c->inversep ? as->invNext : as->next);
  253.       return c->value;
  254.     }
  255.     c->pdata = (c->inversep ? as->invNext : as->next);
  256.   }
  257.   return null;
  258. }
  259.  
  260.  
  261.  
  262. RDF_Error
  263. SCookDisposeCursor (RDFT mcf, RDF_Cursor c)
  264. {
  265.   freeMem(c);
  266.   return noRDFErr;
  267. }
  268.  
  269.  
  270.  
  271. Assertion
  272. getArg1 (RDFT r, RDF_Resource u)
  273. {
  274.   return PL_HashTableLookup(((SCookDB)r->pdata)->lhash, u);
  275. }
  276.  
  277.  
  278.  
  279. Assertion
  280. getArg2 (RDFT r, RDF_Resource u)
  281. {
  282.   return PL_HashTableLookup(((SCookDB)r->pdata)->rhash, u);
  283. }
  284.  
  285.  
  286.  
  287. void
  288. setArg1 (RDFT r, RDF_Resource u, Assertion as)
  289. {
  290.   if (as == NULL) {
  291.     PL_HashTableRemove(((SCookDB)r->pdata)->lhash, u);
  292.   } else {
  293.     PL_HashTableAdd(((SCookDB)r->pdata)->lhash, u, as);
  294.   }
  295. }
  296.  
  297.  
  298.  
  299. void
  300. setArg2 (RDFT r, RDF_Resource u, Assertion as)
  301.  
  302. {
  303.  if (as == NULL) {
  304.     PL_HashTableRemove(((SCookDB)r->pdata)->rhash, u);
  305.   } else {
  306.     PL_HashTableAdd(((SCookDB)r->pdata)->rhash, u, as);
  307.   }
  308. }
  309.  
  310.  
  311.  
  312. void
  313. gcSCookFile (RDFT rdf, RDFFile f)
  314. {
  315.   int16 n = 0;
  316.   RDFFile f1;
  317.   SCookDB sk = (SCookDB)rdf->pdata;
  318.   f1 = sk->rf;
  319.   
  320.   if (f->locked) return;
  321.   
  322.   if (f == f1) {
  323.     sk->rf = f->next;
  324.   } else {
  325.     RDFFile prev = f1;
  326.     while (f1 != NULL) {
  327.       if (f1 == f) {
  328.     prev->next = f->next;
  329.     break;
  330.       }
  331.       prev = f1;
  332.       f1 = f1->next;
  333.     }
  334.   }
  335.   
  336.   while (n < f->assertionCount) {
  337.     Assertion as = *(f->assertionList + n);
  338.     SCookUnassert(rdf, as->u, as->s, as->value, as->type);
  339.     freeAssertion(as);
  340.     *(f->assertionList + n) = NULL;
  341.     n++;
  342.   }
  343.   n = 0;
  344.   while (n < f->resourceCount) {
  345.     RDF_Resource u = *(f->resourceList + n);
  346.     possiblyGCResource(u);
  347.     n++;
  348.   }
  349.   freeMem(f->assertionList);
  350.   freeMem(f->resourceList);    
  351. }
  352.  
  353.  
  354.  
  355. void
  356. disposeAllSCookFiles (RDFT rdf, RDFFile f)
  357. {
  358.   if (f != NULL) {
  359.     disposeAllSCookFiles(rdf, f->next);
  360.     gcSCookFile(rdf, f);
  361.   }
  362. }
  363.  
  364.  
  365.  
  366. void
  367. SCookDisposeDB (RDFT rdf)
  368. {
  369.   SCookDB db = (SCookDB)rdf->pdata;
  370.   disposeAllSCookFiles(rdf, db->rf);
  371.   PL_HashTableDestroy(db->rhash);
  372.   PL_HashTableDestroy(db->lhash);
  373.   freeMem(db);
  374. }
  375.  
  376.  
  377.  
  378. static PRBool
  379. SCookFileReadp (RDFT rdf, RDF_Resource u)
  380. {
  381.   RDFFile f;
  382.   SCookDB db = (SCookDB)rdf->pdata;
  383.   uint n = 0;
  384.   for (f = db->rf; (f != NULL) ; f = f->next) {
  385.       n++;
  386.     if (urlEquals( resourceID(u), f->url)) {
  387.       return true;
  388.     }
  389.   }
  390.   return false;
  391. }
  392.  
  393.  
  394.  
  395. void
  396. possiblyAccessSCookFile (RDFT mcf, RDF_Resource u, RDF_Resource s, PRBool inversep)
  397. {
  398.   if ((s == gCoreVocab->RDF_parent) && (strstr(resourceID(u), ":/")) &&
  399.       (((SCookDB)mcf->pdata)->rf != NULL) && (containerp(u)) && 
  400.       (resourceType(u) == RDF_RT) && (!SCookFileReadp(mcf, u))) {
  401.     RDFFile newFile = makeRDFFile( resourceID(u), u, 0);
  402.     SCookDB db = (SCookDB)mcf->pdata;
  403.     newFile->next = db->rf;
  404.     newFile->fileType = RDF_XML;
  405.     newFile->db   = mcf;
  406.     db->rf = newFile;
  407.     newFile->db = mcf;
  408.     newFile->assert = SCookAssert2;
  409.     beginReadingRDFFile(newFile);
  410.   }
  411. }
  412.  
  413.  
  414.  
  415. RDFT
  416. MakeSCookDB (char* url)
  417. {
  418.   if (startsWith("rdf:scook:", url) || (startsWith("rdf:ht", url))) {
  419.     RDFT ntr = (RDFT)getMem(sizeof(struct RDF_TranslatorStruct));
  420.     SCookDB sk = (SCookDB)getMem(sizeof(SCookDBStruct));    
  421.     ntr->pdata = sk;
  422.     sk->db     = ntr;
  423.     sk->lhash = PL_NewHashTable(500, idenHash, PL_CompareValues, PL_CompareValues,  NULL, NULL);
  424.     sk->rhash = PL_NewHashTable(500, idenHash, PL_CompareValues, PL_CompareValues,  NULL, NULL);
  425.     ntr->assert = (startsWith("rdf:scook", url) ? SCookAssert3 : SCookAssert1);
  426.     ntr->unassert = SCookUnassert;
  427.     ntr->getSlotValue = SCookGetSlotValue;
  428.     ntr->getSlotValues = SCookGetSlotValues;
  429.     ntr->hasAssertion = SCookHasAssertion;
  430.     ntr->nextValue = SCookNextValue;
  431.     ntr->disposeCursor = SCookDisposeCursor;
  432.     if (startsWith("rdf:scook:", url)) {
  433.         sk->rf = makeRDFFile(makeSCookPathname(&url[10]), NULL, 0);    
  434.         sk->rf->db = (RDFT)ntr;
  435.         sk->rf->assert = SCookAssert2;
  436.     sk->rf->localp = 1;
  437.         beginReadingRDFFile(sk->rf);
  438.     }
  439.     return ntr;
  440.   } else return NULL;
  441. }
  442.