Back to index

lightning-sunbird  0.9+nobinonly
nsAbQueryStringToExpression.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  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsAbQueryStringToExpression.h"
00040 
00041 #include "nsIComponentManager.h"
00042 #include "nsIServiceManager.h"
00043 #include "nsCOMPtr.h"
00044 #include "nsXPIDLString.h"
00045 #include "nsString.h"
00046 #include "nsISupportsArray.h"
00047 #include "nsITextToSubURI.h"
00048 #include "nsAbBooleanExpression.h"
00049 #include "nsAbBaseCID.h"
00050 #include "nsCRT.h"
00051 
00052 nsresult nsAbQueryStringToExpression::Convert (
00053     const char* queryString,
00054     nsIAbBooleanExpression** expression)
00055 {
00056     nsresult rv;
00057 
00058     nsCAutoString q(queryString);
00059     q.StripWhitespace ();
00060     queryString = q.get ();
00061 
00062     nsCOMPtr<nsISupports> s;
00063     rv = ParseExpression (&queryString, getter_AddRefs(s));
00064     NS_ENSURE_SUCCESS(rv, rv);
00065 
00066     // Case: Not end of string
00067     if (*queryString != 0)
00068         return NS_ERROR_FAILURE;
00069 
00070     nsCOMPtr<nsIAbBooleanExpression> e(do_QueryInterface(s, &rv));
00071     NS_ENSURE_SUCCESS(rv, rv);
00072 
00073     NS_IF_ADDREF(*expression = e);
00074     return rv;
00075 }
00076 
00077 nsresult nsAbQueryStringToExpression::ParseExpression (
00078     const char** index,
00079     nsISupports** expression)
00080 {
00081     nsresult rv;
00082 
00083     if (**index != '(')
00084         return NS_ERROR_FAILURE;
00085 
00086     const char* indexBracket = *index + 1;
00087     while (*indexBracket &&
00088         *indexBracket != '(' && *indexBracket != ')')
00089         indexBracket++;
00090 
00091     // Case: End of string
00092     if (*indexBracket == 0)
00093         return NS_ERROR_FAILURE;
00094 
00095     // Case: "((" or "()"
00096     if (indexBracket == *index + 1)
00097     {
00098          return NS_ERROR_FAILURE;
00099     }
00100     // Case: "(*("
00101     else if (*indexBracket == '(')
00102     {
00103         // printf ("Case: (*(: %s\n", *index);
00104 
00105         nsXPIDLCString operation;
00106         rv = ParseOperationEntry (
00107             *index, indexBracket,
00108             getter_Copies (operation));
00109         NS_ENSURE_SUCCESS(rv, rv);
00110 
00111         nsCOMPtr<nsIAbBooleanExpression> e;
00112         rv = CreateBooleanExpression(operation,
00113             getter_AddRefs(e));
00114         NS_ENSURE_SUCCESS(rv, rv);
00115 
00116         // Case: "(*)(*)....(*))"
00117         *index = indexBracket;
00118         rv = ParseExpressions (index, e);
00119         NS_ENSURE_SUCCESS(rv, rv);
00120 
00121         NS_IF_ADDREF(*expression = e);
00122     }
00123     // Case" "(*)"
00124     else if (*indexBracket == ')')
00125     {
00126         // printf ("Case: (*): %s\n", *index);
00127 
00128         nsCOMPtr<nsIAbBooleanConditionString> conditionString;
00129         rv = ParseCondition (index, indexBracket,
00130             getter_AddRefs(conditionString));
00131         NS_ENSURE_SUCCESS(rv, rv);
00132 
00133         NS_IF_ADDREF(*expression = conditionString);
00134     }
00135 
00136     if (**index != ')')
00137         return NS_ERROR_FAILURE;
00138 
00139     (*index)++;
00140 
00141     return NS_OK;
00142 }
00143 
00144 
00145 nsresult nsAbQueryStringToExpression::ParseExpressions (
00146     const char** index,
00147     nsIAbBooleanExpression* expression)
00148 {
00149     nsresult rv;
00150 
00151     nsCOMPtr<nsISupportsArray> expressions;
00152     NS_NewISupportsArray(getter_AddRefs(expressions));
00153 
00154     // Case: ")(*)(*)....(*))"
00155     // printf ("Case: )(*)(*)....(*)): %s\n", *index);
00156     while (**index == '(')
00157     {
00158         nsCOMPtr<nsISupports> childExpression;
00159         rv = ParseExpression (index, getter_AddRefs (childExpression));
00160         NS_ENSURE_SUCCESS(rv, rv);
00161 
00162         expressions->AppendElement (childExpression);
00163     }
00164 
00165     if (**index == 0)
00166         return NS_ERROR_FAILURE;
00167 
00168     // Case: "))"
00169     // printf ("Case: )): %s\n", *index);
00170 
00171     if (**index != ')')
00172         return NS_ERROR_FAILURE;
00173 
00174     expression->SetExpressions (expressions);
00175 
00176     return NS_OK;
00177 }
00178 
00179 nsresult nsAbQueryStringToExpression::ParseCondition (
00180     const char** index,
00181     const char* indexBracketClose,
00182     nsIAbBooleanConditionString** conditionString)
00183 {
00184     nsresult rv;
00185 
00186     (*index)++;
00187 
00188     nsXPIDLCString entries[3];
00189     for (int i = 0; i < 3; i++)
00190     {
00191         rv = ParseConditionEntry (index, indexBracketClose,
00192                 getter_Copies (entries[i]));
00193         NS_ENSURE_SUCCESS(rv, rv);
00194 
00195         if (*index == indexBracketClose)
00196             break;
00197     }
00198     
00199     if (*index != indexBracketClose)
00200         return NS_ERROR_FAILURE;
00201 
00202     nsCOMPtr<nsIAbBooleanConditionString> c;
00203     rv = CreateBooleanConditionString (
00204         entries[0],
00205         entries[1],
00206         entries[2],
00207         getter_AddRefs (c));
00208     NS_ENSURE_SUCCESS(rv, rv);
00209 
00210     NS_IF_ADDREF(*conditionString = c);
00211     return NS_OK;
00212 }
00213 
00214 nsresult nsAbQueryStringToExpression::ParseConditionEntry (
00215     const char** index,
00216     const char* indexBracketClose,
00217     char** entry)
00218 {
00219     const char* indexDeliminator = *index;
00220     while (indexDeliminator != indexBracketClose &&
00221         *indexDeliminator != ',')
00222         indexDeliminator++;
00223 
00224     int entryLength = indexDeliminator - *index;
00225     if (entryLength)
00226         *entry = nsCRT::strndup (*index, entryLength); 
00227     else
00228         *entry = 0;
00229 
00230     if (indexDeliminator != indexBracketClose)
00231         *index = indexDeliminator + 1;
00232     else
00233         *index = indexDeliminator;
00234 
00235     return NS_OK;
00236 }
00237 
00238 nsresult nsAbQueryStringToExpression::ParseOperationEntry (
00239     const char* indexBracketOpen1,
00240     const char* indexBracketOpen2,
00241     char** operation)
00242 {
00243     int operationLength = indexBracketOpen2 - indexBracketOpen1 - 1;
00244     if (operationLength)
00245         *operation = nsCRT::strndup (indexBracketOpen1 + 1,
00246             operationLength); 
00247     else
00248         *operation = 0;
00249 
00250     return NS_OK;
00251 }
00252 
00253 nsresult nsAbQueryStringToExpression::CreateBooleanExpression(
00254         const char* operation,
00255         nsIAbBooleanExpression** expression)
00256 {
00257     nsAbBooleanOperationType op;
00258     if (nsCRT::strcasecmp (operation, "and") == 0)
00259         op = nsIAbBooleanOperationTypes::AND;
00260     else if (nsCRT::strcasecmp (operation, "or") == 0)
00261         op = nsIAbBooleanOperationTypes::OR;
00262     else if (nsCRT::strcasecmp (operation, "not") == 0)
00263         op = nsIAbBooleanOperationTypes::NOT;
00264     else
00265         return NS_ERROR_FAILURE;
00266 
00267     nsresult rv;
00268 
00269     nsCOMPtr <nsIAbBooleanExpression> expr = do_CreateInstance(NS_BOOLEANEXPRESSION_CONTRACTID, &rv);
00270     NS_ENSURE_SUCCESS(rv, rv);
00271 
00272     NS_IF_ADDREF(*expression = expr);
00273     
00274     rv = expr->SetOperation (op);
00275     return rv;
00276 }
00277 
00278 nsresult nsAbQueryStringToExpression::CreateBooleanConditionString (
00279     const char* attribute,
00280     const char* condition,
00281     const char* value,
00282     nsIAbBooleanConditionString** conditionString)
00283 {
00284     if (attribute == 0 || condition == 0 || value == 0)
00285         return NS_ERROR_FAILURE;
00286 
00287     nsAbBooleanConditionType c;
00288 
00289     if (nsCRT::strcasecmp (condition, "=") == 0)
00290         c = nsIAbBooleanConditionTypes::Is;
00291     else if (nsCRT::strcasecmp (condition, "!=") == 0)
00292         c = nsIAbBooleanConditionTypes::IsNot;
00293     else if (nsCRT::strcasecmp (condition, "lt") == 0)
00294         c = nsIAbBooleanConditionTypes::LessThan;
00295     else if (nsCRT::strcasecmp (condition, "gt") == 0)
00296         c = nsIAbBooleanConditionTypes::GreaterThan;
00297     else if (nsCRT::strcasecmp (condition, "bw") == 0)
00298         c = nsIAbBooleanConditionTypes::BeginsWith;
00299     else if (nsCRT::strcasecmp (condition, "ew") == 0)
00300         c = nsIAbBooleanConditionTypes::EndsWith;
00301     else if (nsCRT::strcasecmp (condition, "c")== 0)
00302         c = nsIAbBooleanConditionTypes::Contains;
00303     else if (nsCRT::strcasecmp (condition, "!c") == 0)
00304         c = nsIAbBooleanConditionTypes::DoesNotContain;
00305     else if (nsCRT::strcasecmp (condition, "~=") == 0)
00306         c = nsIAbBooleanConditionTypes::SoundsLike;
00307     else if (nsCRT::strcasecmp (condition, "regex") == 0)
00308         c = nsIAbBooleanConditionTypes::RegExp;
00309     else
00310         return NS_ERROR_FAILURE;
00311 
00312     nsresult rv;
00313 
00314     nsCOMPtr<nsIAbBooleanConditionString> cs = do_CreateInstance(NS_BOOLEANCONDITIONSTRING_CONTRACTID, &rv);
00315     NS_ENSURE_SUCCESS(rv, rv);
00316 
00317     rv = cs->SetCondition (c);
00318     NS_ENSURE_SUCCESS(rv, rv);
00319 
00320     nsCOMPtr<nsITextToSubURI> textToSubURI = do_GetService(NS_ITEXTTOSUBURI_CONTRACTID,&rv); 
00321     if (NS_SUCCEEDED(rv))
00322     {
00323         nsXPIDLString attributeUCS2;
00324         nsXPIDLString valueUCS2;
00325 
00326         rv = textToSubURI->UnEscapeAndConvert("UTF-8",
00327             attribute, getter_Copies(attributeUCS2));
00328         NS_ENSURE_SUCCESS(rv, rv);
00329 
00330         rv = textToSubURI->UnEscapeAndConvert("UTF-8",
00331             value, getter_Copies(valueUCS2));
00332         NS_ENSURE_SUCCESS(rv, rv);
00333 
00334         NS_ConvertUCS2toUTF8 attributeUTF8(attributeUCS2);
00335 
00336         rv = cs->SetName (attributeUTF8.get ());
00337         NS_ENSURE_SUCCESS(rv, rv);
00338         rv = cs->SetValue (valueUCS2);
00339         NS_ENSURE_SUCCESS(rv, rv);
00340     }
00341     else
00342     {
00343         NS_ConvertUTF8toUCS2 valueUCS2(value);
00344 
00345         rv = cs->SetName (attribute);
00346         NS_ENSURE_SUCCESS(rv, rv);
00347         rv = cs->SetValue (valueUCS2.get ());
00348         NS_ENSURE_SUCCESS(rv, rv);
00349     }
00350             
00351 
00352     NS_IF_ADDREF(*conditionString = cs);
00353     return NS_OK;
00354 }
00355 
00356