Back to index

lightning-sunbird  0.9+nobinonly
nsSchemaComplexType.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications.
00019  * Portions created by the Initial Developer are Copyright (C) 2001
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Vidur Apparao <vidur@netscape.com> (original author)
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * 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 "nsSchemaPrivate.h"
00040 
00042 //
00043 // nsSchemaComplexType implementation
00044 //
00046 nsSchemaComplexType::nsSchemaComplexType(nsSchema* aSchema,
00047                                          const nsAString& aName,
00048                                          PRBool aAbstract)
00049   : nsSchemaComponentBase(aSchema), mName(aName), mAbstract(aAbstract),
00050     mContentModel(CONTENT_MODEL_ELEMENT_ONLY), 
00051     mDerivation(DERIVATION_SELF_CONTAINED)
00052 {
00053 }
00054 
00055 nsSchemaComplexType::~nsSchemaComplexType()
00056 {
00057 }
00058 
00059 NS_IMPL_ISUPPORTS3_CI(nsSchemaComplexType, 
00060                       nsISchemaComponent,
00061                       nsISchemaType,
00062                       nsISchemaComplexType)
00063 
00064 /* void resolve (in nsIWebServiceErrorHandler* aErrorHandler); */
00065 NS_IMETHODIMP
00066 nsSchemaComplexType::Resolve(nsIWebServiceErrorHandler* aErrorHandler)
00067 {
00068   if (mIsResolved) {
00069     return NS_OK;
00070   }
00071 
00072   mIsResolved = PR_TRUE;
00073   nsresult rv;
00074   PRUint32 i, count;
00075 
00076   count = mAttributes.Count();
00077   for (i = 0; i < count; ++i) {
00078     rv = mAttributes.ObjectAt(i)->Resolve(aErrorHandler);
00079     if (NS_FAILED(rv)) {
00080       nsAutoString attrName;
00081       nsresult rv1 = mAttributes.ObjectAt(i)->GetName(attrName);
00082       NS_ENSURE_SUCCESS(rv1, rv1);
00083 
00084       nsAutoString errorMsg;
00085       errorMsg.AppendLiteral("Failure resolving schema complex type, ");
00086       errorMsg.AppendLiteral("cannot resolve attribute \"");
00087       errorMsg.Append(attrName);
00088       errorMsg.AppendLiteral("\"");
00089       
00090       NS_SCHEMALOADER_FIRE_ERROR(rv, errorMsg);
00091 
00092       return rv;
00093     }
00094   }
00095 
00096   if (!mSchema) {
00097     return NS_ERROR_FAILURE;
00098   }
00099 
00100   nsCOMPtr<nsISchemaType> type;
00101   if (mBaseType) {
00102     rv = mSchema->ResolveTypePlaceholder(aErrorHandler, mBaseType, getter_AddRefs(type));
00103     if (NS_FAILED(rv)) {
00104       return NS_ERROR_FAILURE;
00105     }
00106     mBaseType = type;
00107     rv = mBaseType->Resolve(aErrorHandler);
00108     if (NS_FAILED(rv)) {
00109       nsAutoString baseStr;
00110       nsresult rv1 = type->GetName(baseStr);
00111       NS_ENSURE_SUCCESS(rv1, rv1);
00112 
00113       nsAutoString errorMsg;
00114       errorMsg.AppendLiteral("Failure resolving schema complex type, ");
00115       errorMsg.AppendLiteral("cannot resolve base type \"");
00116       errorMsg.Append(baseStr);
00117       errorMsg.AppendLiteral("\"");
00118 
00119       NS_SCHEMALOADER_FIRE_ERROR(rv, errorMsg);
00120       return NS_ERROR_FAILURE;
00121     }
00122   }
00123     
00124   if (mSimpleBaseType) {
00125     rv = mSchema->ResolveTypePlaceholder(aErrorHandler, mSimpleBaseType, 
00126                                          getter_AddRefs(type));
00127     if (NS_FAILED(rv)) {
00128       return NS_ERROR_FAILURE;
00129     }
00130 
00131     mSimpleBaseType = do_QueryInterface(type);
00132 
00133     // mSimpleBaseType could become a complex type under certain conditions
00134     // (simple content that restricts a complex type, which itself is a
00135     // simple content).  So if we can't QI to a simple type, get the simple
00136     // base type if it is a complex type.
00137     if (!mSimpleBaseType) {
00138       nsCOMPtr<nsISchemaComplexType> complexType = do_QueryInterface(type);
00139       if (complexType) {
00140         complexType->GetSimpleBaseType(getter_AddRefs(mSimpleBaseType));
00141       }
00142     }
00143 
00144     if (!mSimpleBaseType) {
00145       return NS_ERROR_FAILURE;
00146     }
00147     rv = mSimpleBaseType->Resolve(aErrorHandler);
00148     if (NS_FAILED(rv)) {
00149       return NS_ERROR_FAILURE;
00150     }
00151   }
00152 
00153   if (mModelGroup) {
00154     rv = mModelGroup->Resolve(aErrorHandler);
00155     if (NS_FAILED(rv)) {
00156       nsAutoString modelName;
00157       nsresult rv1 = mModelGroup->GetName(modelName);
00158       NS_ENSURE_SUCCESS(rv1, rv1);
00159 
00160       nsAutoString errorMsg;
00161       errorMsg.AppendLiteral("Failure resolving schema complex type, ");
00162       errorMsg.AppendLiteral("cannot resolve model group \"");
00163       errorMsg.Append(modelName);
00164       errorMsg.AppendLiteral("\"");
00165 
00166       NS_SCHEMALOADER_FIRE_ERROR(rv, errorMsg);
00167 
00168       return NS_ERROR_FAILURE;
00169     }
00170   }
00171 
00172   if (mArrayInfo) {
00173     nsCOMPtr<nsISchemaType> placeHolder;
00174     mArrayInfo->GetType(getter_AddRefs(placeHolder));
00175     if (placeHolder) {
00176       PRUint16 schemaType;
00177       placeHolder->GetSchemaType(&schemaType);
00178       if (schemaType == nsISchemaType::SCHEMA_TYPE_PLACEHOLDER) {
00179         rv = mSchema->ResolveTypePlaceholder(aErrorHandler, placeHolder, getter_AddRefs(type));
00180         if (NS_FAILED(rv)) {
00181           return NS_ERROR_FAILURE;
00182         }
00183         rv = type->Resolve(aErrorHandler);
00184         if (NS_FAILED(rv)) {
00185           return NS_ERROR_FAILURE;
00186         }
00187         SetArrayInfo(type, mArrayInfo->GetDimension());
00188       }
00189       else {
00190          rv = placeHolder->Resolve(aErrorHandler);
00191         if (NS_FAILED(rv)) {
00192           return NS_ERROR_FAILURE;
00193         }
00194       }
00195     } 
00196   }
00197 
00198   return NS_OK;
00199 }
00200 
00201 /* void clear (); */
00202 NS_IMETHODIMP
00203 nsSchemaComplexType::Clear()
00204 {
00205   if (mIsCleared) {
00206     return NS_OK;
00207   }
00208 
00209   mIsCleared = PR_TRUE;
00210   if (mBaseType) {
00211     mBaseType->Clear();
00212     mBaseType = nsnull;
00213   }
00214   if (mSimpleBaseType) {
00215     mSimpleBaseType->Clear();
00216     mSimpleBaseType = nsnull;
00217   }
00218   if (mModelGroup) {
00219     mModelGroup->Clear();
00220     mModelGroup = nsnull;
00221   }
00222 
00223   PRUint32 i, count;
00224   count = mAttributes.Count();
00225   for (i = 0; i < count; ++i) {
00226     mAttributes.ObjectAt(i)->Clear();
00227   }
00228   mAttributes.Clear();
00229   mAttributesHash.Clear();
00230 
00231   return NS_OK;
00232 }
00233 
00234 /* readonly attribute wstring name; */
00235 NS_IMETHODIMP
00236 nsSchemaComplexType::GetName(nsAString& aName)
00237 {
00238   aName.Assign(mName);
00239   
00240   return NS_OK;
00241 }
00242 
00243 /* readonly attribute unsigned short schemaType; */
00244 NS_IMETHODIMP
00245 nsSchemaComplexType::GetSchemaType(PRUint16 *aSchemaType)
00246 {
00247   NS_ENSURE_ARG_POINTER(aSchemaType);
00248 
00249   *aSchemaType = nsISchemaType::SCHEMA_TYPE_COMPLEX;
00250 
00251   return NS_OK;
00252 }
00253 
00254 /* readonly attribute unsigned short contentModel; */
00255 NS_IMETHODIMP
00256 nsSchemaComplexType::GetContentModel(PRUint16 *aContentModel)
00257 {
00258   NS_ENSURE_ARG_POINTER(aContentModel);
00259   
00260   *aContentModel = mContentModel;
00261   
00262   return NS_OK;
00263 }
00264 
00265 /* readonly attribute unsigned short derivation; */
00266 NS_IMETHODIMP
00267 nsSchemaComplexType::GetDerivation(PRUint16 *aDerivation)
00268 {
00269   NS_ENSURE_ARG_POINTER(aDerivation);
00270 
00271   *aDerivation = mDerivation;
00272 
00273   return NS_OK;
00274 }
00275 
00276 /* readonly attribute nsISchemaType baseType; */
00277 NS_IMETHODIMP
00278 nsSchemaComplexType::GetBaseType(nsISchemaType * *aBaseType)
00279 {
00280   NS_ENSURE_ARG_POINTER(aBaseType);
00281 
00282   NS_IF_ADDREF(*aBaseType = mBaseType);
00283 
00284   return NS_OK;
00285 }
00286 
00287 /* readonly attribute nsISchemaSimpleType simplBaseType; */
00288 NS_IMETHODIMP
00289 nsSchemaComplexType::GetSimpleBaseType(nsISchemaSimpleType * *aSimpleBaseType)
00290 {
00291   NS_ENSURE_ARG_POINTER(aSimpleBaseType);
00292 
00293   NS_IF_ADDREF(*aSimpleBaseType = mSimpleBaseType);
00294 
00295   return NS_OK;
00296 }
00297 
00298 /* readonly attribute nsISchemaModelGroup modelGroup; */
00299 NS_IMETHODIMP
00300 nsSchemaComplexType::GetModelGroup(nsISchemaModelGroup * *aModelGroup)
00301 {
00302   NS_ENSURE_ARG_POINTER(aModelGroup);
00303 
00304   NS_IF_ADDREF(*aModelGroup = mModelGroup);
00305 
00306   return NS_OK;
00307 }
00308 
00309 /* readonly attribute PRUint32 attributeCount; */
00310 NS_IMETHODIMP
00311 nsSchemaComplexType::GetAttributeCount(PRUint32 *aAttributeCount)
00312 {
00313   NS_ENSURE_ARG_POINTER(aAttributeCount);
00314 
00315   *aAttributeCount = mAttributes.Count();
00316 
00317   return NS_OK;
00318 }
00319 
00320 /* nsISchemaAttributeComponent getAttributeByIndex (in PRUint32 index); */
00321 NS_IMETHODIMP
00322 nsSchemaComplexType::GetAttributeByIndex(PRUint32 aIndex, 
00323                                          nsISchemaAttributeComponent** aResult)
00324 {
00325   NS_ENSURE_ARG_POINTER(aResult);
00326 
00327   if (aIndex >= (PRUint32)mAttributes.Count()) {
00328     return NS_ERROR_FAILURE;
00329   }
00330 
00331   NS_ADDREF(*aResult = mAttributes.ObjectAt(aIndex));
00332 
00333   return NS_OK;
00334 }
00335 
00336 /* nsISchemaAttributeComponent getAttributeByName (in AString name); */
00337 NS_IMETHODIMP
00338 nsSchemaComplexType::GetAttributeByName(const nsAString& aName, 
00339                                         nsISchemaAttributeComponent** aResult)
00340 {
00341   NS_ENSURE_ARG_POINTER(aResult);
00342 
00343   mAttributesHash.Get(aName, aResult);
00344 
00345   return NS_OK;
00346 }
00347 
00348 /* readonly attribute boolean abstract; */
00349 NS_IMETHODIMP
00350 nsSchemaComplexType::GetAbstract(PRBool *aAbstract)
00351 {
00352   NS_ENSURE_ARG_POINTER(aAbstract);
00353 
00354   *aAbstract = mAbstract;
00355   
00356   return NS_OK;
00357 }
00358 
00359 /* readonly attribute boolean isArray; */
00360 NS_IMETHODIMP
00361 nsSchemaComplexType::GetIsArray(PRBool* aIsArray) 
00362 {
00363   NS_ENSURE_ARG_POINTER(aIsArray);
00364 
00365   nsCOMPtr<nsISchemaComplexType> complexBase = do_QueryInterface(mBaseType);
00366   if (complexBase) {
00367     return complexBase->GetIsArray(aIsArray);
00368   }
00369 
00370   *aIsArray = PR_FALSE;
00371 
00372   return NS_OK;
00373 }
00374 
00375 /* readonly attribute nsISchemaType arrayType; */
00376 NS_IMETHODIMP
00377 nsSchemaComplexType::GetArrayType(nsISchemaType** aArrayType)
00378 {
00379   NS_ENSURE_ARG_POINTER(aArrayType);
00380 
00381   *aArrayType = nsnull;
00382   if (mArrayInfo) {
00383     mArrayInfo->GetType(aArrayType);
00384   }
00385   else {
00386     nsCOMPtr<nsISchemaComplexType> complexBase = do_QueryInterface(mBaseType);
00387     if (complexBase) {
00388       return complexBase->GetArrayType(aArrayType);
00389     }
00390   }
00391 
00392   return NS_OK;
00393 }
00394 
00395 /* readonly attribute PRUint32 arrayDimension; */
00396 NS_IMETHODIMP
00397 nsSchemaComplexType::GetArrayDimension(PRUint32* aDimension)
00398 {
00399   NS_ENSURE_ARG_POINTER(aDimension);
00400 
00401   *aDimension = 0;
00402   if (mArrayInfo) {
00403     *aDimension = mArrayInfo->GetDimension();
00404   }
00405   else {
00406     nsCOMPtr<nsISchemaComplexType> complexBase = do_QueryInterface(mBaseType);
00407     if (complexBase) {
00408       return complexBase->GetArrayDimension(aDimension);
00409     }
00410   }
00411 
00412   return NS_OK;
00413 }
00414 
00415 NS_IMETHODIMP
00416 nsSchemaComplexType::SetContentModel(PRUint16 aContentModel)
00417 {
00418   mContentModel = aContentModel;
00419 
00420   return NS_OK;
00421 }
00422 
00423 NS_IMETHODIMP
00424 nsSchemaComplexType::SetDerivation(PRUint16 aDerivation, 
00425                                    nsISchemaType* aBaseType)
00426 {
00427   mDerivation = aDerivation;
00428   mBaseType = aBaseType;
00429 
00430   return NS_OK;
00431 }
00432 
00433 NS_IMETHODIMP
00434 nsSchemaComplexType::SetSimpleBaseType(nsISchemaSimpleType* aSimpleBaseType)
00435 {
00436   mSimpleBaseType = aSimpleBaseType;
00437 
00438   return NS_OK;
00439 }
00440 
00441 NS_IMETHODIMP
00442 nsSchemaComplexType::SetModelGroup(nsISchemaModelGroup* aModelGroup)
00443 {
00444   mModelGroup = aModelGroup;
00445 
00446   return NS_OK;
00447 }
00448 
00449 NS_IMETHODIMP
00450 nsSchemaComplexType::AddAttribute(nsISchemaAttributeComponent* aAttribute)
00451 {
00452   NS_ENSURE_ARG_POINTER(aAttribute);
00453 
00454   nsAutoString name;
00455   aAttribute->GetName(name);
00456 
00457   mAttributes.AppendObject(aAttribute);
00458   mAttributesHash.Put(name, aAttribute);
00459 
00460   return NS_OK;  
00461 }
00462 
00463 NS_IMETHODIMP
00464 nsSchemaComplexType::SetArrayInfo(nsISchemaType* aType, PRUint32 aDimension)
00465 {
00466   mArrayInfo = new nsComplexTypeArrayInfo(aType, aDimension);
00467 
00468   return mArrayInfo ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
00469 }