This class handles the communication between Jackalope and Jackrabbit over Davex. Once the login method has been called, the workspace is set and can not be changed anymore. We make one exception to the rule that nothing may be cached in the transport: Repository descriptors are considered immutable and cached (because they are also used in startup to check the backend version is compatible).
Author: Christian Stocker (chregu@liip.ch)
Author: David Buchmann (david@liip.ch)
Author: Tobias Ebnöther (ebi@liip.ch)
Author: Roland Schilter (roland.schilter@liip.ch)
Author: Uwe Jäger (uwej711@googlemail.com)
Author: Lukas Kahwe Smith (smith@pooteeweet.org)
Author: Daniel Barsotti (daniel.barsotti@liip.ch)
Author: Markus Schmucker (markus.sr@gmx.net)
Inheritance: extends Jackalope\Transport\BaseTransport, implements Jackalope\Transport\QueryInterface, implements Jackalope\Transport\PermissionInterface, implements Jackalope\Transport\WritingInterface, implements Jackalope\Transport\VersioningInterface, implements Jackalope\Transport\NodeTypeCndManagementInterface, implements Jackalope\Transport\LockingInterface, implements Jackalope\Transport\ObservationInterface, implements Jackalope\Transport\WorkspaceManagementInterface
 /**
  * {@inheritDoc}
  */
 public function deleteWorkspace($name)
 {
     $this->transport->deleteWorkspace($name);
 }
Ejemplo n.º 2
0
 /**
  * Handles errors caused by singleRequest and multiRequest
  *
  * For transport level errors, tries to figure out what went wrong to
  * throw the most appropriate exception.
  *
  * @param curl   $curl
  * @param string $response the response body
  * @param int    $httpCode the http response code
  *
  * @throws NoSuchWorkspaceException if it was not possible to reach the server (resolve host or connect)
  * @throws ItemNotFoundException    if the object was not found
  * @throws RepositoryException      on any other error.
  * @throws PathNotFoundException    if the path was not found (server returned 404 without xml response)
  */
 protected function handleError(curl $curl, $response, $httpCode)
 {
     // first: check if the backend is too old for us
     if (!self::$versionChecked) {
         // avoid endless loops.
         self::$versionChecked = true;
         try {
             // getting the descriptors triggers a version check
             $this->client->getRepositoryDescriptors();
         } catch (\Exception $e) {
             if ($e instanceof \PHPCR\UnsupportedRepositoryOperationException) {
                 throw $e;
             }
             //otherwise ignore exception here as to not confuse what happened
         }
     }
     switch ($curl->errno()) {
         case CURLE_COULDNT_RESOLVE_HOST:
         case CURLE_COULDNT_CONNECT:
             $info = $curl->getinfo();
             throw new NoSuchWorkspaceException($curl->error() . ' "' . $info['url'] . '"');
         case CURLE_RECV_ERROR:
             throw new RepositoryException(sprintf('CURLE_RECV_ERROR (errno 56) encountered. This has been known to happen intermittently with ' . 'some versions of libcurl (see https://github.com/jackalope/jackalope-jackrabbit/issues/89). ' . 'You can use the "jackalope.jackrabbit_force_http_version_10" option to force HTTP 1.0 as a workaround'));
     }
     // use XML error response if it's there
     if (substr($response, 0, 2) === '<?') {
         $dom = new DOMDocument();
         $dom->loadXML($response);
         $err = $dom->getElementsByTagNameNS(Client::NS_DCR, 'exception');
         if ($err->length > 0) {
             $err = $err->item(0);
             $errClass = $err->getElementsByTagNameNS(Client::NS_DCR, 'class')->item(0)->textContent;
             $errMsg = $err->getElementsByTagNameNS(Client::NS_DCR, 'message')->item(0)->textContent;
             $exceptionMsg = 'HTTP ' . $httpCode . ': ' . $errMsg;
             switch ($errClass) {
                 case 'javax.jcr.NoSuchWorkspaceException':
                     throw new NoSuchWorkspaceException($exceptionMsg);
                 case 'javax.jcr.nodetype.NoSuchNodeTypeException':
                     throw new NoSuchNodeTypeException($exceptionMsg);
                 case 'javax.jcr.ItemNotFoundException':
                     throw new ItemNotFoundException($exceptionMsg);
                 case 'javax.jcr.nodetype.ConstraintViolationException':
                     throw new ConstraintViolationException($exceptionMsg);
                 case 'javax.jcr.ReferentialIntegrityException':
                     throw new ReferentialIntegrityException($exceptionMsg);
                     //TODO: Two more errors needed for Transactions. How does the corresponding Jackrabbit response look like?
                     // javax.transaction.RollbackException => \PHPCR\Transaction\RollbackException
                     // java.lang.SecurityException => \PHPCR\AccessDeniedException
                     //TODO: map more errors here?
                 //TODO: Two more errors needed for Transactions. How does the corresponding Jackrabbit response look like?
                 // javax.transaction.RollbackException => \PHPCR\Transaction\RollbackException
                 // java.lang.SecurityException => \PHPCR\AccessDeniedException
                 //TODO: map more errors here?
                 default:
                     // try to generically "guess" the right exception class name
                     $class = substr($errClass, strlen('javax.jcr.'));
                     $class = explode('.', $class);
                     array_walk($class, function (&$ns) {
                         $ns = ucfirst(str_replace('nodetype', 'NodeType', $ns));
                     });
                     $class = '\\PHPCR\\' . implode('\\', $class);
                     if (class_exists($class)) {
                         throw new $class($exceptionMsg);
                     }
                     throw new RepositoryException($exceptionMsg . " ({$errClass})");
             }
         }
     }
     if (401 == $httpCode) {
         throw new LoginException("HTTP 401 Unauthorized\n" . $this->getShortErrorString());
     }
     if (404 == $httpCode) {
         throw new PathNotFoundException("HTTP 404 Path Not Found: {$this->method} \n" . $this->getShortErrorString());
     }
     if (405 == $httpCode) {
         throw new HTTPErrorException("HTTP 405 Method Not Allowed: {$this->method} \n" . $this->getShortErrorString(), 405);
     }
     if (412 == $httpCode) {
         throw new LockException("Unable to lock the non-lockable node '" . reset($this->uri) . "\n" . $this->getShortErrorString());
     }
     if ($httpCode >= 500) {
         $msg = "HTTP {$httpCode} Error from backend on: {$this->method} \n" . $this->getLongErrorString($curl, $response);
         try {
             $workspaceUri = array($this->client->getWorkSpaceUri());
             if (!$this->errorHandlingMode && ($workspaceUri !== $this->uri || self::GET !== $this->method)) {
                 $this->errorHandlingMode = true;
                 $this->setUri($workspaceUri);
                 $this->setMethod(self::GET);
                 $this->executeDom();
             }
         } catch (PathNotFoundException $e) {
             $msg = "Error likely caused by incorrect server URL configuration '" . reset($this->uri) . "' resulted in:\n{$msg}";
         }
         $this->errorHandlingMode = false;
         throw new RepositoryException($msg);
     }
     $curlError = $curl->error();
     $msg = "Unexpected error: \nCURL Error: {$curlError} \nResponse (HTTP {$httpCode}): {$this->method} \n" . $this->getLongErrorString($curl, $response);
     throw new RepositoryException($msg);
 }
Ejemplo n.º 3
0
 /**
  * {@inheritDoc}
  */
 public function getNodePathForIdentifier($uuid, $workspace = null)
 {
     if (null !== $workspace && $workspace != $this->workspace) {
         $client = new Client($this->factory, $this->server);
         $client->login($this->credentials, $workspace);
         return $client->getNodePathForIdentifier($uuid);
     }
     $request = $this->getRequest(Request::REPORT, $this->workspaceUri);
     $request->setBody($this->buildLocateRequest($uuid));
     $dom = $request->executeDom();
     /* answer looks like
           <D:multistatus xmlns:D="DAV:">
             <D:response>
                 <D:href>http://localhost:8080/server/tests/jcr%3aroot/tests_level1_access_base/idExample/</D:href>
             </D:response>
         </D:multistatus>
        */
     $set = $dom->getElementsByTagNameNS(self::NS_DAV, 'href');
     if ($set->length != 1) {
         throw new RepositoryException('Unexpected answer from server: ' . $dom->saveXML());
     }
     $fullPath = $set->item(0)->textContent;
     if (strncmp($this->workspaceUriRoot, $fullPath, strlen($this->workspaceUri))) {
         throw new RepositoryException("Server answered a path that is not in the current workspace: uuid={$uuid}, path={$fullPath}, workspace=" . $this->workspaceUriRoot);
     }
     return $this->stripServerRootFromUri(substr(urldecode($fullPath), 0, -1));
 }