Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions features/bootstrap/FeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -646,4 +646,54 @@ public function iCloneNodeFromTo($arg1, $arg2, $arg3)
$workspace = $session->getWorkspace();
$workspace->cloneFrom($arg2, $arg1, $arg3, false);
}

/**
* @Given /^the node "([^"]*)" is locked$/
*/
public function theNodeIsLocked($arg1)
{
$session = $this->getSession();
$workspace = $session->getWorkspace();
$lockManager = $workspace->getLockManager();
$lockManager->lock($arg1, true, true);
}

/**
* @Given /^the node "([^"]*)" is not locked$/
*/
public function theNodeIsNotLocked($arg1)
{
$session = $this->getSession();
$workspace = $session->getWorkspace();
$lockManager = $workspace->getLockManager();
if ($lockManager->isLocked($arg1)) {
$lockManager->unlock($arg1);
}
}

/**
* @Given /^the node "([^"]*)" should be locked$/
*/
public function theNodeShouldBeLocked($arg1)
{
$session = $this->getSession();
$workspace = $session->getWorkspace();
$lockManager = $workspace->getLockManager();
$isLocked = $lockManager->isLocked($arg1);

PHPUnit_Framework_Assert::assertTrue($isLocked);
}

/**
* @Given /^the node "([^"]*)" should not be locked$/
*/
public function theNodeShouldNotBeLocked($arg1)
{
$session = $this->getSession();
$workspace = $session->getWorkspace();
$lockManager = $workspace->getLockManager();
$isLocked = $lockManager->isLocked($arg1);

PHPUnit_Framework_Assert::assertFalse($isLocked);
}
}
29 changes: 29 additions & 0 deletions features/lock_info.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Feature: Show the details of a lock
In order to show the details of a lock
As a user that is logged into the shell
I should be able to run a command which does that

Background:
Given that I am logged in as "testuser"
And the "session_data.xml" fixtures are loaded
And the node at "/tests_general_base" has the mixin "mix:lockable"
And the node "/tests_general_base" is locked

Scenario: Create a new node
Given I execute the "lock:info /tests_general_base" command
Then the command should fail
And I should see the following:
"""
Not implemented
"""
# And I should see the following:
# """
# Lock Owner: admin
# Lock Token: foobar
# Seconds Remaining: 123
# Deep?: yes
# Live?: yes
# Owned by current session?: no
# Session Scoped?: no
# """

14 changes: 14 additions & 0 deletions features/lock_lock.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Feature: Lock the node at a given path
In order to lock a node at a given path
As a user that is logged into the shell
I should be able to run a command which does that

Background:
Given that I am logged in as "testuser"
And the "session_data.xml" fixtures are loaded
And the node at "/tests_general_base" has the mixin "mix:lockable"

Scenario: Create a new lock
Given I execute the "lock:lock /tests_general_base --deep --session-scoped --timeout=30 --owner-info=random" command
Then the command should not fail
And the node "/tests_general_base" should be locked
16 changes: 16 additions & 0 deletions features/lock_refresh.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Feature: Refresh the TTL of a lock
In order to reset the TTL on the lock of a given node path
As a user that is logged into the shell
I should be able to run a command which does that

Background:
Given that I am logged in as "testuser"
And I execute the "lock:lock /tests_general_base --session-scoped --timeout=10" command

Scenario: Create a new node
And I execute the "lock:refresh /tests_general_base" command
Then the command should fail
And I should see the following:
"""
Not implemented
"""
16 changes: 16 additions & 0 deletions features/lock_token_add.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Feature: Add a lock token in the current session
In order to create a new lock token
As a user that is logged into the shell
I should be able to run a command which does that

Background:
Given that I am logged in as "testuser"

Scenario: Create a new node
Given I execute the "lock:token:add foobar" command
Then the command should fail
Then I should see the following:
"""
Not implemented
"""

14 changes: 14 additions & 0 deletions features/lock_token_list.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Feature: List the lock tokens registered with the current session
In order to list the lock tokens registered in the current session
As a user that is logged into the shell
I should be able to run a command which does that

Background:
Given that I am logged in as "testuser"

Scenario: List lock tokens
Given I execute the "lock:token:add foobar" command
Then the command should fail
"""
Not implemented
"""
15 changes: 15 additions & 0 deletions features/lock_token_remove.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Feature: Remove a lock token in the current session
In order to create a new lock token
As a user that is logged into the shell
I should be able to run a command which does that

Background:
Given that I am logged in as "testuser"

Scenario: Create a new node
Given I execute the "lock:token:remove foobar" command
Then the command should fail
Then I should not see the following:
"""
Not implemented
"""
15 changes: 15 additions & 0 deletions features/lock_unlock.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Feature: Unlock the node at a given path
In order to unlock a node at a given path
As a user that is logged into the shell
I should be able to run a command which does that

Background:
Given that I am logged in as "testuser"
And the "session_data.xml" fixtures are loaded
And the node at "/tests_general_base" has the mixin "mix:lockable"

Scenario: Create a new node
Given I execute the "lock:lock /tests_general_base --session-scoped" command
And I execute the "lock:unlock /tests_general_base" command
Then the command should not fail
And the node "/tests_general_base" should not be locked
15 changes: 15 additions & 0 deletions features/node_remove.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Feature: Remove a node
In order to remove a node
As a user that is logged into the shell
I should be able to run a command which does that

Background:
Given that I am logged in as "testuser"
And the "session_data.xml" fixtures are loaded

Scenario: Remove a node
Given the current node is "/tests_general_base"
And I execute the "node:remove" command
Then the command should not fail
And I save the session
And there should not exist a node at "/tests_general_base"
14 changes: 14 additions & 0 deletions src/PHPCR/Shell/Console/Application/ShellApplication.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@
use PHPCR\Shell\Console\Command\NodeSharedShowCommand;
use PHPCR\Shell\Console\Command\NodeSharedRemoveCommand;
use PHPCR\Shell\Console\Command\NodeRemoveCommand;
use PHPCR\Shell\Console\Command\LockLockCommand;
use PHPCR\Shell\Console\Command\LockInfoCommand;
use PHPCR\Shell\Console\Command\LockRefreshCommand;
use PHPCR\Shell\Console\Command\LockTokenAddCommand;
use PHPCR\Shell\Console\Command\LockTokenListCommand;
use PHPCR\Shell\Console\Command\LockTokenRemoveCommand;
use PHPCR\Shell\Console\Command\LockUnlockCommand;

use Jackalope\NotImplementedException;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
Expand Down Expand Up @@ -181,6 +188,13 @@ public function init()
$this->add(new NodeSharedShowCommand());
$this->add(new NodeSharedRemoveCommand());
$this->add(new NodeRemoveCommand());
$this->add(new LockLockCommand());
$this->add(new LockInfoCommand());
$this->add(new LockRefreshCommand());
$this->add(new LockTokenAddCommand());
$this->add(new LockTokenListCommand());
$this->add(new LockTokenRemoveCommand());
$this->add(new LockUnlockCommand());

// add shell-specific commands
$this->add(new ChangePathCommand());
Expand Down
56 changes: 56 additions & 0 deletions src/PHPCR/Shell/Console/Command/LockInfoCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace PHPCR\Shell\Console\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

class LockInfoCommand extends Command
{
protected function configure()
{
$this->setName('lock:info');
$this->setDescription('Create a node at the current path');
$this->addArgument('absPath', InputArgument::REQUIRED, 'Absolute path of locked node');
$this->setHelp(<<<HERE
Shows the details of the lock that applies to the node at the specified
absPath.

This may be either of the lock on that node itself or a deep lock on a node
above that node.
HERE
);
}

public function execute(InputInterface $input, OutputInterface $output)
{
$session = $this->getHelper('phpcr')->getSession();
$absPath = $input->getArgument('absPath');
$workspace = $session->getWorkspace();
$lockManager = $workspace->getLockManager();

$lock = $lockManager->getLock($absPath);

$info = array(
'Lock owner' => $lock->getLockOwner(),
'Lock token' => $lock->getLockToken(),
'Seconds remaining' => $lock->getSecondsRemaining(),
'Deep?' => $lock->isDeep() ? 'yes' : 'no',
'Live?' => $lock->isLove() ? 'yes' : 'no',
'Owned by current session?' => $lock->isLockOwningSession() ? 'yes' : 'no',
'Session scoped?' => $lock->isSessionScoped() ? 'yes' : 'no',
);

$table = clone $this->getHelper('table');

foreach ($info as $label => $value) {
$table->addRow(array($label, $value));
}

$table->render($output);
}
}

70 changes: 70 additions & 0 deletions src/PHPCR/Shell/Console/Command/LockLockCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

namespace PHPCR\Shell\Console\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

class LockLockCommand extends Command
{
protected function configure()
{
$this->setName('lock:lock');
$this->setDescription('Lock the node at the given path');
$this->addArgument('absPath', InputArgument::REQUIRED, 'Absolute path of node to be locked');
$this->addOption('deep', null, InputOption::VALUE_NONE, 'If given this lock will apply to this node and all its descendants; if not, it applies only to this node.');
$this->addOption('session-scoped', null, InputOption::VALUE_NONE, 'If given, this lock expires with the current session; if not it expires when explicitly or automatically unlocked for some other reason');
$this->addOption('timeout', null, InputOption::VALUE_REQUIRED, 'Desired lock timeout in seconds (servers are free to ignore this value). If not used lock will not timeout');
$this->addOption('owner-info', null, InputOption::VALUE_REQUIRED, ' string containing owner information supplied by the client; servers are free to ignore this value. If none is specified, the implementation chooses one (i.e. user name of current backend authentication credentials');
$this->setHelp(<<<HERE
Places a lock on the node at <info>absPath</info>.

If successful, the node is said to hold the lock.

If <info>deep</info> option is given then the lock applies to the specified node and
all its descendant nodes; if false, the lock applies only to the
specified node. On a successful lock, the jcr:lockIsDeep property of the
locked node is set to this value.

If <b>session-scoped</b> is specified then this lock will expire upon the
expiration of the current session (either through an automatic or
explicit <info>sesiion:logout</info>; if not given, this lock does not
expire until it is explicitly unlocked, it times out, or it is
automatically unlocked due to a implementation-specific limitation.

The <info>timeout</info> parameter specifies the number of seconds until the
lock times out (if it is not refreshed with LockInterface::refresh() in
the meantime). An implementation may use this information as a hint or
ignore it altogether. Clients can discover the actual timeout by
inspecting the returned Lock object.

The <info>ownerInfo</info> parameter can be used to pass a string holding
owner information relevant to the client. An implementation may either
use or ignore this parameter.

The addition or change of the properties jcr:lockIsDeep and
jcr:lockOwnerare persisted immediately; there is no need to call save.

It is possible to lock a node even if it is checked-in.
HERE
);
}

public function execute(InputInterface $input, OutputInterface $output)
{
$session = $this->getHelper('phpcr')->getSession();
$workspace = $session->getWorkspace();
$lockManager = $workspace->getLockManager();

$absPath = $input->getArgument('absPath');
$isDeep = $input->getOption('deep');
$isSessionScoped = $input->getOption('session-scoped');
$timeout = $input->getOption('timeout');
$ownerInfo = $input->getOption('owner-info');

$lockManager->lock($absPath, $isDeep, $isSessionScoped, $timeout, $ownerInfo);
}
}
39 changes: 39 additions & 0 deletions src/PHPCR/Shell/Console/Command/LockRefreshCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace PHPCR\Shell\Console\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

class LockRefreshCommand extends Command
{
protected function configure()
{
$this->setName('lock:refresh');
$this->setDescription('Refresh the TTL of the lock of the node at the given path');
$this->addArgument('absPath', InputArgument::REQUIRED, 'Absolute path of node containing the lock to be refreshed');
$this->setHelp(<<<HERE
If this lock's time-to-live is governed by a timer, this command resets
that timer so that the lock does not timeout and expire.

If this lock's time-to-live is not governed by a timer, then this method
has no effect.
HERE
);
}

public function execute(InputInterface $input, OutputInterface $output)
{
$session = $this->getHelper('phpcr')->getSession();
$workspace = $session->getWorkspace();
$lockManager = $workspace->getLockManager();

$absPath = $input->getArgument('absPath');

$lock = $lockManager->getLock($absPath);
$lock->refresh();
}
}
Loading