From a12a4508a87df3e2a427bd911f765894b766ac69 Mon Sep 17 00:00:00 2001 From: "doronr%us.ibm.com" Date: Wed, 29 Jun 2005 20:42:24 +0000 Subject: [PATCH] XForms bug 278447 - Implement XForms Schema Types. r=aaronr/smaug a=mkaply git-svn-id: svn://10.0.0.236/trunk@175341 18797224-902f-48f8-a5cc-f745e15eee43 --- .../src/nsSchemaValidator.cpp | 27 ++- .../xforms/nsXFormsSchemaValidator.cpp | 171 +++++++++++++++++- .../xforms/nsXFormsSchemaValidator.h | 62 ++++++- 3 files changed, 238 insertions(+), 22 deletions(-) diff --git a/mozilla/extensions/schema-validation/src/nsSchemaValidator.cpp b/mozilla/extensions/schema-validation/src/nsSchemaValidator.cpp index 377a61d0c0b..f295147fdfa 100644 --- a/mozilla/extensions/schema-validation/src/nsSchemaValidator.cpp +++ b/mozilla/extensions/schema-validation/src/nsSchemaValidator.cpp @@ -21,6 +21,7 @@ * * Contributor(s): * Doron Rosenberg (original author) + * Laurent Jouanneau * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -1467,7 +1468,7 @@ nsSchemaValidator::IsValidSchemaGYearMonth(const nsAString & aNodeValue, // back one up since we have the separator included year = Substring(buffStart, --start); - isValid = IsValidSchemaGYear(year, &aYearMonth->gYear); + isValid = IsValidSchemaGYear(year, aYearMonth ? &aYearMonth->gYear : nsnull); if (isValid) { nsAutoString month; @@ -1475,7 +1476,7 @@ nsSchemaValidator::IsValidSchemaGYearMonth(const nsAString & aNodeValue, start++; month.Append(Substring(start, end)); - isValid = IsValidSchemaGMonth(month, &aYearMonth->gMonth); + isValid = IsValidSchemaGMonth(month, aYearMonth ? &aYearMonth->gMonth : nsnull); } done = PR_TRUE; } else { @@ -1590,7 +1591,7 @@ nsSchemaValidator::IsValidSchemaGMonthDay(const nsAString & aNodeValue, nsAutoString month; month.AppendLiteral("--"); month.Append(Substring(buffStart, start.advance(2))); - isValid = IsValidSchemaGMonth(month, &aMonthDay->gMonth); + isValid = IsValidSchemaGMonth(month, aMonthDay ? &aMonthDay->gMonth : nsnull); if (isValid) { buffStart = start; @@ -1603,7 +1604,7 @@ nsSchemaValidator::IsValidSchemaGMonthDay(const nsAString & aNodeValue, nsAutoString day; day.AppendLiteral("---"); day.Append(Substring(++buffStart, end)); - isValid = IsValidSchemaGDay(day, &aMonthDay->gDay); + isValid = IsValidSchemaGDay(day, aMonthDay ? &aMonthDay->gDay : nsnull); done = PR_TRUE; } } @@ -1708,15 +1709,17 @@ NS_IMETHODIMP nsSchemaValidator::ValidateBuiltinTypeTime(const nsAString & aValue, PRTime *aResult) { + nsresult rv = NS_OK; PRTime time; if (IsValidSchemaTime(aValue, &time)) { *aResult = time; } else { *aResult = nsnull; + rv = NS_ERROR_ILLEGAL_VALUE; } - return NS_OK; + return rv; } PRBool @@ -1871,17 +1874,20 @@ NS_IMETHODIMP nsSchemaValidator::ValidateBuiltinTypeDate(const nsAString & aValue, PRTime *aResult) { + nsresult rv = NS_OK; PRTime time; if (IsValidSchemaDate(aValue, &time)) { *aResult = time; } else { *aResult = nsnull; + rv = NS_ERROR_ILLEGAL_VALUE; } - return NS_OK; + return rv; } + /* http://www.w3.org/TR/xmlschema-2/#dateTime */ nsresult nsSchemaValidator::ValidateBuiltinTypeDateTime(const nsAString & aNodeValue, @@ -1958,15 +1964,17 @@ NS_IMETHODIMP nsSchemaValidator::ValidateBuiltinTypeDateTime(const nsAString & aValue, PRTime *aResult) { + nsresult rv = NS_OK; PRTime time; if (IsValidSchemaDateTime(aValue, &time)) { *aResult = time; } else { *aResult = nsnull; + rv = NS_ERROR_ILLEGAL_VALUE; } - return NS_OK; + return rv; } int @@ -2108,14 +2116,17 @@ NS_IMETHODIMP nsSchemaValidator::ValidateBuiltinTypeDuration(const nsAString & aValue, nsISchemaDuration **aDuration) { + nsresult rv = NS_OK; *aDuration = nsnull; nsCOMPtr duration; if (IsValidSchemaDuration(aValue, getter_AddRefs(duration))) { duration.swap(*aDuration); + } else { + rv = NS_ERROR_ILLEGAL_VALUE; } - return NS_OK; + return rv; } PRBool diff --git a/mozilla/extensions/xforms/nsXFormsSchemaValidator.cpp b/mozilla/extensions/xforms/nsXFormsSchemaValidator.cpp index 00f1fd9a65f..f090d3cae61 100644 --- a/mozilla/extensions/xforms/nsXFormsSchemaValidator.cpp +++ b/mozilla/extensions/xforms/nsXFormsSchemaValidator.cpp @@ -38,10 +38,15 @@ // XPCOM includes #include "nsIServiceManager.h" +#include "nsString.h" +#include "nsXFormsUtils.h" #include "nsISchemaValidator.h" +#include "nsISchemaDuration.h" #include "nsXFormsSchemaValidator.h" +#include "nsIDOM3Node.h" + #define NS_SCHEMAVALIDATOR_CONTRACTID "@mozilla.org/schemavalidator;1" nsXFormsSchemaValidator::nsXFormsSchemaValidator() @@ -49,39 +54,185 @@ nsXFormsSchemaValidator::nsXFormsSchemaValidator() mSchemaValidator = do_GetService(NS_SCHEMAVALIDATOR_CONTRACTID); } -nsresult nsXFormsSchemaValidator::LoadSchema(nsISchema* aSchema) +nsresult +nsXFormsSchemaValidator::LoadSchema(nsISchema* aSchema) { NS_ENSURE_TRUE(mSchemaValidator, NS_ERROR_UNEXPECTED); return mSchemaValidator->LoadSchema(aSchema); } -PRBool nsXFormsSchemaValidator::ValidateString(const nsAString & aValue, - const nsAString & aType, const nsAString & aNamespace) +PRBool +nsXFormsSchemaValidator::ValidateString(const nsAString & aValue, + const nsAString & aType, + const nsAString & aNamespace) { PRBool isValid = PR_FALSE; NS_ENSURE_TRUE(mSchemaValidator, isValid); - mSchemaValidator->ValidateString(aValue, aType, aNamespace, &isValid); + + // if it is the XForms namespace, handle it internally, else delegate to + // nsISchemaValidator + if (aNamespace.EqualsLiteral(NS_NAMESPACE_XFORMS)) { + isValid = ValidateXFormsTypeString(aValue, aType); + } else { + mSchemaValidator->ValidateString(aValue, aType, aNamespace, &isValid); + } return isValid; } -PRBool nsXFormsSchemaValidator::Validate(nsIDOMNode* aElement) +PRBool +nsXFormsSchemaValidator::ValidateNode(nsIDOMNode* aElement, + const nsAString & aType, + const nsAString & aNamespace) { PRBool isValid = PR_FALSE; - NS_ENSURE_TRUE(mSchemaValidator, isValid); - mSchemaValidator->Validate(aElement, &isValid); + + if (aNamespace.EqualsLiteral(NS_NAMESPACE_XFORMS)) { + // XXX: currently, we will only support validating a lone node. When + // we get complex type support, we should load the schema for the xforms + // types and use ValidateAgainstType like below. + nsAutoString nodeValue; + nsCOMPtr domNode3 = do_QueryInterface(aElement); + domNode3->GetTextContent(nodeValue); + + isValid = ValidateString(nodeValue, aType, aNamespace); + } else { + nsCOMPtr type; + if (GetType(aType, aNamespace, getter_AddRefs(type))) { + mSchemaValidator->ValidateAgainstType(aElement, type, &isValid); + } + } return isValid; } -PRBool nsXFormsSchemaValidator::GetType(const nsAString & aType, - const nsAString & aNamespace, nsISchemaType **aSchemaType) +PRBool +nsXFormsSchemaValidator::GetType(const nsAString & aType, + const nsAString & aNamespace, + nsISchemaType **aSchemaType) { NS_ENSURE_TRUE(mSchemaValidator, PR_FALSE); + + PRBool success = PR_FALSE; nsresult rv = mSchemaValidator->GetType(aType, aNamespace, aSchemaType); - return( NS_SUCCEEDED(rv) ); + return NS_SUCCEEDED(rv); } + +// xforms schema types +PRBool +nsXFormsSchemaValidator::ValidateXFormsTypeString(const nsAString & aValue, + const nsAString & aType) +{ + if (aType.IsEmpty()) { + return PR_FALSE; + } + + PRBool isValid = PR_FALSE; + + if (aType.EqualsLiteral("yearMonthDuration")) { + isValid = IsValidSchemaYearMonthDuration(aValue); + } else if (aType.EqualsLiteral("dayTimeDuration")) { + isValid = IsValidSchemaDayTimeDuration(aValue); + } else if (aType.EqualsLiteral("listItem")) { + isValid = IsValidSchemaListItem(aValue); + } else if (aType.EqualsLiteral("listItems")) { + isValid = IsValidSchemaListItems(aValue); + } + + return isValid; +} + +PRBool +nsXFormsSchemaValidator::IsValidSchemaYearMonthDuration(const nsAString & aValue) +{ + PRBool isValid = PR_FALSE; + + nsCOMPtr duration; + nsresult rv = + mSchemaValidator->ValidateBuiltinTypeDuration(aValue, + getter_AddRefs(duration)); + + // valid duration + if (NS_SUCCEEDED(rv)) { + // check if no days/hours/minutes/seconds/fractionseconds were set + PRUint32 temp; + duration->GetDays(&temp); + + if (temp == 0) { + duration->GetHours(&temp); + if (temp == 0) { + duration->GetMinutes(&temp); + if (temp == 0) { + duration->GetSeconds(&temp); + if (temp == 0) { + duration->GetFractionSeconds(&temp); + if (temp == 0) { + isValid = PR_TRUE; + } + } + } + } + } + } + + return isValid; +} + +PRBool +nsXFormsSchemaValidator::IsValidSchemaDayTimeDuration(const nsAString & aValue) +{ + PRBool isValid = PR_FALSE; + + nsCOMPtr duration; + nsresult rv = + mSchemaValidator->ValidateBuiltinTypeDuration(aValue, + getter_AddRefs(duration)); + + if (NS_SUCCEEDED(rv)) { + PRUint32 years, months; + duration->GetYears(&years); + duration->GetMonths(&months); + + // if years/months exist, invalid + if ((years == 0) && (months == 0)) + isValid = PR_TRUE; + } + + return isValid; +} + +PRBool +nsXFormsSchemaValidator::IsValidSchemaListItem(const nsAString & aValue) +{ + PRBool isValid = PR_FALSE; + + // like a string, but no whitespace + nsAutoString string(aValue); + if (string.FindCharInSet(" \t\r\n") == kNotFound) { + mSchemaValidator->ValidateString(aValue, NS_LITERAL_STRING("string"), + NS_LITERAL_STRING("http://www.w3.org/1999/XMLSchema"), + &isValid); + } + + return isValid; +} + +PRBool +nsXFormsSchemaValidator::IsValidSchemaListItems(const nsAString & aValue) +{ + PRBool isValid = PR_FALSE; + + // listItem is like a string, but no whitespace. listItems is a whitespace + // delimeted list of listItem, so therefore just need to see if it is a valid + // xsd:string + mSchemaValidator->ValidateString(aValue, NS_LITERAL_STRING("string"), + NS_LITERAL_STRING("http://www.w3.org/1999/XMLSchema"), + &isValid); + + return isValid; +} + diff --git a/mozilla/extensions/xforms/nsXFormsSchemaValidator.h b/mozilla/extensions/xforms/nsXFormsSchemaValidator.h index e8260492542..b1ddf0ebfe3 100644 --- a/mozilla/extensions/xforms/nsXFormsSchemaValidator.h +++ b/mozilla/extensions/xforms/nsXFormsSchemaValidator.h @@ -42,16 +42,70 @@ class nsXFormsSchemaValidator { public: - nsXFormsSchemaValidator(); + /** + * Loads a schema into the validator + * + * @param aSchema The schema to load + * @return If it succeeded or not + */ nsresult LoadSchema(nsISchema* aSchema); + + /** + * Validates a string against a namespace and schema type + * + * @param aValue Value to validate + * @param aType Type + * @param aNamespace Namespace + * @return Whether the string is valid or not + */ PRBool ValidateString(const nsAString & aValue, const nsAString & aType, - const nsAString & aNamespace); - PRBool Validate(nsIDOMNode* aElement); + const nsAString & aNamespace); + + /** + * Validates a node against a namespace and schema type + * + * @param aElement Node to validate + * @param aType Type + * @param aNamespace Namespace + * @return Whether the string is valid or not + */ + PRBool ValidateNode(nsIDOMNode* aElement, const nsAString & aType, + const nsAString & aNamespace); + + /** + * Returns a nsISchemaType given an type and namespace + * + * @param aType Type + * @param aNamespace Namespace + * @param aSchemaType The nsISchemaType is stored here. + * @return Whether a type was found or not + */ PRBool GetType(const nsAString & aType, const nsAString & aNamespace, nsISchemaType **aSchemaType); - + + /** + * Validates a string against an XForms Schema Type + * + * @param aValue Value to validate + * @param aType Type + * @return Whether the string is valid or not + */ + PRBool ValidateXFormsTypeString(const nsAString & aValue, + const nsAString & aType); + + // Returns if the string is a valid XForms YearMonth duration + PRBool IsValidSchemaYearMonthDuration(const nsAString & aValue); + + // Returns if the string is a valid XForms DayTime duration + PRBool IsValidSchemaDayTimeDuration(const nsAString & aValue); + + // Returns if the string is a valid XForms listitem + PRBool IsValidSchemaListItem(const nsAString & aValue); + + // Returns if the string is a valid XForms list of listitems + PRBool IsValidSchemaListItems(const nsAString & aValue); protected: nsCOMPtr mSchemaValidator;