Back to index

lightning-sunbird  0.9+nobinonly
nsAbDirectoryQuery.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Sun Microsystems, Inc.
00019  * Portions created by the Initial Developer are Copyright (C) 2001
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Created by: Paul Sandoz   <paul.sandoz@sun.com>
00024  *   Dan Mosedale <dan.mosedale@oracle.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include "nsAbDirectoryQuery.h"
00041 #include "nsAbDirectoryQueryProxy.h"
00042 #include "nsAbUtils.h"
00043 #include "nsAbBooleanExpression.h"
00044 
00045 #include "nsIRDFResource.h"
00046 
00047 #include "nsXPIDLString.h"
00048 #include "nsReadableUtils.h"
00049 #include "nsUnicharUtils.h"
00050 
00051 
00052 NS_IMPL_THREADSAFE_ISUPPORTS1(nsAbDirectoryQuerySimpleBooleanExpression, nsIAbBooleanExpression)
00053 
00054 nsAbDirectoryQuerySimpleBooleanExpression::nsAbDirectoryQuerySimpleBooleanExpression() :
00055     mOperation (nsIAbBooleanOperationTypes::AND)
00056 {
00057 }
00058 
00059 nsAbDirectoryQuerySimpleBooleanExpression::~nsAbDirectoryQuerySimpleBooleanExpression()
00060 {
00061 }
00062 
00063 /* attribute nsAbBooleanOperationType operation; */
00064 NS_IMETHODIMP nsAbDirectoryQuerySimpleBooleanExpression::GetOperation(nsAbBooleanOperationType *aOperation)
00065 {
00066     if (!aOperation)
00067         return NS_ERROR_NULL_POINTER;
00068 
00069     *aOperation = mOperation;
00070 
00071     return NS_OK;
00072 }
00073 NS_IMETHODIMP nsAbDirectoryQuerySimpleBooleanExpression::SetOperation(nsAbBooleanOperationType aOperation)
00074 {
00075     if (aOperation != nsIAbBooleanOperationTypes::AND &&
00076         aOperation != nsIAbBooleanOperationTypes::OR)
00077         return NS_ERROR_FAILURE;
00078 
00079     mOperation = aOperation;
00080 
00081     return NS_OK;
00082 }
00083 
00084 /* attribute nsISupportsArray expressions; */
00085 NS_IMETHODIMP nsAbDirectoryQuerySimpleBooleanExpression::GetExpressions(nsISupportsArray** aExpressions)
00086 {
00087     if (!aExpressions)
00088         return NS_ERROR_NULL_POINTER;
00089 
00090     if (!mExpressions)
00091         NS_NewISupportsArray(getter_AddRefs(mExpressions));
00092 
00093     NS_IF_ADDREF(*aExpressions = mExpressions);
00094     return NS_OK;
00095 }
00096 
00097 NS_IMETHODIMP nsAbDirectoryQuerySimpleBooleanExpression::SetExpressions(nsISupportsArray* aExpressions)
00098 {
00099     if (!aExpressions)
00100         return NS_ERROR_NULL_POINTER;
00101 
00102     nsresult rv;
00103     PRUint32 count;
00104     rv = aExpressions->Count (&count);
00105     NS_ENSURE_SUCCESS(rv, rv);
00106 
00107     for (PRUint32 i = 0; i < count; i++)
00108     {
00109         nsCOMPtr<nsISupports> item;
00110         rv = aExpressions->GetElementAt (i, getter_AddRefs (item));
00111         NS_ENSURE_SUCCESS(rv, rv);
00112 
00113         nsCOMPtr<nsIAbBooleanConditionString> queryExpression (do_QueryInterface (item, &rv));
00114         NS_ENSURE_SUCCESS(rv, rv);
00115     }
00116 
00117     mExpressions = aExpressions;
00118 
00119     return NS_OK;
00120 }
00121 
00122 /* void asetExpressions (in unsigned long aExpressionsSize, [array, size_is (aExpressionsSize)] in nsISupports aExpressionsArray); */
00123 NS_IMETHODIMP nsAbDirectoryQuerySimpleBooleanExpression::AsetExpressions(PRUint32 aExpressionsSize, nsISupports **aExpressionsArray)
00124 {
00125     return NS_ERROR_NOT_IMPLEMENTED;
00126 }
00127 
00128 /* void agetExpressions (out unsigned long aExpressionsSize, [array, size_is (aExpressionsSize), retval] out nsISupports aExpressionsArray); */
00129 NS_IMETHODIMP nsAbDirectoryQuerySimpleBooleanExpression::AgetExpressions(PRUint32 *aExpressionsSize, nsISupports ***aExpressionsArray)
00130 {
00131     return NS_ERROR_NOT_IMPLEMENTED;
00132 }
00133 
00134 NS_IMPL_THREADSAFE_ISUPPORTS1(nsAbDirectoryQueryArguments, nsIAbDirectoryQueryArguments)
00135 
00136 nsAbDirectoryQueryArguments::nsAbDirectoryQueryArguments() :
00137     mQuerySubDirectories(PR_TRUE)
00138 {
00139 }
00140 
00141 nsAbDirectoryQueryArguments::~nsAbDirectoryQueryArguments()
00142 {
00143 }
00144 
00145 /* attribute nsISupportsArray matchItems; */
00146 NS_IMETHODIMP nsAbDirectoryQueryArguments::GetExpression(nsISupports** aExpression)
00147 {
00148     if (!aExpression)
00149         return NS_ERROR_NULL_POINTER;
00150 
00151     NS_IF_ADDREF(*aExpression = mExpression);
00152     return NS_OK;
00153 }
00154 
00155 NS_IMETHODIMP nsAbDirectoryQueryArguments::SetExpression(nsISupports* aExpression)
00156 {
00157     mExpression = aExpression;
00158     return NS_OK;
00159 }
00160 
00161 /* attribute boolean querySubDirectories; */
00162 NS_IMETHODIMP nsAbDirectoryQueryArguments::GetQuerySubDirectories(PRBool* aQuerySubDirectories)
00163 {
00164     NS_ENSURE_ARG_POINTER(aQuerySubDirectories);
00165     *aQuerySubDirectories = mQuerySubDirectories;
00166     return NS_OK;
00167 }
00168 
00169 NS_IMETHODIMP nsAbDirectoryQueryArguments::SetQuerySubDirectories(PRBool aQuerySubDirectories)
00170 {
00171     mQuerySubDirectories = aQuerySubDirectories;
00172     return NS_OK;
00173 }
00174 
00175 /* void setReturnProperties (in unsigned long returnPropertiesSize,
00176  *     [array, size_is (returnPropertiesSize)] in string returnPropertiesArray); */
00177 NS_IMETHODIMP nsAbDirectoryQueryArguments::SetReturnProperties(PRUint32 returnPropertiesSize,
00178         const char** returnPropertiesArray)
00179 {
00180     NS_ENSURE_ARG_POINTER(returnPropertiesArray);
00181 
00182     mReturnProperties.Clear();
00183 
00184     for (PRUint32 i = 0; i < returnPropertiesSize; i++)
00185         mReturnProperties.AppendCString(nsDependentCString(returnPropertiesArray[i]));
00186 
00187     return NS_OK;
00188 }
00189 
00190 /* void getReturnProperties (out unsigned long returnPropertiesSize,
00191  *     [array, size_is (returnPropertiesSize), retval] out string returnPropertiesArray); */
00192 NS_IMETHODIMP nsAbDirectoryQueryArguments::GetReturnProperties(PRUint32* returnPropertiesSize,
00193         char*** returnPropertiesArray)
00194 {
00195     NS_ENSURE_ARG_POINTER(returnPropertiesSize);
00196     NS_ENSURE_ARG_POINTER(returnPropertiesArray);
00197 
00198     PRUint32 size = mReturnProperties.Count();
00199     *returnPropertiesSize = size;
00200     *returnPropertiesArray = NS_STATIC_CAST(char**, nsMemory::Alloc (sizeof (char* ) * size));
00201     if (!(*returnPropertiesArray))
00202         return NS_ERROR_OUT_OF_MEMORY;
00203 
00204     for (PRUint32 i = 0; i < size; i++)
00205         (*returnPropertiesArray)[i] = ToNewCString(*mReturnProperties[i]);
00206 
00207     return NS_OK;
00208 }
00209 
00210 NS_IMETHODIMP nsAbDirectoryQueryArguments::GetTypeSpecificArg(nsISupports** aArg)
00211 {
00212     NS_ENSURE_ARG_POINTER(aArg);
00213 
00214     NS_IF_ADDREF(*aArg = mTypeSpecificArg);
00215     return NS_OK;
00216 }
00217 
00218 NS_IMETHODIMP nsAbDirectoryQueryArguments::SetTypeSpecificArg(nsISupports* aArg)
00219 {
00220     mTypeSpecificArg = aArg;
00221     return NS_OK;
00222 }
00223 
00224 
00225 NS_IMPL_THREADSAFE_ISUPPORTS1(nsAbDirectoryQueryPropertyValue, nsIAbDirectoryQueryPropertyValue)
00226 
00227 nsAbDirectoryQueryPropertyValue::nsAbDirectoryQueryPropertyValue()
00228 {
00229 }
00230 
00231 nsAbDirectoryQueryPropertyValue::nsAbDirectoryQueryPropertyValue(const char* aName,
00232       const PRUnichar* aValue)
00233 {
00234     mName = aName;
00235     mValue = aValue;
00236 }
00237 
00238 nsAbDirectoryQueryPropertyValue::nsAbDirectoryQueryPropertyValue(const char* aName,
00239       nsISupports* aValueISupports)
00240 {
00241     mName = aName;
00242     mValueISupports = aValueISupports;
00243 }
00244 
00245 nsAbDirectoryQueryPropertyValue::~nsAbDirectoryQueryPropertyValue()
00246 {
00247 }
00248 
00249 /* read only attribute string name; */
00250 NS_IMETHODIMP nsAbDirectoryQueryPropertyValue::GetName(char*  *aName)
00251 {
00252     *aName = mName.IsEmpty() ? 0 : ToNewCString(mName);
00253 
00254     return NS_OK;
00255 }
00256 
00257 /* read only attribute wstring value; */
00258 NS_IMETHODIMP nsAbDirectoryQueryPropertyValue::GetValue(PRUnichar*  *aValue)
00259 {
00260     *aValue = ToNewUnicode(mValue);
00261     if (!(*aValue)) 
00262         return NS_ERROR_OUT_OF_MEMORY;
00263     else
00264         return NS_OK;
00265 }
00266 
00267 /* readonly attribute nsISupports valueISupports; */
00268 NS_IMETHODIMP nsAbDirectoryQueryPropertyValue::GetValueISupports(nsISupports*  *aValueISupports)
00269 {
00270     if (!mValueISupports)
00271         return NS_ERROR_NULL_POINTER;
00272 
00273     NS_IF_ADDREF(*aValueISupports = mValueISupports);
00274     return NS_OK;
00275 }
00276 
00277 NS_IMPL_THREADSAFE_ISUPPORTS1(nsAbDirectoryQueryResult, nsIAbDirectoryQueryResult)
00278 
00279 nsAbDirectoryQueryResult::nsAbDirectoryQueryResult() :
00280     mContextID (-1),
00281     mType (queryResultError)
00282 {
00283 }
00284 
00285 nsAbDirectoryQueryResult::nsAbDirectoryQueryResult(PRInt32 aContextID,
00286       nsIAbDirectoryQueryArguments* aContextArgs,
00287       PRInt32 aType,
00288       nsCOMPtr<nsISupportsArray> aResult)
00289 {
00290     mContextID = aContextID;
00291     mContextArgs = aContextArgs;
00292     mType = aType;
00293     mResult = aResult;
00294 }
00295 
00296 nsAbDirectoryQueryResult::~nsAbDirectoryQueryResult()
00297 {
00298 }
00299 
00300 /* readonly attribute long contextID; */
00301 NS_IMETHODIMP nsAbDirectoryQueryResult::GetContextID(PRInt32 *aContextID)
00302 {
00303     *aContextID = mContextID;
00304     
00305     return NS_OK;
00306 }
00307 
00308 /* readonly attribute nsIAbDirectoryQueryArguments contextArgs; */
00309 NS_IMETHODIMP nsAbDirectoryQueryResult::GetContextArgs(nsIAbDirectoryQueryArguments*  *aContextArgs)
00310 {
00311     if (!mContextArgs)
00312         return NS_ERROR_NULL_POINTER;
00313 
00314     NS_IF_ADDREF(*aContextArgs = mContextArgs);
00315     return NS_OK;
00316 }
00317 
00318 /* readonly attribute long type; */
00319 NS_IMETHODIMP nsAbDirectoryQueryResult::GetType(PRInt32 *aType)
00320 {
00321     *aType = mType;
00322 
00323     return NS_OK;
00324 }
00325 
00326 /* readonly attribute nsISupportsArray result; */
00327 NS_IMETHODIMP nsAbDirectoryQueryResult::GetResult(nsISupportsArray*  *aResult)
00328 {
00329     if (!mResult)
00330         return NS_ERROR_NULL_POINTER;
00331 
00332     NS_IF_ADDREF(*aResult = mResult);
00333     return NS_OK;
00334 }
00335 
00336 /* void agetResult (out unsigned long aResultSize, [array, size_is (aResultSize), retval] out nsISupports aResultArray); */
00337 NS_IMETHODIMP nsAbDirectoryQueryResult::AgetResult(PRUint32 *aResultSize, nsISupports* **aResultArray)
00338 {
00339     return NS_ERROR_NOT_IMPLEMENTED;
00340 }
00341 
00342 
00343 
00344 
00345 
00346 
00347 /* Implementation file */
00348 NS_IMPL_ISUPPORTS1(nsAbDirectoryQuery, nsIAbDirectoryQuery)
00349 
00350 nsAbDirectoryQuery::nsAbDirectoryQuery(nsIAbDirectory* aDirectory)
00351 {
00352   mDirectory = aDirectory;
00353 }
00354 
00355 nsAbDirectoryQuery::~nsAbDirectoryQuery()
00356 {
00357 }
00358 
00359 /* long doQuery (in nsIAbDirectoryQueryArguments arguments, in nsIAbDirectoryQueryResultListener listener, in long resultLimit, in long timeOut); */
00360 NS_IMETHODIMP nsAbDirectoryQuery::DoQuery(nsIAbDirectoryQueryArguments* arguments, nsIAbDirectoryQueryResultListener* listener, PRInt32 resultLimit, PRInt32 timeOut, PRInt32* _retval)
00361 {
00362     nsresult rv;
00363     rv = query (mDirectory, arguments, listener, &resultLimit);
00364     if (NS_FAILED(rv))
00365         rv = queryError (arguments, listener);
00366     else
00367         rv = queryFinished (arguments, listener);
00368 
00369     *_retval = 0;
00370     return rv;
00371 }
00372 
00373 /* void stopQuery (in long contextID); */
00374 NS_IMETHODIMP nsAbDirectoryQuery::StopQuery(PRInt32 contextID)
00375 {
00376     return NS_OK;
00377 }
00378 
00379 
00380 nsresult nsAbDirectoryQuery::query (nsIAbDirectory* directory,
00381     nsIAbDirectoryQueryArguments* arguments,
00382     nsIAbDirectoryQueryResultListener* listener,
00383     PRInt32* resultLimit)
00384 {
00385     if (*resultLimit == 0)
00386         return NS_OK;
00387 
00388     nsresult rv = queryCards (directory, arguments, listener, resultLimit);
00389     NS_ENSURE_SUCCESS(rv, rv);
00390 
00391     PRBool doSubDirectories;
00392     arguments->GetQuerySubDirectories (&doSubDirectories);
00393     if (doSubDirectories && *resultLimit != 0) {
00394         rv = queryChildren(directory, arguments, listener, resultLimit);
00395         NS_ENSURE_SUCCESS(rv, rv);
00396     }
00397 
00398     return rv;
00399 }
00400 
00401 nsresult nsAbDirectoryQuery::queryChildren (nsIAbDirectory* directory,
00402     nsIAbDirectoryQueryArguments* arguments,
00403     nsIAbDirectoryQueryResultListener* listener,
00404     PRInt32* resultLimit)
00405 {
00406     nsresult rv = NS_OK;
00407 
00408     nsCOMPtr<nsISimpleEnumerator> subDirectories;
00409     rv = directory->GetChildNodes(getter_AddRefs(subDirectories));
00410     NS_ENSURE_SUCCESS(rv, rv);
00411 
00412     PRBool hasMore;
00413     while (NS_SUCCEEDED(rv = subDirectories->HasMoreElements(&hasMore)) && hasMore)
00414     {
00415         nsCOMPtr<nsISupports> item;
00416         rv = subDirectories->GetNext (getter_AddRefs (item));
00417         NS_ENSURE_SUCCESS(rv, rv);
00418 
00419         nsCOMPtr<nsIAbDirectory> subDirectory(do_QueryInterface(item, &rv));
00420         NS_ENSURE_SUCCESS(rv, rv);
00421         
00422         rv = query (subDirectory, arguments, listener, resultLimit);
00423         NS_ENSURE_SUCCESS(rv, rv);
00424 
00425     }
00426     return NS_OK;
00427 }
00428 
00429 nsresult nsAbDirectoryQuery::queryCards (nsIAbDirectory* directory,
00430     nsIAbDirectoryQueryArguments* arguments,
00431     nsIAbDirectoryQueryResultListener* listener,
00432     PRInt32* resultLimit)
00433 {
00434     nsresult rv = NS_OK;
00435 
00436     nsCOMPtr<nsIEnumerator> cards;
00437     rv = directory->GetChildCards(getter_AddRefs(cards));
00438     if (NS_FAILED(rv))
00439     {
00440         if (rv != NS_ERROR_NOT_IMPLEMENTED)
00441             NS_ENSURE_SUCCESS(rv, rv);
00442         else
00443             return NS_OK;
00444     }
00445 
00446     if (!cards)
00447         return NS_OK;
00448 
00449     rv = cards->First();
00450     if (NS_FAILED(rv))
00451         return NS_OK;
00452 
00453     do
00454     {
00455         nsCOMPtr<nsISupports> item;
00456         rv = cards->CurrentItem(getter_AddRefs(item));
00457         NS_ENSURE_SUCCESS(rv, rv);
00458 
00459         nsCOMPtr<nsIAbCard> card(do_QueryInterface(item, &rv));
00460         NS_ENSURE_SUCCESS(rv, rv);
00461         
00462         rv = matchCard (card, arguments, listener, resultLimit);
00463         NS_ENSURE_SUCCESS(rv, rv);
00464 
00465         if (*resultLimit == 0)
00466             return NS_OK;
00467 
00468         rv = cards->Next ();
00469     }
00470     while (rv == NS_OK);
00471 
00472     return NS_OK;
00473 }
00474 
00475 nsresult nsAbDirectoryQuery::matchCard (nsIAbCard* card,
00476     nsIAbDirectoryQueryArguments* arguments,
00477     nsIAbDirectoryQueryResultListener* listener,
00478     PRInt32* resultLimit)
00479 {
00480     nsCOMPtr<nsISupports> supportsExpression;
00481     nsresult rv = arguments->GetExpression (getter_AddRefs (supportsExpression));
00482     NS_ENSURE_SUCCESS(rv, rv);
00483 
00484     nsCOMPtr<nsIAbBooleanExpression> expression(do_QueryInterface(supportsExpression, &rv));
00485     NS_ENSURE_SUCCESS(rv, rv);
00486 
00487     PRBool matchFound = PR_FALSE;
00488     rv = matchCardExpression (card, expression, &matchFound);
00489     NS_ENSURE_SUCCESS(rv, rv);
00490 
00491     if (matchFound)
00492     {
00493         (*resultLimit)--;
00494         rv = queryMatch (card, arguments, listener);
00495         NS_ENSURE_SUCCESS(rv, rv);
00496     }
00497 
00498     return rv;
00499 }
00500 
00501 nsresult nsAbDirectoryQuery::matchCardExpression (nsIAbCard* card,
00502     nsIAbBooleanExpression* expression,
00503     PRBool* result)
00504 {
00505     nsAbBooleanOperationType operation;
00506     nsresult rv = expression->GetOperation (&operation);
00507     NS_ENSURE_SUCCESS(rv, rv);
00508 
00509     nsCOMPtr<nsISupportsArray> childExpressions;
00510     rv = expression->GetExpressions (getter_AddRefs (childExpressions));
00511     NS_ENSURE_SUCCESS(rv, rv);
00512     
00513     PRUint32 count;
00514     rv = childExpressions->Count (&count);
00515     NS_ENSURE_SUCCESS(rv, rv);
00516 
00517     if (operation == nsIAbBooleanOperationTypes::NOT &&
00518         count > 1)
00519         return NS_ERROR_FAILURE;
00520 
00521     PRBool value = *result = PR_FALSE;
00522     for (PRUint32 i = 0; i < count; i++)
00523     {
00524         nsCOMPtr<nsISupports> item;
00525         rv = childExpressions->GetElementAt (i, getter_AddRefs (item));
00526         NS_ENSURE_SUCCESS(rv, rv);
00527 
00528         nsCOMPtr<nsIAbBooleanConditionString>
00529             childCondition(do_QueryInterface(item, &rv));
00530         if (NS_SUCCEEDED(rv))
00531         {
00532             rv = matchCardCondition (card, childCondition, &value);
00533             NS_ENSURE_SUCCESS(rv, rv);
00534         }
00535         else
00536         {
00537             nsCOMPtr<nsIAbBooleanExpression>
00538                 childExpression(do_QueryInterface(item, &rv));
00539             if (NS_SUCCEEDED(rv))
00540             {
00541                 rv = matchCardExpression (card, childExpression, &value);
00542                 NS_ENSURE_SUCCESS(rv, rv);
00543             }
00544             else
00545                 return NS_ERROR_FAILURE;
00546         }
00547         if (operation == nsIAbBooleanOperationTypes::OR && value)
00548             break;
00549         else if (operation == nsIAbBooleanOperationTypes::AND && !value)
00550             break;
00551         else if (operation == nsIAbBooleanOperationTypes::NOT)
00552             value = !value;
00553     }
00554     *result = value;
00555 
00556     return NS_OK;
00557 }
00558 
00559 nsresult nsAbDirectoryQuery::matchCardCondition (nsIAbCard* card,
00560     nsIAbBooleanConditionString* condition,
00561     PRBool* matchFound)
00562 {
00563     nsAbBooleanConditionType conditionType;
00564     nsresult rv = condition->GetCondition (&conditionType);
00565     NS_ENSURE_SUCCESS(rv, rv);
00566 
00567     nsXPIDLCString name;
00568     rv = condition->GetName (getter_Copies (name));
00569     NS_ENSURE_SUCCESS(rv, rv);
00570 
00571     if (name.Equals ("card:nsIAbCard"))
00572     {
00573       *matchFound = (conditionType == nsIAbBooleanConditionTypes::Exists);
00574       return NS_OK;
00575     }
00576 
00577     nsXPIDLString value;
00578     rv = card->GetCardValue (name.get (), getter_Copies (value));
00579     NS_ENSURE_SUCCESS(rv, rv);
00580 
00581     if (value.IsEmpty())
00582     {
00583       *matchFound = (conditionType == nsIAbBooleanConditionTypes::DoesNotExist) ?
00584           PR_TRUE : PR_FALSE;
00585       return NS_OK;
00586     }
00587 
00588     nsXPIDLString matchValue;
00589     rv = condition->GetValue (getter_Copies (matchValue));
00590     NS_ENSURE_SUCCESS(rv, rv);
00591 
00592     /* TODO
00593      * What about allowing choice between case insensitive
00594      * and case sensitive comparisons?
00595      *
00596      */
00597     switch (conditionType)
00598     {
00599         case nsIAbBooleanConditionTypes::Exists:
00600             *matchFound = PR_TRUE;
00601             break;
00602         case nsIAbBooleanConditionTypes::Contains:
00603             *matchFound = FindInReadable(matchValue, value, nsCaseInsensitiveStringComparator());
00604             break;
00605         case nsIAbBooleanConditionTypes::DoesNotContain:
00606             *matchFound = !FindInReadable(matchValue, value, nsCaseInsensitiveStringComparator());
00607             break;
00608         case nsIAbBooleanConditionTypes::Is:
00609             *matchFound = value.Equals(matchValue, nsCaseInsensitiveStringComparator());
00610             break;
00611         case nsIAbBooleanConditionTypes::IsNot:
00612             *matchFound = !value.Equals(matchValue, nsCaseInsensitiveStringComparator());
00613             break;
00614         case nsIAbBooleanConditionTypes::BeginsWith:
00615             *matchFound = StringBeginsWith(value, matchValue, nsCaseInsensitiveStringComparator());
00616             break;
00617         case nsIAbBooleanConditionTypes::LessThan:
00618             *matchFound = Compare(value, matchValue, nsCaseInsensitiveStringComparator()) < 0;
00619             break;
00620         case nsIAbBooleanConditionTypes::GreaterThan:
00621             *matchFound = Compare(value, matchValue, nsCaseInsensitiveStringComparator()) > 0;
00622             break;
00623         case nsIAbBooleanConditionTypes::EndsWith:
00624             *matchFound = StringEndsWith(value, matchValue, nsCaseInsensitiveStringComparator());
00625             break;
00626         case nsIAbBooleanConditionTypes::SoundsLike:
00627         case nsIAbBooleanConditionTypes::RegExp:
00628             *matchFound = PR_FALSE;
00629             break;
00630         default:
00631             *matchFound = PR_FALSE;
00632     }
00633 
00634     return rv;
00635 }
00636 
00637 nsresult nsAbDirectoryQuery::queryMatch (nsIAbCard* card,
00638     nsIAbDirectoryQueryArguments* arguments,
00639     nsIAbDirectoryQueryResultListener* listener)
00640 {
00641     nsresult rv;
00642     nsCOMPtr<nsISupportsArray> propertyValues;
00643 
00644     CharPtrArrayGuard properties;
00645     rv = arguments->GetReturnProperties (properties.GetSizeAddr(), properties.GetArrayAddr());
00646     NS_ENSURE_SUCCESS(rv, rv);
00647 
00648     nsCAutoString n;
00649     for (PRUint32 i = 0; i < properties.GetSize(); i++)
00650     {
00651         n.Assign (properties[i]);
00652 
00653         nsAbDirectoryQueryPropertyValue* _propertyValue = 0;
00654         if (n.Equals("card:nsIAbCard"))
00655         {
00656             nsCOMPtr<nsISupports> supports(do_QueryInterface(card, &rv));
00657             NS_ENSURE_SUCCESS(rv, rv);
00658 
00659             _propertyValue = new nsAbDirectoryQueryPropertyValue(n.get (), supports);
00660             if (!_propertyValue)
00661                 return NS_ERROR_OUT_OF_MEMORY;
00662         }
00663         else
00664         {
00665             nsXPIDLString value;
00666             rv = card->GetCardValue (n.get (), getter_Copies (value));
00667             NS_ENSURE_SUCCESS(rv, rv);
00668 
00669             if (!value.get () || value.Length () == 0)
00670                 continue;
00671 
00672             _propertyValue = new nsAbDirectoryQueryPropertyValue(n.get (), value.get ());
00673             if (!_propertyValue)
00674                 return NS_ERROR_OUT_OF_MEMORY;
00675         }
00676 
00677         if (_propertyValue)
00678         {
00679             nsCOMPtr<nsIAbDirectoryQueryPropertyValue> propertyValue;
00680             propertyValue = _propertyValue;
00681 
00682             if (!propertyValues)
00683             {
00684                 NS_NewISupportsArray(getter_AddRefs(propertyValues));
00685             }
00686 
00687             nsCOMPtr<nsISupports> supports(do_QueryInterface(propertyValue, &rv));
00688             NS_ENSURE_SUCCESS(rv, rv);
00689 
00690             propertyValues->AppendElement (supports);
00691         }
00692     }
00693 
00694     
00695     if (!propertyValues)
00696         return NS_OK;
00697 
00698     nsCOMPtr<nsIAbDirectoryQueryResult> queryResult;
00699     nsAbDirectoryQueryResult* _queryResult = new nsAbDirectoryQueryResult (0,
00700         arguments,
00701         nsIAbDirectoryQueryResult::queryResultMatch,
00702         propertyValues);
00703     if (!_queryResult)
00704         return NS_ERROR_OUT_OF_MEMORY;
00705     queryResult = _queryResult;
00706 
00707     return listener->OnQueryItem (queryResult);
00708 }
00709 
00710 nsresult nsAbDirectoryQuery::queryFinished (nsIAbDirectoryQueryArguments* arguments,
00711     nsIAbDirectoryQueryResultListener* listener)
00712 {
00713     nsCOMPtr<nsIAbDirectoryQueryResult> queryResult;
00714     nsAbDirectoryQueryResult* _queryResult = new nsAbDirectoryQueryResult (0,
00715         arguments,
00716         nsIAbDirectoryQueryResult::queryResultComplete,
00717         0);
00718     if (!_queryResult)
00719         return NS_ERROR_OUT_OF_MEMORY;
00720     queryResult = _queryResult;
00721 
00722     return listener->OnQueryItem (queryResult);
00723 }
00724 
00725 nsresult nsAbDirectoryQuery::queryError (nsIAbDirectoryQueryArguments* arguments,
00726     nsIAbDirectoryQueryResultListener* listener)
00727 {
00728     nsCOMPtr<nsIAbDirectoryQueryResult> queryResult;
00729     nsAbDirectoryQueryResult* _queryResult = new nsAbDirectoryQueryResult (0,
00730         arguments,
00731         nsIAbDirectoryQueryResult::queryResultError,
00732         0);
00733     if (!_queryResult)
00734         return NS_ERROR_OUT_OF_MEMORY;
00735     queryResult = _queryResult;
00736 
00737     return listener->OnQueryItem (queryResult);
00738 }
00739 
00740 
00741 
00742