content/xul/templates/src/nsRDFConInstanceTestNode.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     6 #include "nsIComponentManager.h"
     7 #include "nsIRDFContainer.h"
     8 #include "nsIRDFContainerUtils.h"
     9 #include "nsIServiceManager.h"
    10 #include "nsRDFCID.h"
    11 #include "nsRDFConInstanceTestNode.h"
    12 #include "nsResourceSet.h"
    14 #include "prlog.h"
    15 #ifdef PR_LOGGING
    16 #include "nsXULContentUtils.h"
    17 extern PRLogModuleInfo* gXULTemplateLog;
    19 static const char*
    20 TestToString(nsRDFConInstanceTestNode::Test aTest) {
    21     switch (aTest) {
    22     case nsRDFConInstanceTestNode::eFalse:    return "false";
    23     case nsRDFConInstanceTestNode::eTrue:     return "true";
    24     case nsRDFConInstanceTestNode::eDontCare: return "dontcare";
    25     }
    26     return "?";
    27 }
    28 #endif
    30 nsRDFConInstanceTestNode::nsRDFConInstanceTestNode(TestNode* aParent,
    31                                                    nsXULTemplateQueryProcessorRDF* aProcessor,
    32                                                    nsIAtom* aContainerVariable,
    33                                                    Test aContainer,
    34                                                    Test aEmpty)
    35     : nsRDFTestNode(aParent),
    36       mProcessor(aProcessor),
    37       mContainerVariable(aContainerVariable),
    38       mContainer(aContainer),
    39       mEmpty(aEmpty)
    40 {
    41 #ifdef PR_LOGGING
    42     if (PR_LOG_TEST(gXULTemplateLog, PR_LOG_DEBUG)) {
    43         nsAutoCString props;
    45         nsResourceSet& containmentProps = aProcessor->ContainmentProperties();
    46         nsResourceSet::ConstIterator last = containmentProps.Last();
    47         nsResourceSet::ConstIterator first = containmentProps.First();
    48         nsResourceSet::ConstIterator iter;
    50         for (iter = first; iter != last; ++iter) {
    51             if (iter != first)
    52                 props += " ";
    54             const char* str;
    55             iter->GetValueConst(&str);
    57             props += str;
    58         }
    60         nsAutoString cvar(NS_LITERAL_STRING("(none)"));
    61         if (mContainerVariable)
    62             mContainerVariable->ToString(cvar);
    64         PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
    65                ("nsRDFConInstanceTestNode[%p]: parent=%p member-props=(%s) container-var=%s container=%s empty=%s",
    66                 this,
    67                 aParent,
    68                 props.get(),
    69                 NS_ConvertUTF16toUTF8(cvar).get(),
    70                 TestToString(aContainer),
    71                 TestToString(aEmpty)));
    72     }
    73 #endif
    74 }
    76 nsresult
    77 nsRDFConInstanceTestNode::FilterInstantiations(InstantiationSet& aInstantiations,
    78                                                bool* aCantHandleYet) const
    79 {
    80     nsresult rv;
    82     if (aCantHandleYet)
    83         *aCantHandleYet = false;
    85     nsCOMPtr<nsIRDFContainerUtils> rdfc
    86         = do_GetService("@mozilla.org/rdf/container-utils;1");
    88     if (! rdfc)
    89         return NS_ERROR_FAILURE;
    91     nsIRDFDataSource* ds = mProcessor->GetDataSource();
    93     InstantiationSet::Iterator last = aInstantiations.Last();
    94     for (InstantiationSet::Iterator inst = aInstantiations.First(); inst != last; ++inst) {
    95         nsCOMPtr<nsIRDFNode> value;
    96         if (! inst->mAssignments.GetAssignmentFor(mContainerVariable, getter_AddRefs(value))) {
    97             NS_ERROR("can't do unbounded container testing");
    98             return NS_ERROR_UNEXPECTED;
    99         }
   101         nsCOMPtr<nsIRDFResource> valueres = do_QueryInterface(value);
   102         if (! valueres) {
   103             aInstantiations.Erase(inst--);
   104             continue;
   105         }
   107 #ifdef PR_LOGGING
   108         if (PR_LOG_TEST(gXULTemplateLog, PR_LOG_DEBUG)) {
   109             const char* container = "(unbound)";
   110             valueres->GetValueConst(&container);
   112             PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
   113                    ("nsRDFConInstanceTestNode[%p]::FilterInstantiations() container=[%s]",
   114                     this, container));
   115         }
   116 #endif
   118         nsCOMPtr<nsIRDFContainer> rdfcontainer;
   120         bool isRDFContainer;
   121         rv = rdfc->IsContainer(ds, valueres, &isRDFContainer);
   122         if (NS_FAILED(rv)) return rv;
   124         if (mEmpty != eDontCare || mContainer != eDontCare) {
   125             Test empty = eDontCare;
   126             Test container = eDontCare;
   128             if (isRDFContainer) {
   129                 // It's an RDF container. Use the container utilities
   130                 // to deduce what's in it.
   131                 container = eTrue;
   133                 // XXX should cache the factory
   134                 rdfcontainer = do_CreateInstance("@mozilla.org/rdf/container;1", &rv);
   135                 if (NS_FAILED(rv)) return rv;
   137                 rv = rdfcontainer->Init(ds, valueres);
   138                 if (NS_FAILED(rv)) return rv;
   140                 int32_t count;
   141                 rv = rdfcontainer->GetCount(&count);
   142                 if (NS_FAILED(rv)) return rv;
   144                 empty = (count == 0) ? eTrue : eFalse;
   145             } else {
   146                 empty = eTrue;
   147                 container = eFalse;
   149                 // First do the simple check of finding some outward
   150                 // arcs; there should be only a few containment arcs, so this can
   151                 // save us time from dealing with an iterator later on
   152                 nsResourceSet& containmentProps = mProcessor->ContainmentProperties();
   153                 for (nsResourceSet::ConstIterator property = containmentProps.First();
   154                      property != containmentProps.Last();
   155                      ++property) {
   156                     nsCOMPtr<nsIRDFNode> target;
   157                     rv = ds->GetTarget(valueres, *property, true, getter_AddRefs(target));
   158                     if (NS_FAILED(rv)) return rv;
   160                     if (target != nullptr) {
   161                         // bingo. we found one.
   162                         empty = eFalse;
   163                         container = eTrue;
   164                         break;
   165                     }
   166                 }
   168                 // if we still don't think its a container, but we
   169                 // want to know for sure whether it is or not, we need
   170                 // to check ArcLabelsOut for potential container arcs.
   171                 if (container == eFalse && mContainer != eDontCare) {
   172                     nsCOMPtr<nsISimpleEnumerator> arcsout;
   173                     rv = ds->ArcLabelsOut(valueres, getter_AddRefs(arcsout));
   174                     if (NS_FAILED(rv)) return rv;
   176                     while (1) {
   177                         bool hasmore;
   178                         rv = arcsout->HasMoreElements(&hasmore);
   179                         if (NS_FAILED(rv)) return rv;
   181                         if (! hasmore)
   182                             break;
   184                         nsCOMPtr<nsISupports> isupports;
   185                         rv = arcsout->GetNext(getter_AddRefs(isupports));
   186                         if (NS_FAILED(rv)) return rv;
   188                         nsCOMPtr<nsIRDFResource> property = do_QueryInterface(isupports);
   189                         NS_ASSERTION(property != nullptr, "not a property");
   190                         if (! property)
   191                             return NS_ERROR_UNEXPECTED;
   193                         if (mProcessor->ContainmentProperties().Contains(property)) {
   194                             container = eTrue;
   195                             break;
   196                         }
   197                     }
   198                 }
   199             }
   201             PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
   202                    ("    empty => %s",
   203                     (empty == mEmpty) ? "consistent" : "inconsistent"));
   205             PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
   206                    ("    container => %s",
   207                     (container == mContainer) ? "consistent" : "inconsistent"));
   209             if (((mEmpty == empty) && (mContainer == container)) ||
   210                 ((mEmpty == eDontCare) && (mContainer == container)) ||
   211                 ((mContainer == eDontCare) && (mEmpty == empty)))
   212             {
   213                 Element* element =
   214                     new nsRDFConInstanceTestNode::Element(valueres, container, empty);
   216                 if (! element)
   217                     return NS_ERROR_OUT_OF_MEMORY;
   219                 inst->AddSupportingElement(element);
   220             }
   221             else {
   222                 aInstantiations.Erase(inst--);
   223             }
   224         }
   225     }
   227     return NS_OK;
   228 }
   230 bool
   231 nsRDFConInstanceTestNode::CanPropagate(nsIRDFResource* aSource,
   232                                        nsIRDFResource* aProperty,
   233                                        nsIRDFNode* aTarget,
   234                                        Instantiation& aInitialBindings) const
   235 {
   236     nsresult rv;
   238     bool canpropagate = false;
   240     nsCOMPtr<nsIRDFContainerUtils> rdfc
   241         = do_GetService("@mozilla.org/rdf/container-utils;1");
   243     if (! rdfc)
   244         return false;
   246     // We can certainly propagate ordinal properties
   247     rv = rdfc->IsOrdinalProperty(aProperty, &canpropagate);
   248     if (NS_FAILED(rv)) return false;
   250     if (! canpropagate) {
   251         canpropagate = mProcessor->ContainmentProperties().Contains(aProperty);
   252     }
   254 #ifdef PR_LOGGING
   255     if (PR_LOG_TEST(gXULTemplateLog, PR_LOG_DEBUG)) {
   256         const char* source;
   257         aSource->GetValueConst(&source);
   259         const char* property;
   260         aProperty->GetValueConst(&property);
   262         nsAutoString target;
   263         nsXULContentUtils::GetTextForNode(aTarget, target);
   265         PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
   266                ("nsRDFConInstanceTestNode[%p]: CanPropagate([%s]==[%s]=>[%s]) => %s",
   267                 this, source, property, NS_ConvertUTF16toUTF8(target).get(),
   268                 canpropagate ? "true" : "false"));
   269     }
   270 #endif
   272     if (canpropagate) {
   273         aInitialBindings.AddAssignment(mContainerVariable, aSource);
   274         return true;
   275     }
   277     return false;
   278 }
   280 void
   281 nsRDFConInstanceTestNode::Retract(nsIRDFResource* aSource,
   282                                   nsIRDFResource* aProperty,
   283                                   nsIRDFNode* aTarget) const
   284 {
   285     // XXXwaterson oof. complicated. figure this out.
   286     if (0) {
   287         mProcessor->RetractElement(Element(aSource, mContainer, mEmpty));
   288     }
   289 }

mercurial