surkov.alexander%gmail.com 4a3e7bbdf0 Bug 388992 – Make schema-validation not depend on webservices, patch=aaronr, r=doronr, sspeiche@gmail.com, benjamin, a=beltzner
git-svn-id: svn://10.0.0.236/trunk@245485 18797224-902f-48f8-a5cc-f745e15eee43
2008-02-12 14:36:40 +00:00

834 lines
18 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is
* Netscape Communications.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Vidur Apparao <vidur@netscape.com> (original author)
*
* 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
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsSchemaPrivate.h"
////////////////////////////////////////////////////////////
//
// nsSchemaParticleBase implementation
//
////////////////////////////////////////////////////////////
nsSchemaParticleBase::nsSchemaParticleBase(nsSchema* aSchema)
: nsSchemaComponentBase(aSchema), mMinOccurs(1), mMaxOccurs(1)
{
}
nsSchemaParticleBase::~nsSchemaParticleBase()
{
}
NS_IMETHODIMP
nsSchemaParticleBase::GetMinOccurs(PRUint32 *aMinOccurs)
{
NS_ENSURE_ARG_POINTER(aMinOccurs);
*aMinOccurs = mMinOccurs;
return NS_OK;
}
NS_IMETHODIMP
nsSchemaParticleBase::GetMaxOccurs(PRUint32 *aMaxOccurs)
{
NS_ENSURE_ARG_POINTER(aMaxOccurs);
*aMaxOccurs = mMaxOccurs;
return NS_OK;
}
NS_IMETHODIMP
nsSchemaParticleBase::SetMinOccurs(PRUint32 aMinOccurs)
{
mMinOccurs = aMinOccurs;
if (mMaxOccurs < mMinOccurs) {
mMaxOccurs = mMinOccurs;
}
return NS_OK;
}
NS_IMETHODIMP
nsSchemaParticleBase::SetMaxOccurs(PRUint32 aMaxOccurs)
{
mMaxOccurs = aMaxOccurs;
if (mMinOccurs > mMaxOccurs) {
mMinOccurs = mMaxOccurs;
}
return NS_OK;
}
////////////////////////////////////////////////////////////
//
// nsSchemaModelGroup implementation
//
////////////////////////////////////////////////////////////
nsSchemaModelGroup::nsSchemaModelGroup(nsSchema* aSchema,
const nsAString& aName)
: nsSchemaParticleBase(aSchema), mName(aName), mCompositor(COMPOSITOR_SEQUENCE)
{
}
nsSchemaModelGroup::~nsSchemaModelGroup()
{
}
NS_IMPL_ISUPPORTS3(nsSchemaModelGroup,
nsISVSchemaComponent,
nsISVSchemaParticle,
nsISVSchemaModelGroup)
/* void resolve (in nsISVSchemaErrorHandler aErrorHandler); */
NS_IMETHODIMP
nsSchemaModelGroup::Resolve(nsISVSchemaErrorHandler* aErrorHandler)
{
if (mIsResolved) {
return NS_OK;
}
mIsResolved = PR_TRUE;
nsresult rv;
PRUint32 i, count;
count = mParticles.Count();
for (i = 0; i < count; ++i) {
rv = mParticles.ObjectAt(i)->Resolve(aErrorHandler);
if (NS_FAILED(rv)) {
nsAutoString name;
nsresult rc = mParticles.ObjectAt(i)->GetName(name);
NS_ENSURE_SUCCESS(rc, rc);
nsAutoString errorMsg;
errorMsg.AppendLiteral("Failure resolving schema particle, cannot ");
errorMsg.AppendLiteral("resolve particle \"");
errorMsg.Append(name);
errorMsg.AppendLiteral("\"");
NS_SCHEMALOADER_FIRE_ERROR(rv, errorMsg);
return rv;
}
}
return NS_OK;
}
/* void clear (); */
NS_IMETHODIMP
nsSchemaModelGroup::Clear()
{
if (mIsCleared) {
return NS_OK;
}
mIsCleared = PR_TRUE;
PRUint32 i, count;
count = mParticles.Count();
for (i = 0; i < count; ++i) {
mParticles.ObjectAt(i)->Clear();
}
return NS_OK;
}
NS_IMETHODIMP
nsSchemaModelGroup::GetParticleType(PRUint16 *aParticleType)
{
NS_ENSURE_ARG_POINTER(aParticleType);
*aParticleType = nsISVSchemaParticle::PARTICLE_TYPE_MODEL_GROUP;
return NS_OK;
}
NS_IMETHODIMP
nsSchemaModelGroup::GetName(nsAString& aName)
{
aName.Assign(mName);
return NS_OK;
}
/* readonly attribute unsigned short compositor; */
NS_IMETHODIMP
nsSchemaModelGroup::GetCompositor(PRUint16 *aCompositor)
{
NS_ENSURE_ARG_POINTER(aCompositor);
*aCompositor = mCompositor;
return NS_OK;
}
/* readonly attribute PRUint32 particleCount; */
NS_IMETHODIMP
nsSchemaModelGroup::GetParticleCount(PRUint32 *aParticleCount)
{
NS_ENSURE_ARG_POINTER(aParticleCount);
*aParticleCount = mParticles.Count();
return NS_OK;
}
/* nsISVSchemaParticle getParticle (in PRUint32 index); */
NS_IMETHODIMP
nsSchemaModelGroup::GetParticle(PRUint32 aIndex, nsISVSchemaParticle** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
if (aIndex >= (PRUint32)mParticles.Count()) {
return NS_ERROR_FAILURE;
}
NS_ADDREF(*aResult = mParticles.ObjectAt(aIndex));
return NS_OK;
}
/* nsISVSchemaElement getElementByName(in AString name); */
NS_IMETHODIMP
nsSchemaModelGroup::GetElementByName(const nsAString& aName,
nsISVSchemaElement** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
PRUint32 i, count;
count = mParticles.Count();
for (i = 0; i < count; ++i) {
nsISVSchemaParticle* particle = mParticles.ObjectAt(i);
nsCOMPtr<nsISVSchemaElement> element = do_QueryInterface(particle);
if (element) {
nsAutoString name;
element->GetName(name);
if (name.Equals(aName)) {
NS_ADDREF(*aResult = element);
return NS_OK;
}
}
else {
nsCOMPtr<nsISVSchemaModelGroup> group = do_QueryInterface(particle);
if (group) {
nsresult rv = group->GetElementByName(aName, aResult);
if (NS_SUCCEEDED(rv)) {
return NS_OK;
}
}
}
}
return NS_ERROR_FAILURE; // No element of that name found
}
NS_IMETHODIMP
nsSchemaModelGroup::SetCompositor(PRUint16 aCompositor)
{
mCompositor = aCompositor;
return NS_OK;
}
NS_IMETHODIMP
nsSchemaModelGroup::AddParticle(nsISVSchemaParticle* aParticle)
{
NS_ENSURE_ARG_POINTER(aParticle);
return mParticles.AppendObject(aParticle) ? NS_OK : NS_ERROR_FAILURE;
}
////////////////////////////////////////////////////////////
//
// nsSchemaModelGroupRef implementation
//
////////////////////////////////////////////////////////////
nsSchemaModelGroupRef::nsSchemaModelGroupRef(nsSchema* aSchema,
const nsAString& aRef,
const nsAString& aRefNS)
: nsSchemaParticleBase(aSchema), mRef(aRef), mRefNS(aRefNS)
{
}
nsSchemaModelGroupRef::~nsSchemaModelGroupRef()
{
}
NS_IMPL_ISUPPORTS3(nsSchemaModelGroupRef,
nsISVSchemaComponent,
nsISVSchemaParticle,
nsISVSchemaModelGroup)
/* void resolve (in nsISVSchemaErrorHandler aErrorHandler); */
NS_IMETHODIMP
nsSchemaModelGroupRef::Resolve(nsISVSchemaErrorHandler* aErrorHandler)
{
nsresult rv = NS_OK;
if (mIsResolved) {
return NS_OK;
}
mIsResolved = PR_TRUE;
if (!mModelGroup && mSchema) {
if (mRefNS.IsEmpty()) {
mSchema->GetModelGroupByName(mRef, getter_AddRefs(mModelGroup));
} else {
// use the namespace and type
nsCOMPtr<nsISVSchemaCollection> schemaColl;
mSchema->GetCollection(getter_AddRefs(schemaColl));
NS_ENSURE_STATE(schemaColl);
// get the right schema
nsCOMPtr<nsISVSchema> schema;
schemaColl->GetSchema(mRefNS, getter_AddRefs(schema));
NS_ENSURE_STATE(schema);
schema->GetModelGroupByName(mRef, getter_AddRefs(mModelGroup));
}
}
if (mModelGroup) {
rv = mModelGroup->Resolve(aErrorHandler);
}
return rv;
}
/* void clear (); */
NS_IMETHODIMP
nsSchemaModelGroupRef::Clear()
{
if (mIsCleared) {
return NS_OK;
}
mIsCleared = PR_TRUE;
if (mModelGroup) {
mModelGroup->Clear();
mModelGroup = nsnull;
}
return NS_OK;
}
NS_IMETHODIMP
nsSchemaModelGroupRef::GetParticleType(PRUint16 *aParticleType)
{
NS_ENSURE_ARG_POINTER(aParticleType);
*aParticleType = nsISVSchemaParticle::PARTICLE_TYPE_MODEL_GROUP;
return NS_OK;
}
NS_IMETHODIMP
nsSchemaModelGroupRef::GetName(nsAString& aName)
{
if (!mModelGroup) {
return NS_ERROR_NOT_INITIALIZED;
}
return mModelGroup->GetName(aName);
}
/* readonly attribute unsigned short compositor; */
NS_IMETHODIMP
nsSchemaModelGroupRef::GetCompositor(PRUint16 *aCompositor)
{
NS_ENSURE_ARG_POINTER(aCompositor);
if (!mModelGroup) {
return NS_ERROR_NOT_INITIALIZED;
}
return mModelGroup->GetCompositor(aCompositor);
}
/* readonly attribute PRUint32 particleCount; */
NS_IMETHODIMP
nsSchemaModelGroupRef::GetParticleCount(PRUint32 *aParticleCount)
{
NS_ENSURE_ARG_POINTER(aParticleCount);
if (!mModelGroup) {
return NS_ERROR_NOT_INITIALIZED;
}
return mModelGroup->GetParticleCount(aParticleCount);
}
/* nsISVSchemaParticle getParticle (in PRUint32 index); */
NS_IMETHODIMP
nsSchemaModelGroupRef::GetParticle(PRUint32 index, nsISVSchemaParticle **_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
if (!mModelGroup) {
return NS_ERROR_NOT_INITIALIZED;
}
return mModelGroup->GetParticle(index, _retval);
}
NS_IMETHODIMP
nsSchemaModelGroupRef::GetElementByName(const nsAString& aName,
nsISVSchemaElement** _retval)
{
NS_ENSURE_ARG_POINTER(_retval);
if (!mModelGroup) {
return NS_ERROR_NOT_INITIALIZED;
}
return mModelGroup->GetElementByName(aName, _retval);
}
////////////////////////////////////////////////////////////
//
// nsSchemaAnyParticle implementation
//
////////////////////////////////////////////////////////////
nsSchemaAnyParticle::nsSchemaAnyParticle(nsSchema* aSchema)
: nsSchemaParticleBase(aSchema), mProcess(PROCESS_STRICT)
{
}
nsSchemaAnyParticle::~nsSchemaAnyParticle()
{
}
NS_IMPL_ISUPPORTS3(nsSchemaAnyParticle,
nsISVSchemaComponent,
nsISVSchemaParticle,
nsISVSchemaAnyParticle)
/* void resolve (in nsISVSchemaErrorHandler aErrorHandler); */
NS_IMETHODIMP
nsSchemaAnyParticle::Resolve(nsISVSchemaErrorHandler* aErrorHandler)
{
return NS_OK;
}
/* void clear (); */
NS_IMETHODIMP
nsSchemaAnyParticle::Clear()
{
return NS_OK;
}
NS_IMETHODIMP
nsSchemaAnyParticle::GetParticleType(PRUint16 *aParticleType)
{
NS_ENSURE_ARG_POINTER(aParticleType);
*aParticleType = nsISVSchemaParticle::PARTICLE_TYPE_ANY;
return NS_OK;
}
NS_IMETHODIMP
nsSchemaAnyParticle::GetName(nsAString& aName)
{
aName.AssignLiteral("any");
return NS_OK;
}
/* readonly attribute unsigned short process; */
NS_IMETHODIMP
nsSchemaAnyParticle::GetProcess(PRUint16 *aProcess)
{
NS_ENSURE_ARG_POINTER(aProcess);
*aProcess = mProcess;
return NS_OK;
}
/* readonly attribute AString namespace; */
NS_IMETHODIMP
nsSchemaAnyParticle::GetNamespace(nsAString & aNamespace)
{
aNamespace.Assign(mNamespace);
return NS_OK;
}
NS_IMETHODIMP
nsSchemaAnyParticle::SetProcess(PRUint16 aProcess)
{
mProcess = aProcess;
return NS_OK;
}
NS_IMETHODIMP
nsSchemaAnyParticle::SetNamespace(const nsAString& aNamespace)
{
mNamespace.Assign(aNamespace);
return NS_OK;
}
////////////////////////////////////////////////////////////
//
// nsSchemaElement implementation
//
////////////////////////////////////////////////////////////
nsSchemaElement::nsSchemaElement(nsSchema* aSchema,
const nsAString& aName)
: nsSchemaParticleBase(aSchema), mName(aName), mFlags(0)
{
}
nsSchemaElement::~nsSchemaElement()
{
}
NS_IMPL_ISUPPORTS3(nsSchemaElement,
nsISVSchemaComponent,
nsISVSchemaParticle,
nsISVSchemaElement)
/* void resolve (in nsISVSchemaErrorHandler aErrorHandler); */
NS_IMETHODIMP
nsSchemaElement::Resolve(nsISVSchemaErrorHandler* aErrorHandler)
{
if (mIsResolved) {
return NS_OK;
}
mIsResolved = PR_TRUE;
nsresult rv = NS_OK;
if (mType && mSchema) {
nsCOMPtr<nsISVSchemaType> type;
rv = mSchema->ResolveTypePlaceholder(aErrorHandler, mType, getter_AddRefs(type));
if (NS_FAILED(rv)) {
return rv;
}
mType = type;
rv = mType->Resolve(aErrorHandler);
}
return rv;
}
/* void clear (); */
NS_IMETHODIMP
nsSchemaElement::Clear()
{
if (mIsCleared) {
return NS_OK;
}
mIsCleared = PR_TRUE;
if (mType) {
mType->Clear();
mType = nsnull;
}
return NS_OK;
}
NS_IMETHODIMP
nsSchemaElement::GetParticleType(PRUint16 *aParticleType)
{
NS_ENSURE_ARG_POINTER(aParticleType);
*aParticleType = nsISVSchemaParticle::PARTICLE_TYPE_ELEMENT;
return NS_OK;
}
NS_IMETHODIMP
nsSchemaElement::GetName(nsAString& aName)
{
aName.Assign(mName);
return NS_OK;
}
/* readonly attribute nsISVSchemaType type; */
NS_IMETHODIMP
nsSchemaElement::GetType(nsISVSchemaType * *aType)
{
NS_ENSURE_ARG_POINTER(aType);
NS_IF_ADDREF(*aType = mType);
return NS_OK;
}
/* readonly attribute AString defaultValue; */
NS_IMETHODIMP
nsSchemaElement::GetDefaultValue(nsAString & aDefaultValue)
{
aDefaultValue.Assign(mDefaultValue);
return NS_OK;
}
/* readonly attribute AString fixedValue; */
NS_IMETHODIMP
nsSchemaElement::GetFixedValue(nsAString & aFixedValue)
{
aFixedValue.Assign(mFixedValue);
return NS_OK;
}
/* readonly attribute boolean nillable; */
NS_IMETHODIMP
nsSchemaElement::GetNillable(PRBool *aNillable)
{
NS_ENSURE_ARG_POINTER(aNillable);
*aNillable = mFlags & nsSchemaElement::NILLABLE;
return NS_OK;
}
/* readonly attribute boolean abstract; */
NS_IMETHODIMP
nsSchemaElement::GetAbstract(PRBool *aAbstract)
{
NS_ENSURE_ARG_POINTER(aAbstract);
*aAbstract = mFlags & nsSchemaElement::ABSTRACT;
return NS_OK;
}
NS_IMETHODIMP
nsSchemaElement::SetType(nsISVSchemaType* aType)
{
NS_ENSURE_ARG_POINTER(aType);
mType = aType;
return NS_OK;
}
NS_IMETHODIMP
nsSchemaElement::SetConstraints(const nsAString& aDefaultValue,
const nsAString& aFixedValue)
{
mDefaultValue.Assign(aDefaultValue);
mFixedValue.Assign(aFixedValue);
return NS_OK;
}
NS_IMETHODIMP
nsSchemaElement::SetFlags(PRInt32 aFlags)
{
mFlags = aFlags;
return NS_OK;
}
NS_IMETHODIMP
nsSchemaElement::GetTargetNamespace(nsAString& aTargetNamespace)
{
if ((mFlags & nsSchemaElement::FORM_QUALIFIED) && mSchema) {
return mSchema->GetTargetNamespace(aTargetNamespace);
}
aTargetNamespace.Truncate();
return NS_OK;
}
////////////////////////////////////////////////////////////
//
// nsSchemaElementRef implementation
//
////////////////////////////////////////////////////////////
nsSchemaElementRef::nsSchemaElementRef(nsSchema* aSchema,
const nsAString& aRef,
const nsAString& aRefNS)
: nsSchemaParticleBase(aSchema), mRef(aRef), mRefNS(aRefNS)
{
}
nsSchemaElementRef::~nsSchemaElementRef()
{
}
NS_IMPL_ISUPPORTS3(nsSchemaElementRef,
nsISVSchemaComponent,
nsISVSchemaParticle,
nsISVSchemaElement)
/* void resolve (in nsISVSchemaErrorHandler aErrorHandler); */
NS_IMETHODIMP
nsSchemaElementRef::Resolve(nsISVSchemaErrorHandler* aErrorHandler)
{
nsresult rv = NS_OK;
if (mIsResolved) {
return NS_OK;
}
mIsResolved = PR_TRUE;
if (!mElement && mSchema) {
if (mRefNS.IsEmpty()) {
mSchema->GetElementByName(mRef, getter_AddRefs(mElement));
} else {
// use the namespace and type
nsCOMPtr<nsISVSchemaCollection> schemaColl;
mSchema->GetCollection(getter_AddRefs(schemaColl));
NS_ENSURE_STATE(schemaColl);
schemaColl->GetElement(mRef, mRefNS, getter_AddRefs(mElement));
}
}
if (mElement) {
rv = mElement->Resolve(aErrorHandler);
}
return rv;
}
/* void clear (); */
NS_IMETHODIMP
nsSchemaElementRef::Clear()
{
if (mIsCleared) {
return NS_OK;
}
mIsCleared = PR_TRUE;
if (mElement) {
mElement->Clear();
mElement = nsnull;
}
return NS_OK;
}
NS_IMETHODIMP
nsSchemaElementRef::GetParticleType(PRUint16 *aParticleType)
{
NS_ENSURE_ARG_POINTER(aParticleType);
*aParticleType = nsISVSchemaParticle::PARTICLE_TYPE_ELEMENT;
return NS_OK;
}
NS_IMETHODIMP
nsSchemaElementRef::GetName(nsAString& aName)
{
if (!mElement) {
return NS_ERROR_NOT_INITIALIZED;
}
return mElement->GetName(aName);
}
/* readonly attribute nsISVSchemaType type; */
NS_IMETHODIMP
nsSchemaElementRef::GetType(nsISVSchemaType * *aType)
{
NS_ENSURE_ARG_POINTER(aType);
if (!mElement) {
return NS_ERROR_NOT_INITIALIZED;
}
return mElement->GetType(aType);
}
/* readonly attribute AString defaultValue; */
NS_IMETHODIMP
nsSchemaElementRef::GetDefaultValue(nsAString & aDefaultValue)
{
if (!mElement) {
return NS_ERROR_NOT_INITIALIZED;
}
return mElement->GetDefaultValue(aDefaultValue);
}
/* readonly attribute AString fixedValue; */
NS_IMETHODIMP
nsSchemaElementRef::GetFixedValue(nsAString & aFixedValue)
{
if (!mElement) {
return NS_ERROR_NOT_INITIALIZED;
}
return mElement->GetFixedValue(aFixedValue);
}
/* readonly attribute boolean nillable; */
NS_IMETHODIMP
nsSchemaElementRef::GetNillable(PRBool *aNillable)
{
NS_ENSURE_ARG_POINTER(aNillable);
if (!mElement) {
return NS_ERROR_NOT_INITIALIZED;
}
return mElement->GetNillable(aNillable);
}
/* readonly attribute boolean abstract; */
NS_IMETHODIMP
nsSchemaElementRef::GetAbstract(PRBool *aAbstract)
{
NS_ENSURE_ARG_POINTER(aAbstract);
if (!mElement) {
return NS_ERROR_NOT_INITIALIZED;
}
return mElement->GetAbstract(aAbstract);
}