LCOV - code coverage report
Current view: top level - dom/xul/templates - nsRDFConMemberTestNode.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 233 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "nsRDFConMemberTestNode.h"
       7             : #include "nsIRDFContainer.h"
       8             : #include "nsIRDFContainerUtils.h"
       9             : #include "nsRDFCID.h"
      10             : #include "nsIServiceManager.h"
      11             : #include "nsResourceSet.h"
      12             : #include "nsString.h"
      13             : #include "nsXULContentUtils.h"
      14             : 
      15             : #include "mozilla/Logging.h"
      16             : 
      17             : using mozilla::LogLevel;
      18             : 
      19             : extern mozilla::LazyLogModule gXULTemplateLog;
      20             : 
      21           0 : nsRDFConMemberTestNode::nsRDFConMemberTestNode(TestNode* aParent,
      22             :                                                nsXULTemplateQueryProcessorRDF* aProcessor,
      23             :                                                nsIAtom *aContainerVariable,
      24           0 :                                                nsIAtom *aMemberVariable)
      25             :     : nsRDFTestNode(aParent),
      26             :       mProcessor(aProcessor),
      27             :       mContainerVariable(aContainerVariable),
      28           0 :       mMemberVariable(aMemberVariable)
      29             : {
      30           0 :     if (MOZ_LOG_TEST(gXULTemplateLog, LogLevel::Debug)) {
      31           0 :         nsAutoCString props;
      32             : 
      33           0 :         nsResourceSet& containmentProps = aProcessor->ContainmentProperties();
      34           0 :         nsResourceSet::ConstIterator last = containmentProps.Last();
      35           0 :         nsResourceSet::ConstIterator first = containmentProps.First();
      36           0 :         nsResourceSet::ConstIterator iter;
      37             : 
      38           0 :         for (iter = first; iter != last; ++iter) {
      39           0 :             if (iter != first)
      40           0 :                 props += " ";
      41             : 
      42             :             const char* str;
      43           0 :             iter->GetValueConst(&str);
      44             : 
      45           0 :             props += str;
      46             :         }
      47             : 
      48           0 :         nsAutoString cvar(NS_LITERAL_STRING("(none)"));
      49           0 :         if (mContainerVariable)
      50           0 :             mContainerVariable->ToString(cvar);
      51             : 
      52           0 :         nsAutoString mvar(NS_LITERAL_STRING("(none)"));
      53           0 :         if (mMemberVariable)
      54           0 :             mMemberVariable->ToString(mvar);
      55             : 
      56           0 :         MOZ_LOG(gXULTemplateLog, LogLevel::Debug,
      57             :                ("nsRDFConMemberTestNode[%p]: parent=%p member-props=(%s) container-var=%s member-var=%s",
      58             :                 this,
      59             :                 aParent,
      60             :                 props.get(),
      61             :                 NS_ConvertUTF16toUTF8(cvar).get(),
      62             :                 NS_ConvertUTF16toUTF8(mvar).get()));
      63             :     }
      64           0 : }
      65             : 
      66             : nsresult
      67           0 : nsRDFConMemberTestNode::FilterInstantiations(InstantiationSet& aInstantiations,
      68             :                                              bool* aCantHandleYet) const
      69             : {
      70             :     // XXX Uh, factor me, please!
      71             :     nsresult rv;
      72             : 
      73           0 :     if (aCantHandleYet)
      74           0 :         *aCantHandleYet = false;
      75             : 
      76             :     nsCOMPtr<nsIRDFContainerUtils> rdfc =
      77           0 :         do_GetService("@mozilla.org/rdf/container-utils;1");
      78             : 
      79           0 :     if (! rdfc)
      80           0 :         return NS_ERROR_FAILURE;
      81             : 
      82           0 :     nsIRDFDataSource* ds = mProcessor->GetDataSource();
      83             : 
      84           0 :     InstantiationSet::Iterator last = aInstantiations.Last();
      85           0 :     for (InstantiationSet::Iterator inst = aInstantiations.First(); inst != last; ++inst) {
      86             :         bool hasContainerBinding;
      87           0 :         nsCOMPtr<nsIRDFNode> containerValue;
      88           0 :         hasContainerBinding = inst->mAssignments.GetAssignmentFor(mContainerVariable,
      89           0 :                                                                   getter_AddRefs(containerValue));
      90             : 
      91           0 :         nsCOMPtr<nsIRDFResource> containerRes = do_QueryInterface(containerValue);
      92             : 
      93           0 :         nsCOMPtr<nsIRDFContainer> rdfcontainer;
      94             : 
      95           0 :         if (hasContainerBinding && containerRes) {
      96             :             // If we have a container assignment, then see if the
      97             :             // container is an RDF container (bag, seq, alt), and if
      98             :             // so, wrap it.
      99             :             bool isRDFContainer;
     100           0 :             rv = rdfc->IsContainer(ds, containerRes, &isRDFContainer);
     101           0 :             if (NS_FAILED(rv)) return rv;
     102             : 
     103           0 :             if (isRDFContainer) {
     104           0 :                 rdfcontainer = do_CreateInstance("@mozilla.org/rdf/container;1", &rv);
     105           0 :                 if (NS_FAILED(rv)) return rv;
     106             : 
     107           0 :                 rv = rdfcontainer->Init(ds, containerRes);
     108           0 :                 if (NS_FAILED(rv)) return rv;
     109             :             }
     110             :         }
     111             : 
     112             :         bool hasMemberBinding;
     113           0 :         nsCOMPtr<nsIRDFNode> memberValue;
     114           0 :         hasMemberBinding = inst->mAssignments.GetAssignmentFor(mMemberVariable,
     115           0 :                                                                getter_AddRefs(memberValue));
     116             : 
     117           0 :         if (MOZ_LOG_TEST(gXULTemplateLog, LogLevel::Debug)) {
     118           0 :             const char* container = "(unbound)";
     119           0 :             if (hasContainerBinding)
     120           0 :                 containerRes->GetValueConst(&container);
     121             : 
     122           0 :             nsAutoString member(NS_LITERAL_STRING("(unbound)"));
     123           0 :             if (hasMemberBinding)
     124           0 :                 nsXULContentUtils::GetTextForNode(memberValue, member);
     125             : 
     126           0 :             MOZ_LOG(gXULTemplateLog, LogLevel::Debug,
     127             :                    ("nsRDFConMemberTestNode[%p]: FilterInstantiations() container=[%s] member=[%s]",
     128             :                     this, container, NS_ConvertUTF16toUTF8(member).get()));
     129             :         }
     130             : 
     131           0 :         if (hasContainerBinding && hasMemberBinding) {
     132             :             // it's a consistency check. see if we have a assignment that is consistent
     133           0 :             bool isconsistent = false;
     134             : 
     135           0 :             if (rdfcontainer) {
     136             :                 // RDF containers are easy. Just use the container API.
     137             :                 int32_t index;
     138           0 :                 rv = rdfcontainer->IndexOf(memberValue, &index);
     139           0 :                 if (NS_FAILED(rv)) return rv;
     140             : 
     141           0 :                 if (index >= 0)
     142           0 :                     isconsistent = true;
     143             :             }
     144             : 
     145             :             // XXXwaterson oof. if we *are* an RDF container, why do
     146             :             // we still need to grovel through all the containment
     147             :             // properties if the thing we're looking for wasn't there?
     148             : 
     149           0 :             if (! isconsistent) {
     150             :                 // Othewise, we'll need to grovel through the
     151             :                 // membership properties to see if we have an
     152             :                 // assertion that indicates membership.
     153           0 :                 nsResourceSet& containmentProps = mProcessor->ContainmentProperties();
     154           0 :                 for (nsResourceSet::ConstIterator property = containmentProps.First();
     155           0 :                      property != containmentProps.Last();
     156             :                      ++property) {
     157             :                     bool hasAssertion;
     158           0 :                     rv = ds->HasAssertion(containerRes,
     159             :                                           *property,
     160             :                                           memberValue,
     161             :                                           true,
     162           0 :                                           &hasAssertion);
     163           0 :                     if (NS_FAILED(rv)) return rv;
     164             : 
     165           0 :                     if (hasAssertion) {
     166             :                         // it's consistent. leave it in the set and we'll
     167             :                         // run it up to our parent.
     168           0 :                         isconsistent = true;
     169           0 :                         break;
     170             :                     }
     171             :                 }
     172             :             }
     173             : 
     174           0 :             MOZ_LOG(gXULTemplateLog, LogLevel::Debug,
     175             :                    ("    consistency check => %s", isconsistent ? "passed" : "failed"));
     176             : 
     177           0 :             if (isconsistent) {
     178             :                 // Add a memory element to our set-of-support.
     179             :                 Element* element =
     180             :                     new nsRDFConMemberTestNode::Element(containerRes,
     181           0 :                                                         memberValue);
     182           0 :                 inst->AddSupportingElement(element);
     183             :             }
     184             :             else {
     185             :                 // it's inconsistent. remove it.
     186           0 :                 aInstantiations.Erase(inst--);
     187             :             }
     188             : 
     189             :             // We're done, go on to the next instantiation
     190           0 :             continue;
     191             :         }
     192             : 
     193           0 :         if (hasContainerBinding && rdfcontainer) {
     194             :             // We've got a container assignment, and the container is
     195             :             // bound to an RDF container. Add each member as a new
     196             :             // instantiation.
     197           0 :             nsCOMPtr<nsISimpleEnumerator> elements;
     198           0 :             rv = rdfcontainer->GetElements(getter_AddRefs(elements));
     199           0 :             if (NS_FAILED(rv)) return rv;
     200             : 
     201             :             while (1) {
     202             :                 bool hasmore;
     203           0 :                 rv = elements->HasMoreElements(&hasmore);
     204           0 :                 if (NS_FAILED(rv)) return rv;
     205             : 
     206           0 :                 if (! hasmore)
     207           0 :                     break;
     208             : 
     209           0 :                 nsCOMPtr<nsISupports> isupports;
     210           0 :                 rv = elements->GetNext(getter_AddRefs(isupports));
     211           0 :                 if (NS_FAILED(rv)) return rv;
     212             : 
     213           0 :                 nsCOMPtr<nsIRDFNode> node = do_QueryInterface(isupports);
     214           0 :                 if (! node)
     215           0 :                     return NS_ERROR_UNEXPECTED;
     216             : 
     217           0 :                 if (MOZ_LOG_TEST(gXULTemplateLog, LogLevel::Debug)) {
     218           0 :                     nsAutoString member;
     219           0 :                     nsXULContentUtils::GetTextForNode(node, member);
     220             : 
     221           0 :                     MOZ_LOG(gXULTemplateLog, LogLevel::Debug,
     222             :                            ("    member => %s", NS_ConvertUTF16toUTF8(member).get()));
     223             :                 }
     224             : 
     225           0 :                 Instantiation newinst = *inst;
     226           0 :                 newinst.AddAssignment(mMemberVariable, node);
     227             : 
     228             :                 Element* element =
     229           0 :                     new nsRDFConMemberTestNode::Element(containerRes, node);
     230           0 :                 newinst.AddSupportingElement(element);
     231           0 :                 aInstantiations.Insert(inst, newinst);
     232           0 :             }
     233             :         }
     234             : 
     235           0 :         if (hasMemberBinding) {
     236             :             // Oh, this is so nasty. If we have a member assignment, then
     237             :             // grovel through each one of our inbound arcs to see if
     238             :             // any of them are ordinal properties (like an RDF
     239             :             // container might have). If so, walk it backwards to get
     240             :             // the container we're in.
     241           0 :             nsCOMPtr<nsISimpleEnumerator> arcsin;
     242           0 :             rv = ds->ArcLabelsIn(memberValue, getter_AddRefs(arcsin));
     243           0 :             if (NS_FAILED(rv)) return rv;
     244             : 
     245             :             while (1) {
     246           0 :                 nsCOMPtr<nsIRDFResource> property;
     247             : 
     248             :                 {
     249             :                     bool hasmore;
     250           0 :                     rv = arcsin->HasMoreElements(&hasmore);
     251           0 :                     if (NS_FAILED(rv)) return rv;
     252             : 
     253           0 :                     if (! hasmore)
     254           0 :                         break;
     255             : 
     256           0 :                     nsCOMPtr<nsISupports> isupports;
     257           0 :                     rv = arcsin->GetNext(getter_AddRefs(isupports));
     258           0 :                     if (NS_FAILED(rv)) return rv;
     259             : 
     260           0 :                     property = do_QueryInterface(isupports);
     261           0 :                     if (! property)
     262           0 :                         return NS_ERROR_UNEXPECTED;
     263             :                 }
     264             : 
     265             :                 // Ordinal properties automagically indicate container
     266             :                 // membership as far as we're concerned. Note that
     267             :                 // we're *only* concerned with ordinal properties
     268             :                 // here: the next block will worry about the other
     269             :                 // membership properties.
     270             :                 bool isordinal;
     271           0 :                 rv = rdfc->IsOrdinalProperty(property, &isordinal);
     272           0 :                 if (NS_FAILED(rv)) return rv;
     273             : 
     274           0 :                 if (isordinal) {
     275             :                     // If we get here, we've found a property that
     276             :                     // indicates container membership leading *into* a
     277             :                     // member node. Find all the people that point to
     278             :                     // it, and call them containers.
     279           0 :                     nsCOMPtr<nsISimpleEnumerator> sources;
     280           0 :                     rv = ds->GetSources(property, memberValue, true,
     281           0 :                                         getter_AddRefs(sources));
     282           0 :                     if (NS_FAILED(rv)) return rv;
     283             : 
     284             :                     while (1) {
     285             :                         bool hasmore;
     286           0 :                         rv = sources->HasMoreElements(&hasmore);
     287           0 :                         if (NS_FAILED(rv)) return rv;
     288             : 
     289           0 :                         if (! hasmore)
     290           0 :                             break;
     291             : 
     292           0 :                         nsCOMPtr<nsISupports> isupports;
     293           0 :                         rv = sources->GetNext(getter_AddRefs(isupports));
     294           0 :                         if (NS_FAILED(rv)) return rv;
     295             : 
     296           0 :                         nsCOMPtr<nsIRDFResource> source = do_QueryInterface(isupports);
     297           0 :                         if (! source)
     298           0 :                             return NS_ERROR_UNEXPECTED;
     299             : 
     300           0 :                         if (MOZ_LOG_TEST(gXULTemplateLog, LogLevel::Debug)) {
     301             :                             const char* container;
     302           0 :                             source->GetValueConst(&container);
     303             : 
     304           0 :                             MOZ_LOG(gXULTemplateLog, LogLevel::Debug,
     305             :                                    ("    container => %s", container));
     306             :                         }
     307             : 
     308             :                         // Add a new instantiation
     309           0 :                         Instantiation newinst = *inst;
     310           0 :                         newinst.AddAssignment(mContainerVariable, source);
     311             : 
     312             :                         Element* element =
     313             :                             new nsRDFConMemberTestNode::Element(source,
     314           0 :                                                                 memberValue);
     315           0 :                         newinst.AddSupportingElement(element);
     316             : 
     317           0 :                         aInstantiations.Insert(inst, newinst);
     318           0 :                     }
     319             :                 }
     320           0 :             }
     321             :         }
     322             : 
     323           0 :         if ((hasContainerBinding && ! hasMemberBinding) ||
     324           0 :             (! hasContainerBinding && hasMemberBinding)) {
     325             :             // it's an open ended query on the container or member. go
     326             :             // through our containment properties to see if anything
     327             :             // applies.
     328           0 :             nsResourceSet& containmentProps = mProcessor->ContainmentProperties();
     329           0 :             for (nsResourceSet::ConstIterator property = containmentProps.First();
     330           0 :                  property != containmentProps.Last();
     331             :                  ++property) {
     332           0 :                 nsCOMPtr<nsISimpleEnumerator> results;
     333           0 :                 if (hasContainerBinding) {
     334           0 :                     rv = ds->GetTargets(containerRes, *property, true,
     335           0 :                                         getter_AddRefs(results));
     336             :                 }
     337             :                 else {
     338           0 :                     rv = ds->GetSources(*property, memberValue, true,
     339           0 :                                         getter_AddRefs(results));
     340             :                 }
     341           0 :                 if (NS_FAILED(rv)) return rv;
     342             : 
     343             :                 while (1) {
     344             :                     bool hasmore;
     345           0 :                     rv = results->HasMoreElements(&hasmore);
     346           0 :                     if (NS_FAILED(rv)) return rv;
     347             : 
     348           0 :                     if (! hasmore)
     349           0 :                         break;
     350             : 
     351           0 :                     nsCOMPtr<nsISupports> isupports;
     352           0 :                     rv = results->GetNext(getter_AddRefs(isupports));
     353           0 :                     if (NS_FAILED(rv)) return rv;
     354             : 
     355             :                     nsIAtom* variable;
     356           0 :                     nsCOMPtr<nsIRDFNode> value;
     357           0 :                     nsCOMPtr<nsIRDFResource> valueRes;
     358             : 
     359           0 :                     if (hasContainerBinding) {
     360           0 :                         variable = mMemberVariable;
     361             : 
     362           0 :                         value = do_QueryInterface(isupports);
     363           0 :                         NS_ASSERTION(value != nullptr, "member is not an nsIRDFNode");
     364           0 :                         if (! value) continue;
     365             : 
     366           0 :                         if (MOZ_LOG_TEST(gXULTemplateLog, LogLevel::Debug)) {
     367           0 :                             nsAutoString s;
     368           0 :                             nsXULContentUtils::GetTextForNode(value, s);
     369             : 
     370           0 :                             MOZ_LOG(gXULTemplateLog, LogLevel::Debug,
     371             :                                    ("    member => %s", NS_ConvertUTF16toUTF8(s).get()));
     372             :                         }
     373             :                     }
     374             :                     else {
     375           0 :                         variable = mContainerVariable;
     376             : 
     377           0 :                         valueRes = do_QueryInterface(isupports);
     378           0 :                         NS_ASSERTION(valueRes != nullptr, "container is not an nsIRDFResource");
     379           0 :                         if (! valueRes) continue;
     380             : 
     381           0 :                         value = valueRes;
     382             : 
     383           0 :                         if (MOZ_LOG_TEST(gXULTemplateLog, LogLevel::Debug)) {
     384             :                             const char* s;
     385           0 :                             valueRes->GetValueConst(&s);
     386             : 
     387           0 :                             MOZ_LOG(gXULTemplateLog, LogLevel::Debug,
     388             :                                    ("    container => %s", s));
     389             :                         }
     390             :                     }
     391             : 
     392             :                     // Copy the original instantiation, and add it to the
     393             :                     // instantiation set with the new assignment that we've
     394             :                     // introduced. Ownership will be transferred to the
     395           0 :                     Instantiation newinst = *inst;
     396           0 :                     newinst.AddAssignment(variable, value);
     397             : 
     398             :                     Element* element;
     399           0 :                     if (hasContainerBinding) {
     400           0 :                         element =
     401           0 :                             new nsRDFConMemberTestNode::Element(containerRes, value);
     402             :                     }
     403             :                     else {
     404           0 :                         element =
     405           0 :                             new nsRDFConMemberTestNode::Element(valueRes, memberValue);
     406             :                     }
     407             : 
     408           0 :                     if (! element)
     409           0 :                         return NS_ERROR_OUT_OF_MEMORY;
     410             : 
     411           0 :                     newinst.AddSupportingElement(element);
     412             : 
     413           0 :                     aInstantiations.Insert(inst, newinst);
     414           0 :                 }
     415             :             }
     416             :         }
     417             : 
     418           0 :         if (! hasContainerBinding && ! hasMemberBinding) {
     419             :             // Neither container nor member assignment!
     420           0 :             if (!aCantHandleYet) {
     421           0 :                 nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_MEMBER_UNBOUND);
     422           0 :                 return NS_ERROR_UNEXPECTED;
     423             :             }
     424             : 
     425           0 :             *aCantHandleYet = true;
     426           0 :             return NS_OK;
     427             :         }
     428             : 
     429             :         // finally, remove the "under specified" instantiation.
     430           0 :         aInstantiations.Erase(inst--);
     431             :     }
     432             : 
     433           0 :     return NS_OK;
     434             : }
     435             : 
     436             : bool
     437           0 : nsRDFConMemberTestNode::CanPropagate(nsIRDFResource* aSource,
     438             :                                      nsIRDFResource* aProperty,
     439             :                                      nsIRDFNode* aTarget,
     440             :                                      Instantiation& aInitialBindings) const
     441             : {
     442             :     nsresult rv;
     443             : 
     444           0 :     bool canpropagate = false;
     445             : 
     446             :     nsCOMPtr<nsIRDFContainerUtils> rdfc =
     447           0 :         do_GetService("@mozilla.org/rdf/container-utils;1");
     448             : 
     449           0 :     if (! rdfc)
     450           0 :         return false;
     451             : 
     452             :     // We can certainly propagate ordinal properties
     453           0 :     rv = rdfc->IsOrdinalProperty(aProperty, &canpropagate);
     454           0 :     if (NS_FAILED(rv)) return false;
     455             : 
     456           0 :     if (! canpropagate) {
     457           0 :         canpropagate = mProcessor->ContainmentProperties().Contains(aProperty);
     458             :     }
     459             : 
     460           0 :     if (MOZ_LOG_TEST(gXULTemplateLog, LogLevel::Debug)) {
     461             :         const char* source;
     462           0 :         aSource->GetValueConst(&source);
     463             : 
     464             :         const char* property;
     465           0 :         aProperty->GetValueConst(&property);
     466             : 
     467           0 :         nsAutoString target;
     468           0 :         nsXULContentUtils::GetTextForNode(aTarget, target);
     469             : 
     470           0 :         MOZ_LOG(gXULTemplateLog, LogLevel::Debug,
     471             :                ("nsRDFConMemberTestNode[%p]: CanPropagate([%s]==[%s]=>[%s]) => %s",
     472             :                 this, source, property, NS_ConvertUTF16toUTF8(target).get(),
     473             :                 canpropagate ? "true" : "false"));
     474             :     }
     475             : 
     476           0 :     if (canpropagate) {
     477           0 :         aInitialBindings.AddAssignment(mContainerVariable, aSource);
     478           0 :         aInitialBindings.AddAssignment(mMemberVariable, aTarget);
     479           0 :         return true;
     480             :     }
     481             : 
     482           0 :     return false;
     483             : }
     484             : 
     485             : void
     486           0 : nsRDFConMemberTestNode::Retract(nsIRDFResource* aSource,
     487             :                                 nsIRDFResource* aProperty,
     488             :                                 nsIRDFNode* aTarget) const
     489             : {
     490           0 :     bool canretract = false;
     491             : 
     492             :     nsCOMPtr<nsIRDFContainerUtils> rdfc =
     493           0 :         do_GetService("@mozilla.org/rdf/container-utils;1");
     494             : 
     495           0 :     if (! rdfc)
     496           0 :         return;
     497             : 
     498             :     // We can certainly retract ordinal properties
     499             :     nsresult rv;
     500           0 :     rv = rdfc->IsOrdinalProperty(aProperty, &canretract);
     501           0 :     if (NS_FAILED(rv)) return;
     502             : 
     503           0 :     if (! canretract) {
     504           0 :         canretract = mProcessor->ContainmentProperties().Contains(aProperty);
     505             :     }
     506             : 
     507           0 :     if (canretract) {
     508           0 :         mProcessor->RetractElement(Element(aSource, aTarget));
     509             :     }
     510             : }

Generated by: LCOV version 1.13