blob: d799525bea6dc6549fdd9533d4cf283e94c69ceb [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*
* XSEC
*
* XKMSStatusImpl := Implementation for Status elements (in KeyBinding)
*
* $Id$
*
*/
// XSEC Includes
#include <xsec/framework/XSECDefs.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xsec/framework/XSECEnv.hpp>
#ifdef XSEC_XKMS_ENABLED
#include "../../utils/XSECDOMUtils.hpp"
#include "XKMSStatusImpl.hpp"
#include <xsec/xkms/XKMSConstants.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
XERCES_CPP_NAMESPACE_USE
// --------------------------------------------------------------------------------
// Construct/Destruct
// --------------------------------------------------------------------------------
XKMSStatusImpl::XKMSStatusImpl(
const XSECEnv * env) :
mp_env(env),
mp_statusElement(NULL) {
m_statusValue = XKMSStatus::StatusUndefined;
StatusValue i;
StatusReason j;
/* Clean out status codes */
for (i = Indeterminate ; i > StatusUndefined; i = (StatusValue)(i-1)) {
for (j = XKMSStatus::Signature; j != XKMSStatus::ReasonUndefined; j = (XKMSStatus::StatusReason) (j-1)) {
m_statusReasons[i-1][j-1] = NULL;
}
}
}
XKMSStatusImpl::XKMSStatusImpl(
const XSECEnv * env,
XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * node) :
mp_env(env),
mp_statusElement(node) {
m_statusValue = XKMSStatus::StatusUndefined;
StatusValue i;
StatusReason j;
/* Clean out status codes */
for (i = Indeterminate ; i > StatusUndefined; i = (StatusValue)(i-1)) {
for (j = XKMSStatus::Signature; j != XKMSStatus::ReasonUndefined; j = (XKMSStatus::StatusReason) (j-1)) {
m_statusReasons[i-1][j-1] = NULL;
}
}
}
XKMSStatusImpl::~XKMSStatusImpl() {
}
// --------------------------------------------------------------------------------
// Load
// --------------------------------------------------------------------------------
void XKMSStatusImpl::load() {
if (mp_statusElement == NULL) {
// Attempt to load an empty element
throw XSECException(XSECException::StatusError,
"XKMSStatus::load - called on empty DOM");
}
/* Load the StatusValue attribute */
mp_statusValueAttr =
mp_statusElement->getAttributeNodeNS(NULL, XKMSConstants::s_tagStatusValue);
/* Decode as appropriate*/
if (mp_statusValueAttr == NULL) {
// Attempt to load an empty element
throw XSECException(XSECException::StatusError,
"XKMSStatus::load - No StatusValue attribute found");
}
const XMLCh * res = mp_statusValueAttr->getNodeValue();
// This is actually an QName, but we cheat and find the ':' character by hand
// without actually checking the qualifier.
// TODO - CHECK the qualifier.
int res2 = XMLString::indexOf(res, chPound);
if (res2 == -1 || XMLString::compareNString(res, XKMSConstants::s_unicodeStrURIXKMS, res2)) {
throw XSECException(XSECException::StatusError,
"XKMSStatus::load - StatusValue not in XKMS Name Space");
}
res = &res[res2+1];
for (m_statusValue = XKMSStatus::Indeterminate;
m_statusValue > XKMSStatus::StatusUndefined;
m_statusValue = (XKMSStatus::StatusValue) (m_statusValue-1)) {
if (strEquals(XKMSConstants::s_tagStatusValueCodes[m_statusValue], res))
break;
}
if (m_statusValue == XKMSStatus::StatusUndefined) {
throw XSECException(XSECException::StatusError,
"XKMSStatus::load - Unknown StatusValue provided");
}
/* Now we need to run through the status values */
DOMElement * e = findFirstElementChild(mp_statusElement);
while (e != NULL) {
const XMLCh * vs = getXKMSLocalName(e);
StatusValue v;
if (strEquals(vs, XKMSConstants::s_tagValidReason)) {
v = Valid;
}
else if (strEquals(vs, XKMSConstants::s_tagInvalidReason)) {
v = Invalid;
}
else if (strEquals(vs, XKMSConstants::s_tagIndeterminateReason)) {
v = Indeterminate;
}
else {
throw XSECException(XSECException::StatusError,
"XKMSStatus::load - Unknown Reason element");
}
DOMNode *t = findFirstChildOfType(e, DOMNode::TEXT_NODE);
if (t == NULL) {
throw XSECException(XSECException::StatusError,
"XKMSStatus::load - Expected text node child of reason element");
}
/* Strip out the URI prefix */
const XMLCh * reason = t->getNodeValue();
int res = XMLString::indexOf(reason, chPound);
if (res == -1 || XMLString::compareNString(reason, XKMSConstants::s_unicodeStrURIXKMS, res)) {
throw XSECException(XSECException::StatusError,
"XKMSStatus::load - StatusReason not in XKMS Name Space");
}
reason = &reason[res+1];
/* Found out what we are! */
XKMSStatus::StatusReason i;
for (i = XKMSStatus::Signature; i != XKMSStatus::ReasonUndefined; i = (XKMSStatus::StatusReason) (i-1)) {
if (strEquals(XKMSConstants::s_tagStatusReasonCodes[i], reason))
break;
}
if (i == XKMSStatus::ReasonUndefined) {
throw XSECException(XSECException::StatusError,
"XKMSStatus::load - Unknown StatusReason");
}
m_statusReasons[v-1][i-1] = e;
e = findNextElementChild(e);
}
}
// --------------------------------------------------------------------------------
// Create Blank Status
// --------------------------------------------------------------------------------
DOMElement * XKMSStatusImpl::createBlankStatus(StatusValue status) {
// Get some setup values
safeBuffer str;
DOMDocument *doc = mp_env->getParentDocument();
const XMLCh * prefix = mp_env->getXKMSNSPrefix();
makeQName(str, prefix, XKMSConstants::s_tagStatus);
mp_statusElement = doc->createElementNS(XKMSConstants::s_unicodeStrURIXKMS,
str.rawXMLChBuffer());
mp_env->doPrettyPrint(mp_statusElement);
/* Now add the StatusValue element */
str.sbXMLChIn(XKMSConstants::s_unicodeStrURIXKMS);
str.sbXMLChCat(XKMSConstants::s_tagStatusValueCodes[status]);
mp_statusElement->setAttributeNS(NULL,
XKMSConstants::s_tagStatusValue,
str.rawXMLChBuffer());
mp_statusValueAttr =
mp_statusElement->getAttributeNodeNS(NULL, XKMSConstants::s_tagStatusValue);
m_statusValue = status;
return mp_statusElement;
}
// --------------------------------------------------------------------------------
// Get methods
// --------------------------------------------------------------------------------
/* Getter Interface Methods */
XKMSStatus::StatusValue XKMSStatusImpl::getStatusValue(void) const {
return m_statusValue;
}
bool XKMSStatusImpl::getStatusReason(StatusValue status, StatusReason reason) const {
if (status == StatusUndefined || reason == ReasonUndefined) {
throw XSECException(XSECException::StatusError,
"XKMSStatus::getStatusReason - status or reason undefined");
}
return (m_statusReasons[status-1][reason-1] != NULL);
}
// --------------------------------------------------------------------------------
// Set methods
// --------------------------------------------------------------------------------
void XKMSStatusImpl::setStatusReason(StatusValue status, StatusReason reason, bool value) {
if (status == StatusUndefined || reason == ReasonUndefined) {
throw XSECException(XSECException::StatusError,
"XKMSStatus::setStatusReason - status or reason undefined");
}
if ((m_statusReasons[status-1][reason-1] != NULL) == value)
return;
/* Delete if necessary */
if (value == false) {
DOMNode * c = m_statusReasons[status-1][reason-1];
mp_statusElement->removeChild(c);
c->release();
m_statusReasons[status-1][reason-1] = NULL;
return;
}
/* Find a previously found element to insert before*/
DOMNode * found = NULL;
m_statusValue = XKMSStatus::StatusUndefined;
StatusValue i;
StatusReason j = XKMSStatus::Signature;
/* Clean out status codes */
for (i = Indeterminate ; i > StatusUndefined && !(i == status && j == reason); i = (StatusValue)(i-1)) {
for (j = XKMSStatus::Signature; j != XKMSStatus::ReasonUndefined && !(i == status && j == reason); j = (XKMSStatus::StatusReason) (j-1)) {
if (m_statusReasons[i-1][j-1] != NULL)
found = m_statusReasons[i-1][j-1];
}
}
/* Now lets create our new element and its text child */
safeBuffer str;
DOMDocument *doc = mp_env->getParentDocument();
// str.sbXMLChIn(XKMSConstants::s_unicodeStrURIXKMS);
const XMLCh * prefix = mp_env->getXKMSNSPrefix();
if (status == Valid) {
makeQName(str, prefix, XKMSConstants::s_tagValidReason);
}
else if (status == Invalid) {
makeQName(str, prefix, XKMSConstants::s_tagInvalidReason);
}
else {
makeQName(str, prefix, XKMSConstants::s_tagIndeterminateReason);
}
DOMElement * e = doc->createElementNS(XKMSConstants::s_unicodeStrURIXKMS,
str.rawXMLChBuffer());
/* Create the text node child */
str.sbXMLChIn(XKMSConstants::s_unicodeStrURIXKMS);
str.sbXMLChCat(XKMSConstants::s_tagStatusReasonCodes[reason]);
e->appendChild(doc->createTextNode(str.rawXMLChBuffer()));
/* Insert at correct place */
if (found == NULL) {
mp_statusElement->appendChild(e);
mp_env->doPrettyPrint(mp_statusElement);
}
else {
mp_statusElement->insertBefore(e, found);
if (mp_env->getPrettyPrintFlag() == true)
mp_statusElement->insertBefore(doc->createTextNode(DSIGConstants::s_unicodeStrNL), found);
}
m_statusReasons[status-1][reason-1] = e;
}
#endif /* XSEC_XKMS_ENABLED */