Use load strategies for project
Use load strategies for project

--- a/include/git/Project.class.php
+++ b/include/git/Project.class.php
@@ -205,6 +205,13 @@
 	 */
 	protected $objectManager;
 
+	/**
+	 * Data load strategy
+	 *
+	 * @var GitPHP_ProjectLoadStrategy_Interface
+	 */
+	protected $strategy;
+
 /*}}}1*/
 
 /* class methods {{{1*/
@@ -215,10 +222,13 @@
 	 * @param string $projectRoot project root
 	 * @param string $project project
 	 */
-	public function __construct($projectRoot, $project)
+	public function __construct($projectRoot, $project, GitPHP_ProjectLoadStrategy_Interface $strategy = null)
 	{
 		$this->projectRoot = GitPHP_Util::AddSlash($projectRoot);
 		$this->SetProject($project);
+
+		if ($strategy)
+			$this->SetStrategy($strategy);
 	}
 
 /*}}}1*/
@@ -579,40 +589,7 @@
 	{
 		$this->readHeadRef = true;
 
-		if ($this->GetCompat()) {
-			$this->ReadHeadCommitGit();
-		} else {
-			$this->ReadHeadCommitRaw();
-		}
-	}
-
-	/**
-	 * Read head commit using git executable
-	 */
-	private function ReadHeadCommitGit()
-	{
-		$args = array();
-		$args[] = '--verify';
-		$args[] = 'HEAD';
-		$this->head = trim(GitPHP_GitExe::GetInstance()->Execute($this->GetPath(), GIT_REV_PARSE, $args));
-	}
-
-	/**
-	 * Read head commit using raw git head pointer
-	 */
-	private function ReadHeadCommitRaw()
-	{
-		$headPointer = trim(file_get_contents($this->GetPath() . '/HEAD'));
-		if (preg_match('/^([0-9A-Fa-f]{40})$/', $headPointer, $regs)) {
-			/* Detached HEAD */
-			$this->head = $regs[1];
-		} else if (preg_match('/^ref: (.+)$/', $headPointer, $regs)) {
-			/* standard pointer to head */
-			$head = substr($regs[1], strlen('refs/heads/'));
-
-			if ($this->GetHeadList()->Exists($head))
-				$this->head = $this->GetHeadList()->GetHead($head)->GetHash();
-		}
+		$this->head = $this->strategy->LoadHead($this);
 	}
 
 /*}}}2*/
@@ -652,48 +629,7 @@
 	{
 		$this->epochRead = true;
 
-		if ($this->GetCompat()) {
-			$this->ReadEpochGit();
-		} else {
-			$this->ReadEpochRaw();
-		}
-	}
-
-	/**
-	 * Reads this project's epoch using git executable
-	 */
-	private function ReadEpochGit()
-	{
-		$args = array();
-		$args[] = '--format="%(committer)"';
-		$args[] = '--sort=-committerdate';
-		$args[] = '--count=1';
-		$args[] = 'refs/heads';
-
-		$epochstr = trim(GitPHP_GitExe::GetInstance()->Execute($this->GetPath(), GIT_FOR_EACH_REF, $args));
-
-		if (preg_match('/ (\d+) [-+][01]\d\d\d$/', $epochstr, $regs)) {
-			$this->epoch = $regs[1];
-		}
-	}
-
-	/**
-	 * Reads this project's epoch using raw objects
-	 */
-	private function ReadEpochRaw()
-	{
-		$epoch = 0;
-		foreach ($this->GetHeadList() as $headObj) {
-			$commit = $headObj->GetCommit();
-			if ($commit) {
-				if ($commit->GetCommitterEpoch() > $epoch) {
-					$epoch = $commit->GetCommitterEpoch();
-				}
-			}
-		}
-		if ($epoch > 0) {
-			$this->epoch = $epoch;
-		}
+		$this->epoch = $this->strategy->LoadEpoch($this);
 	}
 
 /*}}}2*/
@@ -721,6 +657,19 @@
 	}
 
 /*}}}2*/
+
+	/**
+	 * Set data load strategy
+	 *
+	 * @param GitPHP_ProjectLoadStrategy_Interface $strategy strategy
+	 */
+	public function SetStrategy(GitPHP_ProjectLoadStrategy_Interface $strategy)
+	{
+		if (!$strategy)
+			return;
+
+		$this->strategy = $strategy;
+	}
 
 /*}}}1*/
 
@@ -930,73 +879,7 @@
 	 */
 	public function AbbreviateHash($hash)
 	{
-		if (!(preg_match('/[0-9A-Fa-f]{40}/', $hash))) {
-			return $hash;
-		}
-
-		if ($this->GetCompat()) {
-			return $this->AbbreviateHashGit($hash);
-		} else {
-			return $this->AbbreviateHashRaw($hash);
-		}
-	}
-
-	/**
-	 * Abbreviates a hash using the git executable
-	 *
-	 * @param string $hash hash to abbreviate
-	 * @return string abbreviated hash
-	 */
-	private function AbbreviateHashGit($hash)
-	{
-		$args = array();
-		$args[] = '-1';
-		$args[] = '--format=format:%h';
-		$args[] = $hash;
-
-		$abbrevData = explode("\n", GitPHP_GitExe::GetInstance()->Execute($this->GetPath(), GIT_REV_LIST, $args));
-		if (empty($abbrevData[0])) {
-			return $hash;
-		}
-		if (substr_compare(trim($abbrevData[0]), 'commit', 0, 6) !== 0) {
-			return $hash;
-		}
-
-		if (empty($abbrevData[1])) {
-			return $hash;
-		}
-
-		return trim($abbrevData[1]);
-	}
-
-	/**
-	 * Default raw abbreviation length
-	 *
-	 * @const
-	 */
-	const HashAbbreviateLength = 7;
-
-	/**
-	 * Abbreviates a hash using raw git objects
-	 *
-	 * @param string $hash hash to abbreviate
-	 * @return string abbreviated hash
-	 */
-	private function AbbreviateHashRaw($hash)
-	{
-		$abbrevLen = GitPHP_Project::HashAbbreviateLength;
-
-		if ($this->abbreviateLength > 0) {
-			$abbrevLen = max(4, min($this->abbreviateLength, 40));
-		}
-
-		$prefix = substr($hash, 0, $abbrevLen);
-
-		if (!$this->uniqueAbbreviation) {
-			return $prefix;
-		}
-
-		return $this->GetObjectLoader()->EnsureUniqueHash($hash, $prefix);
+		return $this->strategy->AbbreviateHash($this, $hash);
 	}
 
 	/**
@@ -1007,43 +890,7 @@
 	 */
 	public function ExpandHash($abbrevHash)
 	{
-		if (!(preg_match('/[0-9A-Fa-f]{4,39}/', $abbrevHash))) {
-			return $abbrevHash;
-		}
-
-		if ($this->GetCompat()) {
-			return $this->ExpandHashGit($abbrevHash);
-		}  else {
-			return $this->GetObjectLoader()->ExpandHash($abbrevHash);
-		}
-	}
-
-	/**
-	 * Expands a hash using the git executable
-	 *
-	 * @param string $abbrevHash
-	 * @return string full hash
-	 */
-	private function ExpandHashGit($abbrevHash)
-	{
-		$args = array();
-		$args[] = '-1';
-		$args[] = '--format=format:%H';
-		$args[] = $abbrevHash;
-
-		$fullData = explode("\n", GitPHP_GitExe::GetInstance()->Execute($this->GetPath(), GIT_REV_LIST, $args));
-		if (empty($fullData[0])) {
-			return $abbrevHash;
-		}
-		if (substr_compare(trim($fullData[0]), 'commit', 0, 6) !== 0) {
-			return $abbrevHash;
-		}
-
-		if (empty($fullData[1])) {
-			return $abbrevHash;
-		}
-
-		return trim($fullData[1]);
+		return $this->strategy->ExpandHash($this, $abbrevHash);
 	}
 
 /*}}}2*/

--- /dev/null
+++ b/include/git/ProjectLoadStrategy.interface.php
@@ -1,1 +1,46 @@
+<?php
+/**
+ * Interface for project load strategies
+ *
+ * @author Christopher Han <xiphux@gmail.com>
+ * @copyright Copyright (c) 2012 Christopher Han
+ * @package GitPHP
+ * @subpackage Git
+ */
+interface GitPHP_ProjectLoadStrategy_Interface
+{
+	/**
+	 * Load a project's epoch
+	 *
+	 * @param GitPHP_Project $project project
+	 * @return string epoch
+	 */
+	public function LoadEpoch($project);
 
+	/**
+	 * Load a project's head hash
+	 *
+	 * @param GitPHP_Project $project
+	 * @return string head hash
+	 */
+	public function LoadHead($project);
+
+	/**
+	 * Expand an abbreviated hash
+	 *
+	 * @param GitPHP_Project $project project
+	 * @param string $abbrevHash abbreviated hash
+	 * @return string full hash
+	 */
+	public function ExpandHash($project, $abbrevHash);
+
+	/**
+	 * Abbreviate a hash
+	 *
+	 * @param GitPHP_Project $project project
+	 * @param string $hash hash to abbreviate
+	 * @return string abbreviated hash
+	 */
+	public function AbbreviateHash($project, $hash);
+}
+

--- /dev/null
+++ b/include/git/ProjectLoad_Git.class.php
@@ -1,1 +1,145 @@
+<?php
+/**
+ * Project load strategy using git exe
+ *
+ * @author Christopher Han <xiphux@gmail.com>
+ * @copyright Copyright (c) 2012 Christopher Han
+ * @package GitPHP
+ * @subpackage Git
+ */
+class GitPHP_ProjectLoad_Git implements GitPHP_ProjectLoadStrategy_Interface
+{
+	/**
+	 * Executable
+	 *
+	 * @var GitPHP_GitExe
+	 */
+	protected $exe;
 
+	/**
+	 * Constructor
+	 *
+	 * @var GitPHP_Exe $exe git exe
+	 */
+	public function __construct($exe)
+	{
+		if (!$exe)
+			throw new Exception('Git exe is required');
+
+		$this->exe = $exe;
+	}
+
+	/**
+	 * Load a project's epoch
+	 *
+	 * @param GitPHP_Project $project project
+	 * @return string epoch
+	 */
+	public function LoadEpoch($project)
+	{
+		if (!$project)
+			return;
+
+		$args = array();
+		$args[] = '--format="%(committer)"';
+		$args[] = '--sort=-committerdate';
+		$args[] = '--count=1';
+		$args[] = 'refs/heads';
+
+		$epochstr = trim($this->exe->Execute($project->GetPath(), GIT_FOR_EACH_REF, $args));
+
+		if (preg_match('/ (\d+) [-+][01]\d\d\d$/', $epochstr, $regs)) {
+			return $regs[1];
+		}
+	}
+
+	/**
+	 * Load a project's head hash
+	 *
+	 * @param GitPHP_Project $project
+	 * @return string head hash
+	 */
+	public function LoadHead($project)
+	{
+		if (!$project)
+			return;
+
+		$args = array();
+		$args[] = '--verify';
+		$args[] = 'HEAD';
+		return trim($this->exe->Execute($project->GetPath(), GIT_REV_PARSE, $args));
+	}
+
+	/**
+	 * Expand an abbreviated hash
+	 *
+	 * @param GitPHP_Project $project project
+	 * @param string $abbrevHash abbreviated hash
+	 * @return string full hash
+	 */
+	public function ExpandHash($project, $abbrevHash)
+	{
+		if (!$project)
+			return $abbrevHash;
+
+		if (!(preg_match('/[0-9A-Fa-f]{4,39}/', $abbrevHash))) {
+			return $abbrevHash;
+		}
+
+		$args = array();
+		$args[] = '-1';
+		$args[] = '--format=format:%H';
+		$args[] = $abbrevHash;
+
+		$fullData = explode("\n", $this->exe->Execute($project->GetPath(), GIT_REV_LIST, $args));
+		if (empty($fullData[0])) {
+			return $abbrevHash;
+		}
+		if (substr_compare(trim($fullData[0]), 'commit', 0, 6) !== 0) {
+			return $abbrevHash;
+		}
+
+		if (empty($fullData[1])) {
+			return $abbrevHash;
+		}
+
+		return trim($fullData[1]);
+	}
+
+	/**
+	 * Abbreviate a hash
+	 *
+	 * @param GitPHP_Project $project project
+	 * @param string $hash hash to abbreviate
+	 * @return string abbreviated hash
+	 */
+	public function AbbreviateHash($project, $hash)
+	{
+		if (!$project)
+			return $hash;
+
+		if (!(preg_match('/[0-9A-Fa-f]{40}/', $hash))) {
+			return $hash;
+		}
+
+		$args = array();
+		$args[] = '-1';
+		$args[] = '--format=format:%h';
+		$args[] = $hash;
+
+		$abbrevData = explode("\n", $this->exe->Execute($project->GetPath(), GIT_REV_LIST, $args));
+		if (empty($abbrevData[0])) {
+			return $hash;
+		}
+		if (substr_compare(trim($abbrevData[0]), 'commit', 0, 6) !== 0) {
+			return $hash;
+		}
+
+		if (empty($abbrevData[1])) {
+			return $hash;
+		}
+
+		return trim($abbrevData[1]);
+	}
+}
+

--- /dev/null
+++ b/include/git/ProjectLoad_Raw.class.php
@@ -1,1 +1,118 @@
+<?php
+/**
+ * Project load strategy using raw git objects
+ *
+ * @author Christopher Han <xiphux@gmail.com>
+ * @copyright Copyright (c) 2012 Christopher Han
+ * @package GitPHP
+ * @subpackage Git
+ */
+class GitPHP_ProjectLoad_Raw implements GitPHP_ProjectLoadStrategy_Interface
+{
+	/**
+	 * Load a project's epoch
+	 *
+	 * @param GitPHP_Project $project project
+	 * @return string epoch
+	 */
+	public function LoadEpoch($project)
+	{
+		if (!$project)
+			return;
 
+		$epoch = 0;
+		foreach ($project->GetHeadList() as $headObj) {
+			$commit = $headObj->GetCommit();
+			if ($commit) {
+				if ($commit->GetCommitterEpoch() > $epoch) {
+					$epoch = $commit->GetCommitterEpoch();
+				}
+			}
+		}
+		if ($epoch > 0) {
+			return $epoch;
+		}
+	}
+
+	/**
+	 * Load a project's head hash
+	 *
+	 * @param GitPHP_Project $project
+	 * @return string head hash
+	 */
+	public function LoadHead($project)
+	{
+		if (!$project)
+			return;
+
+		$headPointer = trim(file_get_contents($project->GetPath() . '/HEAD'));
+		if (preg_match('/^([0-9A-Fa-f]{40})$/', $headPointer, $regs)) {
+			/* Detached HEAD */
+			return $regs[1];
+		} else if (preg_match('/^ref: (.+)$/', $headPointer, $regs)) {
+			/* standard pointer to head */
+			$head = substr($regs[1], strlen('refs/heads/'));
+
+			if ($project->GetHeadList()->Exists($head))
+				return $project->GetHeadList()->GetHead($head)->GetHash();
+		}
+	}
+
+	/**
+	 * Expand an abbreviated hash
+	 *
+	 * @param GitPHP_Project $project project
+	 * @param string $abbrevHash abbreviated hash
+	 * @return string full hash
+	 */
+	public function ExpandHash($project, $abbrevHash)
+	{
+		if (!$project)
+			return $abbrevHash;
+
+		if (!(preg_match('/[0-9A-Fa-f]{4,39}/', $abbrevHash))) {
+			return $abbrevHash;
+		}
+
+		return $project->GetObjectLoader()->ExpandHash($abbrevHash);
+	}
+
+	/**
+	 * Default raw abbreviation length
+	 *
+	 * @const
+	 */
+	const HashAbbreviateLength = 7;
+
+	/**
+	 * Abbreviate a hash
+	 *
+	 * @param GitPHP_Project $project project
+	 * @param string $hash hash to abbreviate
+	 * @return string abbreviated hash
+	 */
+	public function AbbreviateHash($project, $hash)
+	{
+		if (!$project)
+			return $hash;
+
+		if (!(preg_match('/[0-9A-Fa-f]{40}/', $hash))) {
+			return $hash;
+		}
+
+		$abbrevLen = GitPHP_ProjectLoad_Raw::HashAbbreviateLength;
+
+		if ($project->GetAbbreviateLength() > 0) {
+			$abbrevLen = max(4, min($project->GetAbbreviateLength(), 40));
+		}
+
+		$prefix = substr($hash, 0, $abbrevLen);
+
+		if (!$project->GetUniqueAbbreviation()) {
+			return $prefix;
+		}
+
+		return $project->GetObjectLoader()->EnsureUniqueHash($hash, $prefix);
+	}
+}
+

--- a/include/git/projectlist/ProjectListBase.class.php
+++ b/include/git/projectlist/ProjectListBase.class.php
@@ -234,6 +234,12 @@
 			return;
 
 		$compat = $project->GetCompat();
+
+		if ($compat) {
+			$project->SetStrategy(new GitPHP_ProjectLoad_Git(GitPHP_GitExe::GetInstance()));
+		} else {
+			$project->SetStrategy(new GitPHP_ProjectLoad_Raw());
+		}
 
 		$headListStrategy = null;
 		if ($compat) {

comments