/* -*- 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 (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 element = do_QueryInterface(particle); if (element) { nsAutoString name; element->GetName(name); if (name.Equals(aName)) { NS_ADDREF(*aResult = element); return NS_OK; } } else { nsCOMPtr 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 schemaColl; mSchema->GetCollection(getter_AddRefs(schemaColl)); NS_ENSURE_STATE(schemaColl); // get the right schema nsCOMPtr 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 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 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); }