/**
* Extract the information from a LOCK DAV response and create the
* corresponding Lock object.
*
* @param \DOMElement $response
* @param bool $sessionOwning whether the current session is owning the lock (aka
* we created it in this request)
* @param string $path the owning node path, if we created this node
*
* @return \Jackalope\Lock\Lock
*/
protected function generateLockFromDavResponse($response, $sessionOwning = false, $path = null)
{
$lock = new Lock();
$lockDom = $this->getRequiredDomElementByTagNameNS($response, self::NS_DAV, 'activelock', "No lock received");
// Check this is not a transaction lock
$type = $this->getRequiredDomElementByTagNameNS($lockDom, self::NS_DAV, 'locktype', 'No lock type received');
if (!$type->childNodes->length) {
$tagName = $type->childNodes->item(0)->localName;
if ($tagName !== 'write') {
throw new RepositoryException("Invalid lock type '{$tagName}'");
}
}
// Extract the lock scope
$scopeDom = $this->getRequiredDomElementByTagNameNS($lockDom, self::NS_DAV, 'lockscope', 'No lock scope in the received lock');
if ($this->getRequiredDomElementByTagNameNS($scopeDom, self::NS_DCR, 'exclusive-session-scoped')) {
$lock->setIsSessionScoped(true);
} elseif ($this->getRequiredDomElementByTagNameNS($scopeDom, self::NS_DAV, 'exclusive')) {
$lock->setIsSessionScoped(false);
} else {
// Unknown XML found in the <D:lockscope> tag
throw new RepositoryException('Invalid lock scope received: ' . $response->saveHTML($scopeDom));
}
// Extract the depth
$depthDom = $this->getRequiredDomElementByTagNameNS($lockDom, self::NS_DAV, 'depth', 'No depth in the received lock');
$lock->setIsDeep($depthDom->textContent === 'infinity');
// Extract the owner
$ownerDom = $this->getRequiredDomElementByTagNameNS($lockDom, self::NS_DAV, 'owner', 'No owner in the received lock');
$lock->setLockOwner($ownerDom->textContent);
// Extract the lock token
$tokenDom = $this->getRequiredDomElementByTagNameNS($lockDom, self::NS_DAV, 'href', 'No lock token in the received lock');
$lock->setLockToken($tokenDom->textContent);
// Extract the timeout
$timeoutDom = $this->getRequiredDomElementByTagNameNS($lockDom, self::NS_DAV, 'timeout', 'No lock timeout in the received lock');
$lock->setExpireTime($this->parseTimeout($timeoutDom->nodeValue));
$lock->setIsLockOwningSession($sessionOwning);
if (null !== $path) {
$lock->setNodePath($path);
} else {
throw new NotImplementedException('get the lock owning node or provide Lock with info so it can get it when requested');
// TODO: get the lock owning node
// Note that $n->getLock()->getNode() (where $n is a locked node) will only
// return $n if $n is the lock holder. If $n is in the subgraph of the lock
// holder, $h, then this call will return $h.
}
return $lock;
}