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
This commit is contained in:
doronr%us.ibm.com 2005-06-29 20:42:24 +00:00
parent 6bf164df2c
commit a12a4508a8
3 changed files with 238 additions and 22 deletions

View File

@ -21,6 +21,7 @@
* *
* Contributor(s): * Contributor(s):
* Doron Rosenberg <doronr@us.ibm.com> (original author) * Doron Rosenberg <doronr@us.ibm.com> (original author)
* Laurent Jouanneau <laurent@xulfr.org>
* *
* Alternatively, the contents of this file may be used under the terms of * 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 * 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 // back one up since we have the separator included
year = Substring(buffStart, --start); year = Substring(buffStart, --start);
isValid = IsValidSchemaGYear(year, &aYearMonth->gYear); isValid = IsValidSchemaGYear(year, aYearMonth ? &aYearMonth->gYear : nsnull);
if (isValid) { if (isValid) {
nsAutoString month; nsAutoString month;
@ -1475,7 +1476,7 @@ nsSchemaValidator::IsValidSchemaGYearMonth(const nsAString & aNodeValue,
start++; start++;
month.Append(Substring(start, end)); month.Append(Substring(start, end));
isValid = IsValidSchemaGMonth(month, &aYearMonth->gMonth); isValid = IsValidSchemaGMonth(month, aYearMonth ? &aYearMonth->gMonth : nsnull);
} }
done = PR_TRUE; done = PR_TRUE;
} else { } else {
@ -1590,7 +1591,7 @@ nsSchemaValidator::IsValidSchemaGMonthDay(const nsAString & aNodeValue,
nsAutoString month; nsAutoString month;
month.AppendLiteral("--"); month.AppendLiteral("--");
month.Append(Substring(buffStart, start.advance(2))); month.Append(Substring(buffStart, start.advance(2)));
isValid = IsValidSchemaGMonth(month, &aMonthDay->gMonth); isValid = IsValidSchemaGMonth(month, aMonthDay ? &aMonthDay->gMonth : nsnull);
if (isValid) { if (isValid) {
buffStart = start; buffStart = start;
@ -1603,7 +1604,7 @@ nsSchemaValidator::IsValidSchemaGMonthDay(const nsAString & aNodeValue,
nsAutoString day; nsAutoString day;
day.AppendLiteral("---"); day.AppendLiteral("---");
day.Append(Substring(++buffStart, end)); day.Append(Substring(++buffStart, end));
isValid = IsValidSchemaGDay(day, &aMonthDay->gDay); isValid = IsValidSchemaGDay(day, aMonthDay ? &aMonthDay->gDay : nsnull);
done = PR_TRUE; done = PR_TRUE;
} }
} }
@ -1708,15 +1709,17 @@ NS_IMETHODIMP
nsSchemaValidator::ValidateBuiltinTypeTime(const nsAString & aValue, nsSchemaValidator::ValidateBuiltinTypeTime(const nsAString & aValue,
PRTime *aResult) PRTime *aResult)
{ {
nsresult rv = NS_OK;
PRTime time; PRTime time;
if (IsValidSchemaTime(aValue, &time)) { if (IsValidSchemaTime(aValue, &time)) {
*aResult = time; *aResult = time;
} else { } else {
*aResult = nsnull; *aResult = nsnull;
rv = NS_ERROR_ILLEGAL_VALUE;
} }
return NS_OK; return rv;
} }
PRBool PRBool
@ -1871,17 +1874,20 @@ NS_IMETHODIMP
nsSchemaValidator::ValidateBuiltinTypeDate(const nsAString & aValue, nsSchemaValidator::ValidateBuiltinTypeDate(const nsAString & aValue,
PRTime *aResult) PRTime *aResult)
{ {
nsresult rv = NS_OK;
PRTime time; PRTime time;
if (IsValidSchemaDate(aValue, &time)) { if (IsValidSchemaDate(aValue, &time)) {
*aResult = time; *aResult = time;
} else { } else {
*aResult = nsnull; *aResult = nsnull;
rv = NS_ERROR_ILLEGAL_VALUE;
} }
return NS_OK; return rv;
} }
/* http://www.w3.org/TR/xmlschema-2/#dateTime */ /* http://www.w3.org/TR/xmlschema-2/#dateTime */
nsresult nsresult
nsSchemaValidator::ValidateBuiltinTypeDateTime(const nsAString & aNodeValue, nsSchemaValidator::ValidateBuiltinTypeDateTime(const nsAString & aNodeValue,
@ -1958,15 +1964,17 @@ NS_IMETHODIMP
nsSchemaValidator::ValidateBuiltinTypeDateTime(const nsAString & aValue, nsSchemaValidator::ValidateBuiltinTypeDateTime(const nsAString & aValue,
PRTime *aResult) PRTime *aResult)
{ {
nsresult rv = NS_OK;
PRTime time; PRTime time;
if (IsValidSchemaDateTime(aValue, &time)) { if (IsValidSchemaDateTime(aValue, &time)) {
*aResult = time; *aResult = time;
} else { } else {
*aResult = nsnull; *aResult = nsnull;
rv = NS_ERROR_ILLEGAL_VALUE;
} }
return NS_OK; return rv;
} }
int int
@ -2108,14 +2116,17 @@ NS_IMETHODIMP
nsSchemaValidator::ValidateBuiltinTypeDuration(const nsAString & aValue, nsSchemaValidator::ValidateBuiltinTypeDuration(const nsAString & aValue,
nsISchemaDuration **aDuration) nsISchemaDuration **aDuration)
{ {
nsresult rv = NS_OK;
*aDuration = nsnull; *aDuration = nsnull;
nsCOMPtr<nsISchemaDuration> duration; nsCOMPtr<nsISchemaDuration> duration;
if (IsValidSchemaDuration(aValue, getter_AddRefs(duration))) { if (IsValidSchemaDuration(aValue, getter_AddRefs(duration))) {
duration.swap(*aDuration); duration.swap(*aDuration);
} else {
rv = NS_ERROR_ILLEGAL_VALUE;
} }
return NS_OK; return rv;
} }
PRBool PRBool

View File

@ -38,10 +38,15 @@
// XPCOM includes // XPCOM includes
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "nsString.h"
#include "nsXFormsUtils.h"
#include "nsISchemaValidator.h" #include "nsISchemaValidator.h"
#include "nsISchemaDuration.h"
#include "nsXFormsSchemaValidator.h" #include "nsXFormsSchemaValidator.h"
#include "nsIDOM3Node.h"
#define NS_SCHEMAVALIDATOR_CONTRACTID "@mozilla.org/schemavalidator;1" #define NS_SCHEMAVALIDATOR_CONTRACTID "@mozilla.org/schemavalidator;1"
nsXFormsSchemaValidator::nsXFormsSchemaValidator() nsXFormsSchemaValidator::nsXFormsSchemaValidator()
@ -49,39 +54,185 @@ nsXFormsSchemaValidator::nsXFormsSchemaValidator()
mSchemaValidator = do_GetService(NS_SCHEMAVALIDATOR_CONTRACTID); mSchemaValidator = do_GetService(NS_SCHEMAVALIDATOR_CONTRACTID);
} }
nsresult nsXFormsSchemaValidator::LoadSchema(nsISchema* aSchema) nsresult
nsXFormsSchemaValidator::LoadSchema(nsISchema* aSchema)
{ {
NS_ENSURE_TRUE(mSchemaValidator, NS_ERROR_UNEXPECTED); NS_ENSURE_TRUE(mSchemaValidator, NS_ERROR_UNEXPECTED);
return mSchemaValidator->LoadSchema(aSchema); return mSchemaValidator->LoadSchema(aSchema);
} }
PRBool nsXFormsSchemaValidator::ValidateString(const nsAString & aValue, PRBool
const nsAString & aType, const nsAString & aNamespace) nsXFormsSchemaValidator::ValidateString(const nsAString & aValue,
const nsAString & aType,
const nsAString & aNamespace)
{ {
PRBool isValid = PR_FALSE; PRBool isValid = PR_FALSE;
NS_ENSURE_TRUE(mSchemaValidator, isValid); NS_ENSURE_TRUE(mSchemaValidator, 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); mSchemaValidator->ValidateString(aValue, aType, aNamespace, &isValid);
}
return isValid; return isValid;
} }
PRBool nsXFormsSchemaValidator::Validate(nsIDOMNode* aElement) PRBool
nsXFormsSchemaValidator::ValidateNode(nsIDOMNode* aElement,
const nsAString & aType,
const nsAString & aNamespace)
{ {
PRBool isValid = PR_FALSE; PRBool isValid = PR_FALSE;
NS_ENSURE_TRUE(mSchemaValidator, isValid); 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<nsIDOM3Node> domNode3 = do_QueryInterface(aElement);
domNode3->GetTextContent(nodeValue);
isValid = ValidateString(nodeValue, aType, aNamespace);
} else {
nsCOMPtr<nsISchemaType> type;
if (GetType(aType, aNamespace, getter_AddRefs(type))) {
mSchemaValidator->ValidateAgainstType(aElement, type, &isValid);
}
}
return isValid; return isValid;
} }
PRBool nsXFormsSchemaValidator::GetType(const nsAString & aType, PRBool
const nsAString & aNamespace, nsISchemaType **aSchemaType) nsXFormsSchemaValidator::GetType(const nsAString & aType,
const nsAString & aNamespace,
nsISchemaType **aSchemaType)
{ {
NS_ENSURE_TRUE(mSchemaValidator, PR_FALSE); NS_ENSURE_TRUE(mSchemaValidator, PR_FALSE);
PRBool success = PR_FALSE;
nsresult rv = mSchemaValidator->GetType(aType, aNamespace, aSchemaType); 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<nsISchemaDuration> 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<nsISchemaDuration> 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;
}

View File

@ -42,16 +42,70 @@
class nsXFormsSchemaValidator class nsXFormsSchemaValidator
{ {
public: public:
nsXFormsSchemaValidator(); nsXFormsSchemaValidator();
/**
* Loads a schema into the validator
*
* @param aSchema The schema to load
* @return If it succeeded or not
*/
nsresult LoadSchema(nsISchema* aSchema); 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, PRBool ValidateString(const nsAString & aValue, const nsAString & aType,
const nsAString & aNamespace); const nsAString & aNamespace);
PRBool Validate(nsIDOMNode* aElement);
/**
* 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, PRBool GetType(const nsAString & aType, const nsAString & aNamespace,
nsISchemaType **aSchemaType); 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: protected:
nsCOMPtr<nsISchemaValidator> mSchemaValidator; nsCOMPtr<nsISchemaValidator> mSchemaValidator;