1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is Mozilla Communicator client code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
23 * Chris Waterson <waterson@netscape.com>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either of the GNU General Public License Version 2 or later (the "GPL"),
27 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 #include "nsRDFPropertyTestNode.h"
44 extern PRLogModuleInfo
* gXULTemplateLog
;
45 #include "nsIRDFLiteral.h"
46 #include "nsXULContentUtils.h"
49 nsRDFPropertyTestNode::nsRDFPropertyTestNode(TestNode
* aParent
,
50 nsXULTemplateQueryProcessorRDF
* aProcessor
,
51 nsIAtom
* aSourceVariable
,
52 nsIRDFResource
* aProperty
,
53 nsIAtom
* aTargetVariable
)
54 : nsRDFTestNode(aParent
),
55 mProcessor(aProcessor
),
56 mSourceVariable(aSourceVariable
),
59 mTargetVariable(aTargetVariable
),
63 if (PR_LOG_TEST(gXULTemplateLog
, PR_LOG_DEBUG
)) {
64 const char* prop
= "(null)";
66 aProperty
->GetValueConst(&prop
);
68 nsAutoString
svar(NS_LITERAL_STRING("(none)"));
70 mSourceVariable
->ToString(svar
);
72 nsAutoString
tvar(NS_LITERAL_STRING("(none)"));
74 mTargetVariable
->ToString(tvar
);
76 PR_LOG(gXULTemplateLog
, PR_LOG_DEBUG
,
77 ("nsRDFPropertyTestNode[%p]: parent=%p source=%s property=%s target=%s",
78 this, aParent
, NS_ConvertUTF16toUTF8(svar
).get(), prop
, NS_ConvertUTF16toUTF8(tvar
).get()));
84 nsRDFPropertyTestNode::nsRDFPropertyTestNode(TestNode
* aParent
,
85 nsXULTemplateQueryProcessorRDF
* aProcessor
,
86 nsIRDFResource
* aSource
,
87 nsIRDFResource
* aProperty
,
88 nsIAtom
* aTargetVariable
)
89 : nsRDFTestNode(aParent
),
90 mProcessor(aProcessor
),
94 mTargetVariable(aTargetVariable
),
98 if (PR_LOG_TEST(gXULTemplateLog
, PR_LOG_DEBUG
)) {
99 const char* source
= "(null)";
101 aSource
->GetValueConst(&source
);
103 const char* prop
= "(null)";
105 aProperty
->GetValueConst(&prop
);
107 nsAutoString
tvar(NS_LITERAL_STRING("(none)"));
109 mTargetVariable
->ToString(tvar
);
111 PR_LOG(gXULTemplateLog
, PR_LOG_DEBUG
,
112 ("nsRDFPropertyTestNode[%p]: parent=%p source=%s property=%s target=%s",
113 this, aParent
, source
, prop
, NS_ConvertUTF16toUTF8(tvar
).get()));
119 nsRDFPropertyTestNode::nsRDFPropertyTestNode(TestNode
* aParent
,
120 nsXULTemplateQueryProcessorRDF
* aProcessor
,
121 nsIAtom
* aSourceVariable
,
122 nsIRDFResource
* aProperty
,
124 : nsRDFTestNode(aParent
),
125 mProcessor(aProcessor
),
126 mSourceVariable(aSourceVariable
),
128 mProperty(aProperty
),
133 if (PR_LOG_TEST(gXULTemplateLog
, PR_LOG_DEBUG
)) {
134 nsAutoString
svar(NS_LITERAL_STRING("(none)"));
136 mSourceVariable
->ToString(svar
);
138 const char* prop
= "(null)";
140 aProperty
->GetValueConst(&prop
);
143 nsXULContentUtils::GetTextForNode(aTarget
, target
);
145 PR_LOG(gXULTemplateLog
, PR_LOG_DEBUG
,
146 ("nsRDFPropertyTestNode[%p]: parent=%p source=%s property=%s target=%s",
147 this, aParent
, NS_ConvertUTF16toUTF8(svar
).get(), prop
, NS_ConvertUTF16toUTF8(target
).get()));
154 nsRDFPropertyTestNode::FilterInstantiations(InstantiationSet
& aInstantiations
,
155 PRBool
* aCantHandleYet
) const
160 *aCantHandleYet
= PR_FALSE
;
162 nsIRDFDataSource
* ds
= mProcessor
->GetDataSource();
164 InstantiationSet::Iterator last
= aInstantiations
.Last();
165 for (InstantiationSet::Iterator inst
= aInstantiations
.First(); inst
!= last
; ++inst
) {
166 PRBool hasSourceBinding
;
167 nsCOMPtr
<nsIRDFResource
> sourceRes
;
170 hasSourceBinding
= PR_TRUE
;
174 nsCOMPtr
<nsIRDFNode
> sourceValue
;
175 hasSourceBinding
= inst
->mAssignments
.GetAssignmentFor(mSourceVariable
,
176 getter_AddRefs(sourceValue
));
177 sourceRes
= do_QueryInterface(sourceValue
);
180 PRBool hasTargetBinding
;
181 nsCOMPtr
<nsIRDFNode
> targetValue
;
184 hasTargetBinding
= PR_TRUE
;
185 targetValue
= mTarget
;
188 hasTargetBinding
= inst
->mAssignments
.GetAssignmentFor(mTargetVariable
,
189 getter_AddRefs(targetValue
));
193 if (PR_LOG_TEST(gXULTemplateLog
, PR_LOG_DEBUG
)) {
194 const char* source
= "(unbound)";
195 if (hasSourceBinding
)
196 sourceRes
->GetValueConst(&source
);
198 nsAutoString
target(NS_LITERAL_STRING("(unbound)"));
199 if (hasTargetBinding
)
200 nsXULContentUtils::GetTextForNode(targetValue
, target
);
202 PR_LOG(gXULTemplateLog
, PR_LOG_DEBUG
,
203 ("nsRDFPropertyTestNode[%p]: FilterInstantiations() source=[%s] target=[%s]",
204 this, source
, NS_ConvertUTF16toUTF8(target
).get()));
208 if (hasSourceBinding
&& hasTargetBinding
) {
209 // it's a consistency check. see if we have a assignment that is consistent
211 rv
= ds
->HasAssertion(sourceRes
, mProperty
, targetValue
,
212 PR_TRUE
, &hasAssertion
);
213 if (NS_FAILED(rv
)) return rv
;
216 PR_LOG(gXULTemplateLog
, PR_LOG_DEBUG
,
217 (" consistency check => %s", hasAssertion
? "passed" : "failed"));
223 nsRDFPropertyTestNode::Element::Create(sourceRes
,
228 return NS_ERROR_OUT_OF_MEMORY
;
230 inst
->AddSupportingElement(element
);
233 // it's inconsistent. remove it.
234 aInstantiations
.Erase(inst
--);
237 else if ((hasSourceBinding
&& ! hasTargetBinding
) ||
238 (! hasSourceBinding
&& hasTargetBinding
)) {
239 // it's an open ended query on the source or
240 // target. figure out what matches and add as a
242 nsCOMPtr
<nsISimpleEnumerator
> results
;
243 if (hasSourceBinding
) {
244 rv
= ds
->GetTargets(sourceRes
,
247 getter_AddRefs(results
));
250 rv
= ds
->GetSources(mProperty
,
253 getter_AddRefs(results
));
254 if (NS_FAILED(rv
)) return rv
;
259 rv
= results
->HasMoreElements(&hasMore
);
260 if (NS_FAILED(rv
)) return rv
;
265 nsCOMPtr
<nsISupports
> isupports
;
266 rv
= results
->GetNext(getter_AddRefs(isupports
));
267 if (NS_FAILED(rv
)) return rv
;
270 nsCOMPtr
<nsIRDFNode
> value
;
272 if (hasSourceBinding
) {
273 variable
= mTargetVariable
;
275 value
= do_QueryInterface(isupports
);
276 NS_ASSERTION(value
!= nsnull
, "target is not an nsIRDFNode");
279 if (PR_LOG_TEST(gXULTemplateLog
, PR_LOG_DEBUG
)) {
280 nsAutoString
s(NS_LITERAL_STRING("(none found)"));
282 nsXULContentUtils::GetTextForNode(value
, s
);
284 PR_LOG(gXULTemplateLog
, PR_LOG_DEBUG
,
285 (" target => %s", NS_ConvertUTF16toUTF8(s
).get()));
289 if (! value
) continue;
294 variable
= mSourceVariable
;
296 nsCOMPtr
<nsIRDFResource
> source
= do_QueryInterface(isupports
);
297 NS_ASSERTION(source
!= nsnull
, "source is not an nsIRDFResource");
300 if (PR_LOG_TEST(gXULTemplateLog
, PR_LOG_DEBUG
)) {
301 const char* s
= "(none found)";
303 source
->GetValueConst(&s
);
305 PR_LOG(gXULTemplateLog
, PR_LOG_DEBUG
,
306 (" source => %s", s
));
310 if (! source
) continue;
312 value
= sourceRes
= source
;
315 // Copy the original instantiation, and add it to the
316 // instantiation set with the new assignment that we've
317 // introduced. Ownership will be transferred to the
318 Instantiation newinst
= *inst
;
319 newinst
.AddAssignment(variable
, value
);
322 nsRDFPropertyTestNode::Element::Create(sourceRes
,
327 return NS_ERROR_OUT_OF_MEMORY
;
329 newinst
.AddSupportingElement(element
);
331 aInstantiations
.Insert(inst
, newinst
);
334 // finally, remove the "under specified" instantiation.
335 aInstantiations
.Erase(inst
--);
338 if (!aCantHandleYet
) {
339 // Neither source nor target assignment!
340 return NS_ERROR_UNEXPECTED
;
343 *aCantHandleYet
= PR_TRUE
;
352 nsRDFPropertyTestNode::CanPropagate(nsIRDFResource
* aSource
,
353 nsIRDFResource
* aProperty
,
355 Instantiation
& aInitialBindings
) const
359 if ((mProperty
.get() != aProperty
) ||
360 (mSource
&& mSource
.get() != aSource
) ||
361 (mTarget
&& mTarget
.get() != aTarget
)) {
366 aInitialBindings
.AddAssignment(mSourceVariable
, aSource
);
369 aInitialBindings
.AddAssignment(mTargetVariable
, aTarget
);
375 if (PR_LOG_TEST(gXULTemplateLog
, PR_LOG_DEBUG
)) {
377 aSource
->GetValueConst(&source
);
379 const char* property
;
380 aProperty
->GetValueConst(&property
);
383 nsXULContentUtils::GetTextForNode(aTarget
, target
);
385 PR_LOG(gXULTemplateLog
, PR_LOG_DEBUG
,
386 ("nsRDFPropertyTestNode[%p]: CanPropagate([%s]==[%s]=>[%s]) => %s",
387 this, source
, property
, NS_ConvertUTF16toUTF8(target
).get(),
388 result
? "true" : "false"));
396 nsRDFPropertyTestNode::Retract(nsIRDFResource
* aSource
,
397 nsIRDFResource
* aProperty
,
398 nsIRDFNode
* aTarget
) const
400 if (aProperty
== mProperty
.get()) {
402 if (PR_LOG_TEST(gXULTemplateLog
, PR_LOG_DEBUG
)) {
404 aSource
->GetValueConst(&source
);
406 const char* property
;
407 aProperty
->GetValueConst(&property
);
410 nsXULContentUtils::GetTextForNode(aTarget
, target
);
412 PR_LOG(gXULTemplateLog
, PR_LOG_DEBUG
,
413 ("nsRDFPropertyTestNode[%p]: Retract([%s]==[%s]=>[%s])",
414 this, source
, property
, NS_ConvertUTF16toUTF8(target
).get()));
418 mProcessor
->RetractElement(Element(aSource
, aProperty
, aTarget
));