📄 typefact.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//+----------------------------------------------------------------------------
//
//
// File: typefact.cpp
//
// Contents:
//
// implementation file
//
//
//
//-----------------------------------------------------------------------------
#include "headers.h"
#include "typefact.h"
#ifdef UNDER_CE
#include "WinCEUtils.h"
#endif
const int c_growSize = 16;
TYPEINFOIDS(ISoapTypeMapperFactory, MSSOAPLib)
BEGIN_INTERFACE_MAP(CTypeMapperFactory)
ADD_IUNKNOWN(CTypeMapperFactory, ISoapTypeMapperFactory)
ADD_INTERFACE(CTypeMapperFactory, ISoapTypeMapperFactory)
ADD_INTERFACE(CTypeMapperFactory, IDispatch)
END_INTERFACE_MAP(CTypeMapperFactory)
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CTypeMapperFactory::CTypeMapperFactory()
//
// parameters:
//
// description:
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
CTypeMapperFactory::CTypeMapperFactory()
{
m_ppCustomMapperInfo = 0;
m_lCacheSize = 0;
m_lNextMapperID = 0;
m_enRevision = enSchemaLast;
// if this fires, we updated the table with checking...
ASSERT(enSchemaLast == enSchema2001);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CTypeMapperFactory::~CTypeMapperFactory()
//
// parameters:
//
// description:
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
CTypeMapperFactory::~CTypeMapperFactory()
{
ULONG ulCount;
CCustomMapperInfo * pCustom;
if (m_ppCustomMapperInfo)
{
// free the custom mappers
for (ulCount = 0; ulCount < (ULONG) m_lNextMapperID; ulCount++)
{
pCustom = m_ppCustomMapperInfo[ulCount];
if (pCustom)
{
delete pCustom;
}
}
delete [] m_ppCustomMapperInfo;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: BOOLEAN CTypeMapperFactory::IsArrayDefinition( IXMLDOMNode *pSchemaNode)
//
// parameters:
//
// description:
// will return TRUE if we recognized an array definition
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOLEAN CTypeMapperFactory::IsArrayDefinition(
IXMLDOMNode *pSchemaNode)
{
CAutoRefc<IXMLDOMNode> pCheck(NULL);
HRESULT hr = S_OK;
XPathState xp;
xp.init(pSchemaNode);
showNode(pSchemaNode);
{
schemaRevisionNr revision;
CAutoFormat autoFormat;
if FAILED(_XSDFindRevision(pSchemaNode, &revision))
revision = enSchemaLast;
CHK(autoFormat.sprintf(L"xmlns:schema='%s'", _XSDSchemaNS(revision)));
CHK (xp.addNamespace(&autoFormat)); //gives us schema:
CHK (xp.addNamespace(g_pwstrXpathDef)); //give us def: wsdl
}
// there are 5 different array scenarios we will check:
// (1) <element><complexType><sequence><element>
// (2) <complexType><sequence><element>
// (3) <element><complexType><element>
// (4) <complexType><complexContent><restriction><attribute>
// (5) <complexType><complexContent><restriction><sequence><attribute>
// as we are in getElement, only 1 + 3 are checked for at this place
// let's check on scenario 1
pSchemaNode->selectSingleNode(L"self::*[schema:complexType[schema:sequence[schema:element[@maxOccurs] and not (schema:element[2])] and not (schema:sequence[2])] and not (schema:complexType[2])]", &pCheck);
if (pCheck)
return TRUE;
// let's check on scenario 3
pSchemaNode->selectSingleNode(L"self::*[schema:complexType[schema:element[@maxOccurs] and not (schema:element[2])] and not (schema:complexType[2])]", &pCheck);
if (pCheck)
return TRUE;
// let's check on scenario 2
pSchemaNode->selectSingleNode(L"self::*[schema:sequence[schema:element[@maxOccurs] and not (schema:element[2])] and not (schema:sequence[2])]", &pCheck);
if (pCheck)
return TRUE;
// let's check on scenario 4
pSchemaNode->selectSingleNode(L"self::*[schema:complexContent[schema:restriction[schema:attribute[@def:arrayType] and not (schema:attribute[2])] and not (schema:restriction[2])] and not (schema:complexContent[2])]", &pCheck);
if (pCheck)
return TRUE;
// let's check on scenario 5
pSchemaNode->selectSingleNode(L"self::*[schema:complexContent[schema:restriction [schema:sequence [schema:element[@maxOccurs] and not(schema:element[2])] and not (schema:sequence[2])] and not (schema:restriction[2])] and not (schema:complexContent[2])]", &pCheck);
if (pCheck)
return TRUE;
Cleanup:
// no array
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT CTypeMapperFactory::getElementMapper(IXMLDOMNode *pSchemaNode, ISoapTypeMapper ** pptypeMapper )
//
// parameters:
//
// description:
// returns a typemapper based on elementnode
//
// returns:
// S_OK if everything is fine
// E_FAIL
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CTypeMapperFactory::getElementMapper(
IXMLDOMNode *pSchemaNode,
ISoapTypeMapper ** pptypeMapper
)
{
HRESULT hr = E_INVALIDARG;
CAutoBSTR bstrElementNameSpace;
CAutoBSTR bstrElementName;
CAutoBSTR bstrTemp;
CAutoBSTR bstrURI;
CAutoBSTR bstrBuffer;
TCHAR achPrefix[_MAX_ATTRIBUTE_LEN];
#ifndef UNDER_CE
TCHAR achName[_MAX_ATTRIBUTE_LEN];
TCHAR achURI[_MAX_ATTRIBUTE_LEN];
#endif
XPathState xp;
#ifndef CE_NO_EXCEPTIONS
try
{
#endif
CHK_BOOL(m_pSchemaDocument, E_FAIL);
CHK(xp.init(m_pSchemaDocument));
CHK(_XSDSetupDefaultXPath(m_pSchemaDocument, m_enRevision));
if (!pSchemaNode)
{
goto Cleanup;
}
if (FAILED(_WSDLUtilFindAttribute(pSchemaNode, _T("name"), &bstrElementName)))
{
CHK(_WSDLUtilFindAttribute(pSchemaNode, _T("ref"), &bstrElementName));
// as we have a REF now, find that node and call myself again
CHK(_WSDLUtilSplitQName(bstrElementName, achPrefix,&bstrBuffer));
if (_tcslen(achPrefix) > 0)
{
// defined in different schema
hr = _XSDFindURIForPrefix(pSchemaNode, achPrefix, &bstrURI);
}
else
{
// get the targetNameSpace attribute
hr = _XSDFindTargetNameSpace(pSchemaNode, &bstrURI);
}
if (FAILED(hr))
{
globalAddError(WSDL_IDS_URIFORQNAMENF, WSDL_IDS_MAPPER, hr, achPrefix, bstrElementName);
goto Cleanup;
}
hr = getElementMapperbyName(bstrBuffer, bstrURI, pptypeMapper );
goto Cleanup;
}
// get the 2 things we need: namespace and name
CHK(_XSDFindTargetNameSpace(pSchemaNode, &bstrElementNameSpace));
// first verify if there is a buildin/custom one for this
hr = findRegisteredTypeMapper(bstrElementName, bstrElementNameSpace, false, pSchemaNode, pptypeMapper);
if (hr == S_FALSE)
{
showNode(pSchemaNode);
if (pSchemaNode)
{
// we have the guy.
hr = _WSDLUtilFindAttribute(pSchemaNode, _T("type"), &bstrTemp);
if (FAILED(hr))
{
// there is the chance we are having an array mapper here
if (IsArrayDefinition(pSchemaNode))
{
// let's assume we have found an array for now
hr = createBuildInMapper(pptypeMapper, pSchemaNode, enXSDarray);
}
else
{
// this could be an element with inline array ... we can recognize this:
CAutoRefc<IXMLDOMNode> pChild(NULL);
pSchemaNode->get_firstChild(&pChild);
if (pChild)
{
if (IsArrayDefinition(pChild))
{
// let's assume we have found an array for now
hr = createBuildInMapper(pptypeMapper, pChild, enXSDarray);
}
}
}
if (FAILED(hr))
{
// NO array, let's try something else, this will create dom mapper as fallback
CHK(checkForXSDSubclassing(pptypeMapper, pSchemaNode));
}
}
else
{
CHK(_WSDLUtilSplitQName(bstrTemp, achPrefix,&bstrBuffer));
hr = _XSDFindURIForPrefix(pSchemaNode, achPrefix, &bstrURI);
if (FAILED(hr))
{
globalAddError(WSDL_IDS_URIFORQNAMENF, WSDL_IDS_MAPPER, hr, achPrefix, bstrTemp);
goto Cleanup;
}
hr = getTypeMapperbyName(bstrBuffer, bstrURI, pptypeMapper );
}
}
else
{
globalAddError(WSDL_IDS_MAPPERNODEFINITION, WSDL_IDS_MAPPER, hr, bstrElementName);
hr = E_FAIL;
}
}
#ifndef CE_NO_EXCEPTIONS
}
catch(...)
{
hr = E_UNEXPECTED;
}
#endif
Cleanup:
ASSERT(hr==S_OK);
return (hr);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT CTypeMapperFactory::getElementMapperbyName(BSTR bstrElementName, BSTR bstrElementNamespace,
// ISoapTypeMapper **ppSoapTypeMapper)
//
// parameters:
//
// description:
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CTypeMapperFactory::getElementMapperbyName(
BSTR bstrElementName,
BSTR bstrElementNamespace,
ISoapTypeMapper **ppSoapTypeMapper
)
{
CAutoRefc<IXMLDOMNode> pTargetNode=0;
CAutoRefc<IXMLDOMNode> pTargetSchema=0;
CAutoFormat autoFormat;;
HRESULT hr=E_FAIL;
XPathState xp;
#ifndef CE_NO_EXCEPTIONS
try
{
#endif
CHK_BOOL(m_pSchemaDocument, E_FAIL);
CHK(xp.init(m_pSchemaDocument));
CHK(_XSDSetupDefaultXPath(m_pSchemaDocument, m_enRevision));
if (_XSDIsPublicSchema(bstrElementNamespace))
{
// wrong: an element declaration has to point to a private schema
hr = E_FAIL;
globalAddError(WSDL_IDS_MAPPERNOSCHEMA, WSDL_IDS_MAPPER, hr, bstrElementNamespace, bstrElementName);
goto Cleanup;
}
else
{
// user schema, look for the node
hr = _XSDLFindTargetSchema(bstrElementNamespace,m_pSchemaDocument, &pTargetSchema);
if (FAILED(hr))
{
globalAddError(WSDL_IDS_MAPPERNOSCHEMA, WSDL_IDS_MAPPER, hr, bstrElementNamespace, bstrElementName);
goto Cleanup;
}
showNode(pTargetSchema);
// now search for the subnode:
CHK(autoFormat.sprintf(_T(".//schema:element[@name=\"%s\"]"), bstrElementName));
pTargetSchema->selectSingleNode(&autoFormat, &pTargetNode);
if (!pTargetNode)
{
globalAddError(WSDL_IDS_MAPPERNODEFINITION, WSDL_IDS_MAPPER, hr, bstrElementName);
hr = E_FAIL;
goto Cleanup;
}
hr = getElementMapper(pTargetNode, ppSoapTypeMapper);
}
#ifndef CE_NO_EXCEPTIONS
}
catch(...)
{
hr = E_UNEXPECTED;
}
#endif
Cleanup:
ASSERT(hr==S_OK);
return (hr);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT CTypeMapperFactory::getTypeMapper( IXMLDOMNode *pSchemaNode, ISoapTypeMapper ** pptypeMapper )
//
// parameters:
//
// description:
// returns a typemapper based on typenode
//
// returns:
// S_OK if everything is fine
// E_FAIL
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CTypeMapperFactory::getTypeMapper(
IXMLDOMNode *pSchemaNode,
ISoapTypeMapper ** pptypeMapper
)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -