<?php
/*******************************************************************************
 * Copyright (c) 2010, 2012 Eclipse Foundation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Wayne Beaton (Eclipse Foundation) - initial API and implementation
 *    Wayne Beaton (Eclipse Foundation) - Bug 369905
 *******************************************************************************/

/*
 * This script assumes that it is being included by another script. We
 * assume that the $App variable has already been defined.
 */

require_once(dirname(__FILE__) . "/ProjectRoot.class.php");
require_once(dirname(__FILE__) . "/debug.php");
require_once(dirname(__FILE__) . "/common.php");
trace_file_info(__FILE__);

/**
 * Get a project from the PMI instead of the foundation database.
 *
 * @param string $id a project id of the form 'technology.egit'
 * @return PMIProject
 */
function get_project_from_pmi($id) {
	if (!isValidProjectId($id)) return null;
	if (preg_match('/^polarsys\.(.*)$/',$id, $matches)) {
		$id = $matches[1];
		$url = "https://polarsys.org/json/project/$id";
	} else {
		$url = "http://projects.eclipse.org/json/project/$id";
	}
	if (!$json = file_get_contents($url)) return null;
	
	$all = json_decode($json, true);
	return new PMIProject($all['projects'][$id]);
}

/**
 * PMI stand-in for Project class. The intent is that this
 * is a valid subtype. The current reality is that I'm implementing
 * only those bits of functionality that I'm actually using as I
 * need it.
 * 
 * @see Project
 * @see get_project_from_pmi
 */
class PMIProject {
	var $data;
	
	function __construct($data) {
		$this->data = $data;
	}
	
	function getId() {
		// TODO Get the name (when it's available)
		return $this->data['id'][0]['value'];
	}
	
	
	function getName() {
		// TODO Get the name (when it's available)
		return $this->data['id'][0]['value'];
	}
	
	function getPlanUrl() {
		return $this->data['plan_url'][0]['url'];
	}
	
	function getSourceRepositories() {
		$repositories = array();
		foreach($this->data['source_repo'] as $repo) {
			$repositories[] = getSourceRepository($repo['path'], $this);
		}
		return $repositories;
	}

	function getBugzillaProduct() {
		foreach($this->data['bugzilla'] as $record) {
			if (strlen($record['product']) > 0)
				return $record['product'];
		}
		return null;		
	}
	
	function getBugzillaComponents() {
		$components = array();
		foreach($this->data['bugzilla'] as $record) {
			if (strlen($record['component']) > 0)
				$components[] = $record['component'];
		}
		return $components;
	}
}

/**
 * @deprecated use #getProjectRoot()
 */
function get_project_root() {
	return getProjectRoot();
}
/**
 * Lazily create an instance of ProjectRoot; this instance will read in and hold onto
 * the project information. This way, we only read it once.
 * 
 * PRIVATE: THIS IS NOT API
 */
function getProjectRoot() {
	global $_project_root;
	
	if (!$_project_root) $_project_root = new ProjectRoot();
	
	return $_project_root;
}

/**
 * Clear the project cache. Call this method if you need to reload the
 * projects for any reason, or if you just want to try and reclaim some
 * space (though I remain skeptical about PHP's garbage collection).
 */
function clear_project_cache() {
	global $_project_root;
	
	unset($_project_root);
}

/**
 * Force projects to be preloaded. You might use this behaviour
 * to override the default lazy behaviour (which is to load only
 * the active projects) thereby including inactive projects in
 * later queries.
 * 
 * This function is no longer required. Projects load on demand;
 * there is only one way to load.
 * 
 * @deprecated
 * @param bool $activeOnly Load only the active projects (default)
 */
function preloadProjects($activeOnly = true) {
	_loadAllProjects($activeOnly);
}

/**
 * Do the actual load of the projects. Projects are cached.
 * 
 * PRIVATE: THIS IS NOT API
 * 
 * @deprecated This function is unnecessary.
 * @internal
 * @param bool $activeOnly Load only the active projects (default)
 */
function _loadAllProjects($activeOnly = true) {
	global $_project_root;
	$_project_root = new ProjectRoot($activeOnly);
}

/**
 * Answers an array containing all top-level projects. Only
 * active projects are included.
 * 
 * @return Project[]
 */
function getTopLevelProjects() {
	return getProjectRoot()->getTopLevelProjects();
}

/**
 * @deprecated
 * @see #getTopLevelProjects()
 */
function get_project_hierarchy() {
	return getTopLevelProjects();
}

/**
 * This function returns an instance of Project representing the project
 * with the provided $id. Note that this function preserves object
 * identity: if called twice with the same value, it will return the
 * exact same object.
 * 
 * @return Project
 */
function getProject($id) {
	return getProjectRoot()->getProject($id);
}

/**
 * @deprecated use #getProject($id)
 * @return Project
 */
function get_project($id) {
	return getProjectRoot()->get_project($id);
}

/**
 * This function returns all the active projects. 
 * @return Project[]
 */
function getActiveProjects() {
	return getProjectRoot()->getActiveProjects();
}

/**
 * @deprecated use #getActiveProjects()
 * @return Project[]
 */
function get_all_projects() {
	return getActiveProjects();
}

/**
 * This function returns an array containing those projects that have
 * declared participation in the simultaneous release with the provided
 * name.
 * 
 * @param string $name
 */
function getAllProjectsInSimultaneousRelease($name) {
	$all = get_all_projects();
	$projects = array();
	foreach($all as $project) {
		/* @var $project Project */
		if (in_array($name, $project->getSimultaneousReleaseNames())) $projects[] = $project;
	}
	return $projects;
}

/*
 * List of field names in the database.
 * 
 * PRIVATE: THIS FIELD IS NOT API.
 */
$project_fields = array('ProjectId', 'Name','Level','ParentProjectID','Description',
	'UrlDownload','UrlIndex','DateActive','SortOrder','IsActive',
	'BugsName','ProjectPhase','DiskQuotaGB','IsComponent','IsStandard'); 
$project_fields_string = implode(',', $project_fields);

define('PROJECT_LIVELINESS_ACTIVE', 1);
define('PROJECT_LIVELINESS_STALE', 2);
define('PROJECT_LIVELINESS_DEAD', 3);

define('PROJECT_REPO_ALL_GIT', 1);
define('PROJECT_REPO_SOME_GIT', 2);
define('PROJECT_REPO_NO_GIT', 3);
define('PROJECT_REPO_NONE', 4);

class Project {
	/** 
	 * @internal
	 * @var ProjectRoot 
	 */ 
	var $root;
	
	/**
	 * Project information from the 'Foundation' database
	 * @internal
	 */ 
	var $data; 
	
	/** 
	 * Values from the Eclipse database
	 * @internal
	 */ 
	var $values = array(); 
	
	/** 
	 * @internal
	 * @var Project 
	 */ 
	var $parent;
	
	/** 
	 * @internal
	 * @var Project[] 
	 */ 
	var $children = array();
	
	/**
	 * Keep track of the people associated with the project. This
	 * field is lazy-initialized; use the getPeople() method to access.
	 * 
	 * @internal 
	 */ 
	var $people = null;

	/**
	 * An array containing the the projects that the receiver has
	 * been moved from (e.g., if the project moved from a->b->c, then
	 * project c would list (a,b) in this field).
	 * 
	 * @internal
	 * @var Project[]
	 */
	var $movedFrom = array();
	
	/**
	 * @param Project $root
	 * @param mixed $data
	 */
	function __construct($root, $data) {
		$this->root = $root;
		$this->data = $data;
	}
	
	/**
	 * @return string
	 */
	function getId() {
		return $this->data['ProjectId'];
	}
	
	/**
	 * @return Project
	 */
	function getParent() {
		return $this->parent;
	}
	
	function getUrl() {
		return "http://projects.eclipse.org/projects/" . $this->getId();
	}
	
	/**
	 * @return string
	 */
	function getShortId() {
		preg_match("/([^\.]+)$/", $this->getId(), $matches);
		return $matches[1];
	}

	/**
	 * Answer the project's name as it appears in the Project metadata.
	 * If the project metadata has not been specified, get the value
	 * from the Eclipse Foundation Database. If the name has not been 
	 * specified, the ID is answered instead.
	 * 
	 * @return string
	 */
	function getName() {
		if ($name = $this->findFirstValue('projectname')) return $name;
		if ($name = $this->findFirstValue('projectshortname')) return $name;
		return $this->data['Name'] ? $this->data['Name'] : $this->getId();
	}
	
	function getTopLevelProject() {
		if (!$this->parent) return $this;
		return $this->parent->getTopLevelProject();
	}
	
	function getSiblings() {
		return $this->parent ? $this->parent->getChildren() : getTopLevelProjects();
	}
	
	/**
	 * Answer the project's name as it appears in the developer portal
	 * (this value is set by the project's commmitters). If the projectname
	 * field has not been specified, the project's name as it appears
	 * in the Eclipse Foundation Database is answered instead.
	 * 
	 * @return string
	 */
	function getProjectName() {
		$name = $this->findFirstValue('projectname');
		if ($name) return $name;
		return $this->getName();	
	}
	
	/**
	 * Answer the short name of the project as entered in the 
	 * 'projectshortname' field in the portal. If the value is
	 * not set in the portal, the receiver's name is returned instead.
	 * 
	 * @return string
	 */
	function getShortName() {
		$name = $this->findFirstValue('projectshortname');
		return $name ? $name : $this->getName();
	}
	
	/**
	 * Note that this is a fairly expensive operation. We assume that
	 * this function will be called at most once in any session. The current 
	 * implementation does not cache the results, so the caller should
	 * be careful to avoid subsequent calls (or change this implementation).
	 * 
	 * @return string 
	 */
	function getDescription() {	
		$id = $this->getId();
		$raw = $this->getDescriptionUrl();
		$url = normalizeFilePathUrl($raw);
		
		if (!$url) {
			trace("Description URL for $id not provided.");
			return null;
		}
		
		if (preg_match('/\.php$/', $url)) {
			trace("Ignoring PHP description URL for $id.");
			return null;
		}
		
		trace("Description URL for $id is $raw, normalizes to $url.");
		
		$description = @file_get_contents($url);
		if (!$description)  {
			trace("Description for $id not found.");
			return null;
		}
		
		$description = $this->cleanDescription($description);

		if(!trim($description))  {
			trace("Description for $id is empty.");
			return null;
		}
		
		return $description;
	}
	
	/**
	 * The short description is an abridged version of the description. We first
	 * try to obtain the description using the #getParagraph method; if this does
	 * not return a value, we grab the description (assuming that it is available).
	 * Whatever value we start from, we strip out any HTML tags and limit the size
	 * to 100 words. Results vary based on the quality of the input :-(
	 * 
	 * Note that this is a fairly expensive operation. We assume that
	 * this function will be called at most once in any session. The current 
	 * implementation does not cache the results, so the caller should
	 * be careful to avoid subsequent calls (or change this implementation).
	 * 
	 * @return string
	 */
	function getShortDescription() {
		$description = $this->getParagraph();
		if (!$description) $description = $this->getDescription();
		return $this->extractShortDescription($description);
	}
	
	/**
	 * Answer a paragraph describing the receiver, extracted from
	 * the file referenced in the 'paragraphurl' field in the portal,
	 * or <code>null</code> if the field is not specified.
	 * 
	 * @return string|null
	 */
	function getParagraph() {
		$id = $this->getId();
		$raw = $this->getParagraphUrl();
		$url = normalizeFilePathUrl($raw);
		
		if (!$url) {
			trace("Paragraph URL for $id not provided.");
			return null;
		}
		
		trace("Paragraph URL for $id is $raw, normalizes to $url.");
		
		$paragraph = @file_get_contents($url);
		
		if (!$paragraph)  {
			trace("Paragraph for $id not found.");
			return null;
		}
	
		if(!trim($paragraph))  {
			trace("Paragraph for $id is empty.");
			return null;
		}
		
		return $paragraph;
	}
	
	/**
	 * Return the URL for the project. This information is
	 * represented in both the portal and the Foundation database.
	 * The value provided by a project committer in the metadata
	 * (portal) overrides any value that exists in the Foundation 
	 * Database.
	 * 
	 * @string
	 */
	function getProjectUrl() {
		$url = $this->findFirstValue('projecturl');
		if ($url) return $url;
		
		return $this->data['UrlIndex'];
	}
	
	function getPlanUrl() {
		$plan = $this->findFirstValue('projectplanurl');
		if (preg_match('/^http:\/\/(www\.)?eclipse\.org\/projects\/project-plan\.php\?planurl=(.+\.xml)$/', $plan, $matches)) {
			return $matches[2];
		}
		
		return $plan;
	}
	
	function getWikiUrl() {
		return $this->findFirstValue('wikiurl');	
	}
	
	function getIpLogUrl() {
		return $this->findFirstValue('iplogurl');	
	}
	
	function getLogoUrl() {
		return $this->findFirstValue('logourl');	
	}
	
	function getDocumentationUrl() {
		return $this->findFirstValue('documentationurl');
	}

	function getDescriptionUrl() {
		if ($url = $this->findFirstValue('descriptionurl')) return $url;
		
		if ($root = $this->getWebRoot()) return "$root/description.html";
		
		return null;
	}
	
	/**
	 * Answers the root directory for the website of the project.
	 */
	function getWebRoot() {
		$short = end(preg_split('/\./', $this->getId()));
		if (file_exists(normalizeFilePathUrl($short))) return $short;
		return null;
	}

	function getParagraphUrl() {
		return $this->findFirstValue('paragraphurl');
	}
	
	function getDownloadsUrl() {
		return $this->findFirstValue('downloadsurl');
	}
	
	function getGettingStartedUrl() {
		return $this->findFirstValue('gettingstartedurl');
	}
	/**
	 * @return String
	 */
	function getBugzillaProduct() {
		return $this->findFirstValue('bugzilla', 'productname');
	}
	
	/**
	 * Return an array containing the component names for the project.
	 * If no components are specified for this project, then the 
	 * result is an empty array.
	 * 
	 * Components are stored in an single string. Each component is
	 * separated from the next using a comma. We try to be as forgiving
	 * as possible here and trim out leading or trailing spaces.
	 * Since I'm not sure exactly what limitations are placed on
	 * component names, this is probably the best we can do.
	 * 
	 * @return String[]
	 */
	function getBugzillaComponents() {
		$value = $this->findFirstValue('bugzilla', 'components');
		if (!$value) return array();
		$components = array();
		$values = split(',', $value);
		foreach($values as $component) {
			$components[] = trim($component);
		}
		return $components;
	}

	function getBugzillaUrl() {
		return $this->findFirstValue('bugzilla', 'url');
	}
	
	/**
	 * 
	 * @return Review[]
	 */
	function getReviews() {		
		require_once(dirname(__FILE__) . "/Review.class.php");
		return getReviewsForProject($this->getId());
	}
	
	function getProposal() {
		require_once(dirname(__FILE__) . "/Proposal.class.php");
		return getProposalForProject($this->getId());
	}
	
	function getScope() {
		$proposal = $this->getProposal();
		if (!$proposal) return;
		return $proposal->getScope();
	}
	
	/**
	 * Answer the creation review of the receiver or null if
	 * the creation review cannot be found. If $checkParent
	 * (optional) is true (default), then we assume that--if
	 * the receiver does not have its own creation review--it
	 * shares creation with its parent.
	 * 
	 * @return Review|null
	 */
	function getCreationReview($checkParent = true) {
		foreach($this->getReviews() as $review) {
			if ($review->isCreation()) return $review;
		}
		if (!$checkParent) return null;
		if (!$this->parent) return null;		
		return $this->parent->getCreationReview();
	}
	
	/**
	 * Answer the termination review of the receiver or null if
	 * the creation review cannot be found. 
	 * 
	 * @return Review|null
	 */
	function getTerminationReview() {
		foreach($this->getReviews() as $review) {
			if ($review->isTermination()) return $review;
		}
		return null;
	}
	
// At some point, we may consider an approach along these lines.
// For now, it's better to separate methods for each getter to
// better allow for code completion to work.
//	
//	function __call($name, $parameters) {
//		global $projectAPI;
//		
//		$matches = array();
//		if (preg_match('/^get([_\d\w]*)$/')) {
//			$metadata = $projectAPI->findMetaDataForProjectInfo($matches[1]);
//			$value = $this->findFirstValue($metadata['mainkey']);
//			
//		}
//	
//		return parent::__call($name, $description);
//	}
	
	/**
	 * 
	 * @return Newsgroup[]
	 */
	function getNewsgroups() {	
		return $this->getProjectInfoValues('newsgroup');	
	}
	
	function getMailingLists() {
		return $this->getProjectInfoValues('mailinglist');
	}
	
	/**
	 * A project has releases if (a) there is at least one
	 * release documented in the metadata, and (b) there is no
	 * documented release with 'noreleases' as its name.
	 * 
	 * @return bool
	 */
	function hasReleases() {
		return $this->getReleases() ? true : false;
	}
	
	/**
	 * Answers the collection of releases made by the project sorted
	 * in ascending order (i.e. the oldest release is first).
	 * 
	 * @return Release[]
	 */
	function getReleases() {
		$releases = array();
		foreach ($this->getProjectInfoValues('release') as $data) {
			$release = new Release($this, $data);
			if (!$release->isValid()) continue;
			$releases[$release->getName()] = $release;
		}
		
		foreach($this->movedFrom as $project) {
			$trace = trace("Adding releases from " . $project->getId());
			foreach($project->getReleases() as $release) {
				//if (!isset($releases[$release->getName()])) 
					$releases[$release->getName()] = $release;
				//else 
				$trace->trace("Adding " . $release->getName());
			}
		}
		
		usort($releases, array($this, 'sortReleases'));

		return $releases;
	}
	
	/**
	 * This function is used by #renderReleases.
	 * 
	 * @internal
	 * @param Release $release1
	 * @param Release $release2
	 */
	function sortReleases($release1, $release2) {
		$date1 = $release1->getDate();
		$date2 = $release2->getDate();
		if ($date1 == $date2) return 0;
		return $date1 < $date2 ? -1 : 1;
	}
	
	/**
	 * @param $date timestamp
	 * @return Release|null
	 */
	function getReleaseOnDate($date) {
		$string = date('Y-m-d', $date);
		$releases = $this->getReleases();
		foreach ($releases as $release) {
			/* @var $release Release */
			if ($release->getDate() == $string) return $release;
		}
		return null;
	}
	
	/**
	 * @return Release
	 */
	function getGraduationRelease() {
		$releases = array();
		foreach($this->getReleases() as $release) {
			if (preg_match('/(\d+)(\.\d+){1,2}/', $release->getName(), $matches)) {
				$major = $matches[1];
				if ((int)$major > 0) return $release;
			}
		}
		return null;
	}

	/**
	 * @param $name string
	 * @return Release|null
	 */
	function getReleaseNamed($name) {
		$releases = $this->getReleases();
		foreach ($releases as $release) {
			/* @var $release Release */
			if (strcasecmp($release->getName(), $name) == 0) return $release;
		}
		return null;
	}
	
	function hasCommitActivity() {
		foreach($this->getSourceRepositories() as $repository) {
			if ($repository->providesCommitActivity()) return true;
		}
		return false;
	}
	
	/**
	 * This function answers true if the receiver has at least
	 * one source repository specified; it returns false otherwise.
	 * 
	 * @return boolean
	 */
	function hasSourceRepositories() {
		return $this->getSourceRepositories() ? true : false;
	}
	
	function getGitStatus() {
		$types = $this->getSourceRepositoryTypes();
		if (count($types) == 1 && isset($types['git'])) return PROJECT_REPO_ALL_GIT;
		if (isset($types['git']) && count($types) > 1) return PROJECT_REPO_SOME_GIT;
		if (count($types)) return PROJECT_REPO_NO_GIT;
		return PROJECT_REPO_NONE;
	}
	
	/**
	 * This function answers an array of source repository types,
	 * e.g. array('git'=>'git', 'cvs'=>'cvs'). 
	 * 
	 * @return multitype:string
	 */
	function getSourceRepositoryTypes() {
		$types = array();
	
		foreach($this->getSourceRepositories() as $repository) {
			$type = $repository->getType();
			$types[$type] = $type;
		}
	
		return $types;
	}
	
	/**
	 * This function returns a collection of SourceRepository instances,
	 * each representing one of the source repositories associated with
	 * the project. 
	 * 
	 * @return SourceRepository[]
	 */
	function getSourceRepositories() {
		// TODO Cache these results.
		$values = $this->findValues('sourcerepository');
		$repositories = array();
		foreach($values as $repository) {
			if ($sourceRepository = getSourceRepository($repository, $this)) {
				$repositories[$sourceRepository->getName()] = $sourceRepository;
			}
		}
		return $repositories;
	}
	
	function getUniqueSourceRepositories() {
		$repositories = $this->getSourceRepositories();
		$this->removeRedundantRepositories($repositories);
		return $repositories;
	}
	
	/**
	 * @internal
	 * @param SourceRepository[] $repositories
	 */
	function removeRedundantRepositories(&$repositories) {		
		foreach($this->getChildren() as $subproject) {
			foreach($subproject->getUniqueSourceRepositories() as $subrepo) {
				unset($repositories[$subrepo->getName()]);
			}
			$subproject->removeRedundantRepositories($repositories);
		}
	}
	
	function getUpdateSiteUrl() {
		return $this->findFirstValue('updatesiteurl');
	}
	
	function getProjectPhase() {
		return $this->data['ProjectPhase'];
	}
	
	/**
	 * This function answers true if the receiver is marked as
	 * a &quot;Component&quot; in the Eclipse Foundation database.
	 * This is a relatively old concept that predates the 2007 version
	 * of the EDP. Components tend to have their own UNIX groups,
	 * but are considered fully part of the parent project.
	 */
	function isComponent() {
		return $this->data['IsComponent'];
	}
	
	function isActive() {
		return $this->data['IsActive'] == 1;
	}
	
	function isInIncubationPhase() {
		return in_array($this->getProjectPhase(), array('Incubation', 'Incubation.nc'));
	}
	
	function isArchived() {
		return $this->getProjectPhase() == 'Archived';
	}
	
	function isInIncubationConformingPhase() {
		return $this->getProjectPhase() == 'Incubation';
	}

	function isInIncubationNonConformingPhase() {
		return $this->getProjectPhase() == 'Incubation.nc';
	}
	
	function isTopLevel() {
		return !$this->parent;
	}
	
	/**
	 * This function returns an array containing the names of the
	 * simultaneous releases that the receiver participates in.
	 * 
	 * @return string[]
	 */
	function getSimultaneousReleaseNames() {
		$rows = $this->findRows('simultaneousrelease');
		$releases = array();
		foreach ($rows as $row) {
			if ($row['Value'])
				$releases[$row['SubKey']] = true;
		}
		return array_keys($releases);
	}
	
	/**
	 * Returns an instance of SimultaneousReleaseInfo for the receiver,
	 * or <code>null</code> if no information has been provided.
	 * 
	 * @return SimultaneousReleaseInfo
	 */
	function getSimultaneousReleaseInfo($releaseName = null) {
		return getSimultaneousReleaseInfo($this->getId(), $releaseName);
	}
	
	function getLiveliness() {
		$liveliness = PROJECT_LIVELINESS_DEAD;
		foreach($this->getChildren() as $child) {
			$liveliness = min($liveliness, $child->getLiveliness());
		}
		if ($liveliness == PROJECT_LIVELINESS_ACTIVE) return PROJECT_LIVELINESS_ACTIVE;
		if ($this->hasRecentCommitActivity(3)) return PROJECT_LIVELINESS_ACTIVE;
		
		if ($liveliness == PROJECT_LIVELINESS_STALE) return PROJECT_LIVELINESS_STALE;
		if ($this->hasRecentCommitActivity(6)) return PROJECT_LIVELINESS_STALE;
		
		return PROJECT_LIVELINESS_DEAD;
	}
	
	/**
	 * @return int
	 */
	function getActiveCommittersCount() {
		global $App;
	
		$id = $this->getId();
		$result = $App->dashboard_sql("select count(distinct login) as count from ProjectCommitterActivity where project='$id'");
	
		while($row = mysql_fetch_assoc($result)) {
			return (int)$row['count'];
		}
		return 0;
	}	
	
	/**
	 * @return int
	 */
	function getActiveOrganizationsCount() {
		global $App;
	
		$id = $this->getId();
		$result = $App->dashboard_sql("select count(distinct company) as count from ProjectCompanyActivity where project='$id'");

		while($row = mysql_fetch_assoc($result)) {
			return (int)$row['count'];
		}
		return 0;
	}
	
	/**
	 * Answers whether or not the receiver has recent commit activity.
	 * 
	 * @param int $months (Optional) how many months in the past to check.
	 * @return boolean
	 */
	function hasRecentCommitActivity($months = 6) {
		$activity = $this->getCommitActivity();
		$date = strtotime('now');
		while ($months) {
			if ($activity[date('Ym',$date)]) return true;
			$date = strtotime("-1 month", $date);
			$months--;
		}
		return false;
	}
	
	/**
	* Returns the commit activity for the receiver in the form of an 
	* array mapping period to commit count.
	*
	* e.g.,
	*
	* array('201001' => 52, '201002' => 33, ...)
	*
	* Note that this information is cached. The first time this method
	* is called (on any instance), the cache is created.
	*
	* @returns [] array mapping period to commit count.
	*/
	function getCommitActivity() {	
		if (isset($this->_commitActivity)) return $this->_commitActivity;
		
		global $App;
		
		$id = $this->getId();
		$result = $App->dashboard_sql("select period, count from ProjectCommitActivity where project='$id'");

		$this->_commitActivity = array();
		while($row = mysql_fetch_assoc($result)) {
			$this->_commitActivity[$row['period']] = $row['count'];
		}
		return $this->_commitActivity;
	}
	
	/**
	 * Returns the last three month's worth of company commit activity 
	 * for the receiver in the form of an array mapping company name to
	 * commit count.
	 * 
	 * e.g.,
	 * 
	 * array('IBM' => 52, 'Actuate Corporation' => 33)
	 * 
	 * Note that this information is cached. The first time this method 
	 * is called (on any instance), the cache is created.
	 * 
	 * @returns [] array mapping company name to commit count.
	 */
	function getCompanyCommitActivity() {		
		if (isset($this->_companyActivity)) return $this->_companyActivity;
		
		global $App;
		
		$id = $this->getId();
		$result = $App->dashboard_sql("select company, count from ProjectCompanyActivity where project='$id'");

		$this->_companyActivity = array();
		while($row = mysql_fetch_assoc($result)) {
			$this->_companyActivity[$row['company']] = $row['count'];
		}
		return $this->_companyActivity;
	}
	
	/**
	* Returns the last three month's worth of committer commit activity
	* for the receiver in the form of an array mapping committer name to
	* commit count.
	*
	* e.g.,
	*
	* array('Wayne Beaton' => 52, 'Doug Schaefer' => 33)
	*
	* Note that this information is cached. The first time this method
	* is called (on any instance), the cache is created.
	*
	* @returns [] array mapping company name to commit count.
	*/
	function getCommitterCommitActivity() {		
		if (isset($this->_committerActivity)) return $this->_committerActivity;
		
		global $App;
		
		$id = $this->getId();
		$result = $App->dashboard_sql("select login, count from ProjectCommitterActivity where project='$id'");

		$this->_committerActivity = array();
		while($row = mysql_fetch_assoc($result)) {
			$this->_committerActivity[$row['login']] = $row['count'];
		}
		return $this->_committerActivity;
	}
	
	function getLicenses() {
		global $App;
		
		$id = $this->getId();
		
		$sql = "select distinct LicenseId from ProjectLicenses where ProjectId='$id'";
		$result = $App->foundation_sql($sql);
		
		$licenses = array();
		while ($row = mysql_fetch_assoc($result)) {
			$licenses[] = $row['LicenseId'];
		}
		return $licenses;
	}
	
	/*
	 * This function assembles a collection of ProjectInfoValue instances
	 * for the given $key. Essentially, this is an object that represents
	 * a group of values in the receiver and presents a higher-level of
	 * abstraction for accessing those values.
	 * 
	 * Values are stored in the DB in a table like this:
	 * 
	 * +---------------+---------+-----------+----------------------------+
	 * | ProjectInfoID | MainKey | SubKey    | Value                      |
	 * +---------------+---------+-----------+----------------------------+
	 * |...            |         |           |                            |
	 * |8512           |newsgroup|name       |eclipse.examples.users      |
	 * |8512           |newsgroup|type       |main                        |
	 * |8512           |newsgroup|description|A useful newsgroup          |
	 * |9765           |newsgroup|name       |eclipse.examples.dev        |
	 * |9765           |newsgroup|type       |standard                    |
	 * |...            |         |           |                            |
	 * +---------------+---------+-----------+----------------------------+
	 * 
	 * These values are associated with the technology.examples project.
	 * 
	 * If we ask the Project instance to getNewsgroups(), this function will
	 * be invoked and find these five rows. It would, from these rows, create
	 * two instances of ProjectInfoValues: one representing the values for
	 * ProjectInfoID=8512, and a second representing the values for
	 * ProjectInfoID=9765. These instances can then be sent relatively 
	 * high-level messages like getName(), getType(), and getDescription()
	 * to obtain useful information.
	 * 
	 * PRIVATE: THIS FUNCTION IS NOT API.
	 */
	/* private */ function getProjectInfoValues($key) {
		$this->root->load_project_info();
		$infoValues = array();
		foreach($this->values as $value) {
			if ($value['MainKey'] == $key) {
				$id = $value['ProjectInfoID'];
				if (!isset($infoValues[$id])) $infoValues[$id] = new ProjectInfoValue($id, $key, $this);
			}
		}	
		return $infoValues;
	}
	
	/* private */ function findRows($mainkey) {
		$this->root->load_project_info();
		$rows = array();
		foreach($this->values as $row) {
			if ($row['MainKey'] == $mainkey) $rows[] = $row;
		}
		return $rows;
	}
	
	/* private */ function findFirstValue($mainkey, $subkey = '') {
		$this->root->load_project_info();
		foreach($this->values as $row) {
			if ($row['MainKey'] != $mainkey) continue;
			if ($row['SubKey'] != $subkey) continue;
			return trim($row['Value']);
		}
		return null;
	}
	
	/* private */ function findValues($mainkey, $subkey = '') {
		$values = array();
		$this->root->load_project_info();
		foreach($this->values as $row) {
			if ($row['MainKey'] != $mainkey) continue;
			if ($row['SubKey'] != $subkey) continue;
			$values[] = trim($row['Value']);
		}
		return $values;
	}
	
	function isCommitterEmail($address) {
		return true;	
	}
	
	function hasChildren() {
		return $this->children ? true : false;
	}
	
	function getChildren() {
		return $this->children;
	}
	
	/**
	 * Return the people associated with this project. Note that
	 * the value is cached so that subsequent calls return the
	 * same objects.
	 * 
	 * @return Committer[]
	 */
	function getPeople() {
		require_once dirname(__FILE__) . '/Committer.class.php';
		
		if ($this->people === null) 
			$this->people = getCommittersForProject($this->getId());
		
		return $this->people;
	}
	
	/**
	 * Answers <code>true</code> if the receiver's
	 * inherit flag is set (meaning that metadata from the
	 * parent should be inherited), or <code>false</code>
	 * otherwise.
	 */
	function inheritsFromParent() {
		return $this->findFirstValue('inherit', 'inherit');
	}
	
	/**
	 * This function will make sure that the given URL is likely valid by
	 * converting it (if necessary) into an absolute URL. It further checks
	 * to ensure that the URL is from an 'eclipse.org' property.
	 * 
	 * @deprecated Use normalizeFilePathUrl or normalizeHttpUrl
	 * @param A string value representing an absolute or relative URL.
	 * @return A likely valid absolute URL that references an eclipse.org page
	 */
	function normalizeProjectDescriptionUrl($url) {
		return $this->normalizeUrlAsHTTP($url);
	}
	
	/**
	 * This function normalizes the provided URL to an HTTP form. Input
	 * should be a valid eclipse.org URL or a relative URL (with or without
	 * a leading slash).
	 * 
	 * e.g. The following URLs will all normalize to 
	 * http://eclipse.org/woolsey/para.html
	 * 
	 * - http://www.eclipse.org/woolsey/para.html
	 * - http://eclipse.org/woolsey/para.html
	 * - http://localhost/woolsey/para.html
	 * - woolsey/para.html 
	 * - /woolsey/para.html)
	 * 
	 * Note that URLs that do not correspond to eclipse.org addresses, will
	 * result in a <code>null</code> result.
	 * 
	 * Usage: 
	 * 
	 * Project::normalizeHttpUrl('http://www.eclipse.org/woolsey/para.html');
	 * 
	 * @param String $url
	 * @deprecated Use normalizeHttpUrl($url) from common.php
	 */
	public function normalizeHttpUrl($url) {	
		return normalizeHttpUrl($url);
	}
	
	/**
	 * This function normalizes the provided URL to valid file path on the
	 * eclipse.org web directory. Input should be a valid eclipse.org URL 
	 * or a relative URL (with or without a leading slash).
	 * 
	 * e.g. The following URLs will all normalize to 
	 * /home/local/data/httpd/www.eclipse.org/html/woolsey/para.html
	 * 
	 * - http://www.eclipse.org/woolsey/para.html
	 * - http://eclipse.org/woolsey/para.html
	 * - http://localhost/woolsey/para.html
	 * - woolsey/para.html 
	 * - /woolsey/para.html)
	 * 
	 * Note that URLs that do not correspond to eclipse.org addresses, will
	 * result in a <code>null</code> result.
	 * 
	 * Usage: 
	 * 
	 * Project::normalizeFilePathUrl('http://www.eclipse.org/woolsey/para.html');
	 * 
	 * @param String $url
	 * @deprecated Use normalizeFilePathUrl($url) from common.php
	 */
	public function normalizeFilePathUrl($url) {
		return normalizeFilePathUrl($url);
	}
		
	/**
	 * This function normalizes the provided URL to a relative path. 
	 * Input should be a valid eclipse.org URL or a relative URL 
	 * (with or without a leading slash).
	 * 
	 * e.g. The following URLs will all normalize to 
	 * /woolsey/para.html
	 * 
	 * - http://www.eclipse.org/woolsey/para.html
	 * - http://eclipse.org/woolsey/para.html
	 * - http://localhost/woolsey/para.html
	 * - woolsey/para.html 
	 * - /woolsey/para.html)
	 * 
	 * Note that URLs that do not correspond to eclipse.org addresses, will
	 * result in a <code>null</code> result.
	 * 
	 * Usage: 
	 * 
	 * Project::extractcRelativeUrl('http://www.eclipse.org/woolsey/para.html');
	 * 
	 * @param string $url
	 * @deprecated Use normalizeRelativeUrl($url) from common.php
	 */
	public function normalizeRelativeUrl($url) {		
		return normalizeRelativeUrl($url);
	}
	
	/**
	 * PRIVATE - THIS IS NOT API.
	 * 
	 * This method cleans up the description by removing potentially harmful tags.
	 * 
	 * @param string $description
	 */
	function cleanDescription($description) {
		// If we've been given a phoenix page, extract out the interesting bits.
		if(preg_match('/\<div id="midcolumn"\>/s', $description)) {
			$description = preg_replace('/((^.*\<div id="midcolumn"\>)|(\<\/div\>\<div id="footer"\>.*))/s', '', $description);
			$description = substr($description, 0, strripos($description, '</div>'));
		}
		
		return $description;
	}
	
	/**
	 * This function extracts a short description from the provided (potentially)
	 * long one. We attempt to find the first paragraph in what we assume is HTML
	 * text. 
	 * 
	 * @param string $description The (potentially) long description, a string containing HTML.
	 * @param int $maxWords (optional) The maximum number of words in the result.
	 * @return string a string with limited HTML content (no surrounding 'p' tags).
	 */
	function extractShortDescription($description, $maxWords=100) {	
		// Match everything between the first <p> tag and the next </p> or <br> tag.	
		$matches = array();
		if (preg_match('/<p>(.*?)(?:(?:<\/p>)|(?:<br\s*\/?>))/s', $description, $matches)) {
			//print_r($matches);
			$description = $matches[1];
		}
		
		// Kill any tags that might occur in the text.
		$description = preg_replace('/<[^>]*>/', '', $description);
			
		// Restrict the word count in the result.
		$words = str_word_count($description, 2);
		if (count($words) > $maxWords) {
			$indices = array_keys($words);
			$description = substr($description, 0, $indices[$maxWords]) . '...';
		}
		
		return $description;
	}
}

/*
 * Each instance of this class represents a collection of values 
 * from the ProjectInfoValues table that share a common ProjectInfoID and MainKey. 
 * These values are actually stored in an array on the Project instance itself;
 * instances of this class do not store the values themselves, but rather
 * find the values on the Project instance.
 * 
 * Instances can be queried for the values of the various SubKeys in the
 * corresponding values using high-level function names. The function
 * getName(), for example, would return the value in the row with SubKey
 * 'name'.
 * 
 * For more information, see the comment on Project#getProjectInfoValues($key).
 * 
 * THIS CLASS IS NOT INTENDED TO BE INSTANTIATED BY CLIENTS.
 */
class ProjectInfoValue {
	var $id;
	var $key;
	var $project;
	
	function __construct($id, $key, $project) {
		$this->id = $id;
		$this->key = $key;
		$this->project = $project;
	}
	
	function __call($name, $args) {
		$match = array();
		if (preg_match('/^get(.*)$/', $name, $match)) {
			return $this->getValue($match[1]);
		}
	}
		
	/* private */ function getValue($subkey) {
		foreach ($this->project->values as $row) {
			if ($row['MainKey'] != $this->key) continue;
			if ($row['ProjectInfoID'] != $this->id) continue;
			if (strcasecmp($row['SubKey'], $subkey) == 0) return $row['Value'];
		}
		return null;
	}
}

/**
 * We never actually instantiate this class, it is provided to
 * expose API for values returned by the Project#getNewsgroups
 * method. Actual values are instances of ProjectInfoValue and
 * the methods indicated below work through reflection.
 */
abstract class Newsgroup {	
	abstract function getId();
	abstract function getName();
	abstract function getType();
	abstract function getDescription();
}


class Release {	
	var $project;
	var $name;
	var $date;
	
	function __construct($project, $data) {
		$this->project = $project;
		$this->data = $data;
		$name = $data->getValue('name');
		if (preg_match('/(\d+)(\.\d+)?(\.\d+)?[\s\_\-\.]*((M|RC)\d+)?/', $name, $matches)) {
			$name = $matches[1];
			$name .= isset($matches[2]) && $matches[2] ? $matches[2] : '.0';
			$name .= isset($matches[3]) && $matches[3] ? $matches[3] : '.0';
			if (isset($matches[4]) && $matches[4]) $name .= $matches[4];
			$this->name = $name;
		} 
		$this->date = strtotime($data->getValue('date'));
	}
	
	function getReview() {
		foreach($this->project->getReviews() as $review) {
			if (!$review->isRelease()) continue;
			if ($review->getVersion() == $this->name) return $review;
		}
		return null;
	}
	
	function getName() {
		return $this->name;
	}
	
	function isValid() {
		if (!$this->name) return false;
		if (!$this->date) return false;
		if ($this->date < strtotime('2000-01-01')) return false;
		return true;
	}
	
	function isMilestone() {
		return preg_match('/((M|RC)\d+)$/', $this->name);
	}
	
	function getDate() {
		return $this->date;
	}
	
	/**
	 * Fetch the URL for the project plan for this release if it has
	 * been specified. Note that we try to be very forgiving about the format.
	 * 
	 * The following values will all result in a plan URL of "project/plan.xml"
	 * - http://www.eclipse.org/project/plan.xml
	 * - http://eclipse.org/project/plan.xml
	 * - http://www.eclipse.org/projects/project-plan.php?planurl=http://eclipse.org/project/plan.xml
	 * - http://www.eclipse.org/projects/project-plan.php?planurl=/project/plan.xml
	 * - http://www.eclipse.org/projects/project-plan.php?planurl=project/plan.xml
	 * 
	 * @return string
	 */
	function getPlan() {
		$plan = $this->data->getValue('plan');
		if (preg_match('/^(http:\/\/(www\.)?eclipse\.org\/projects\/project-plan\.php\?planurl=)?(http:\/\/(www\.)?eclipse.org)?\/?(.+\.xml)$/', $plan, $matches)) {
			return $matches[5];
		}
		return $plan;
	}
	
	function getStatus() {
		return $this->data->getValue('status');
	}
	
	function getNoteworthyUrl() {
		return $this->data->getValue('noteworthyurl');
	}
	
	function getDownload() {
		return $this->data->getValue('download');
	}
}

abstract class SourceRepository {
	var $project;
	var $path;
	
	function __construct($project, $path) {
		$this->project = $project;
		$this->path = $path;
	}
	
	function getName() {
		return $this->getPath();
	}
	
	function getPath() {
		return $this->path;
	}
	
	function providesCommitActivity() {
		return true;
	}
	
	function isReal() {
		// TODO test to see if the receiver represents a real repository.
		return true;
	}
	
	/**
	 * Get the repository-technology specific URL for the repository.
	 * e.g. git://git.eclipse.org/gitroot/jgit/jgit.git
	 */
	abstract function getUrl();
	abstract function getType();
	
	/**
	 * Return an HTTP link for the receiver. i.e. something that is suitable
	 * for a browser
	 */
	abstract function getLink();
}

class GitRepository extends SourceRepository {
	function getName() {
		if (preg_match('/org\.eclipse\.(.*)\.git$/', $this->path, $matches)) {
			return $matches[1];
		} else if (preg_match('/org\.eclipse\.(.*)$/', $this->path, $matches)) {
			return $matches[1];
		} else if (preg_match('/([^\/]*)\.git$/', $this->path, $matches)) {
			return $matches[1];		
		} else if (preg_match('/([^\/]*)$/', $this->path, $matches)) {
			return $matches[1];
		} else {
			return $this->path;
		}
	}
	
	function getPath() {
		return "/gitroot$this->path";
	}
	
	function getType() {
		return "git";
	}
	
	function getLink() {
		return "http://git.eclipse.org/c$this->path";
	}
	
	function getGitUrl() {
		return "git://git.eclipse.org/gitroot$this->path";
	}
	
	function getUrl() {
		return $this->getGitUrl();
	}
}

class EGitRepository extends GitRepository {	
	
	function getName() {
		return $this->getLink();
	}
	
	function getLink() {
		if (preg_match('/^git:\/\/(egit\.eclipse\.org\/.*)$/', $this->path, $matches)) {
			return 'http://' . $matches[1];
		}
		return $this->path;
	}
	
	function getPath() {
		return $this->getLink();
	}
	
	function getGitUrl() {
		return $this->path;
	}
	
	function providesCommitActivity() {
		return false;
	}
}

class CvsRepository extends SourceRepository  {
	function getType() {
		return "cvs";
	}
	
	function getPath() {
		return "/cvsroot$this->path";
	}
	function getLink() {
		preg_match('/^\/?\w+\/(.*)$/', $this->path, $matches);
		$root = $this->project->getTopLevelProject()->getId();
		if (strlen($root) <= 4) {
			$root = strtoupper($root);
		} else {
			$root = ucwords($root);
		}
		$path = $matches[1];
		return "http://dev.eclipse.org/viewcvs/viewvc.cgi/$path/?root=${root}_Project";
	}
	
	function getUrl() {
		if (preg_match('/^(\/cvsroot\/[^\/]+)\/(.+)$/', $this->getPath(), $matches)) {
			$repository = $matches[1];
			$path = $matches[2];
			
			return ":pserver:anonymous@dev.eclipse.org:$repository:$path";
		} else return null;
	}
}

class SvnRepository extends SourceRepository  {
	function getType() {
		return "svn";
	}
	
	/* private */ function isUppercaseRoot($root) {
		if ($root == 'modeling') return false;
		if ($root == 'technology') return false;
		return true;
	}
	
	function getLink() {
		preg_match('/^[^\/]*\/(.*)$/', $this->path, $matches);
		$root = $this->project->getTopLevelProject()->getId();
		if ($this->isUppercaseRoot($root)) {
			$root = strtoupper($root);
		} else {
			$root = ucwords($root);
		}
		$project = $this->project->getShortId();
		
		// Need to handle a few special cases...
		if ($project == 'swtbot') $project = 'SWTBot';
		else if ($project == 'g-eclipse') $project = 'GEclipse';
		else if ($project == 'eclipselink') $project = 'PERSISTENCE';
		else if ($project == 'dbaccess') $project = 'GEMINI.DBACCESS'; // Bug 369905
		else if ($project == 'naming') $project = 'GEMINI.NAMING';
		else if ($project == 'blueprint') $project = 'GEMINI.BLUEPRINT';
		else if ($project == 'jpa') $project = 'GEMINI.JPA';
		else $project = strtoupper($project);
		
		return "http://dev.eclipse.org/viewcvs/viewvc.cgi/?root=${root}_${project}";
	}
	
	function getUrl() {
		$path = $this->getPath();
		return "http://dev.eclipse.org$path";
	}
	
	function getPath() {
		return "/svnroot/$this->path";
	}
}

/**
 * Sort the array of projects by the given key. Valid keys
 * are 'name', or 'top' (top level project).
 * 
 * @param Project[] $projects
 * @param string $key
 */
function sortProjects(&$projects, $key = 'name') {
	if (!in_array($key, array('name', 'top'))) $key = 'name';
	
	return usort($projects, "_sortProjects_$key");
}

/* private */ function _sortProjects_name($a, $b) {
	return strcasecmp($a->getName(), $b->getName());	
}

/* private */ function _sortProjects_top($a, $b) {
	return strcasecmp($a->getTopLevelProject()->getName(), $b->getTopLevelProject()->getName());	
}

/**
 * This function answers an instance of SourceRepository corresponding to the
 * value of the parameter.
 * 
 * Example:
 * 
 * getSourceRepository('/gitroot/woolsey/org.eclipse.woolsey.iplog.git')
 *  returns an instance of GitRepository
 *  
 * @see SourceRepository
 * @see GitRepository
 * @see EGitRepository
 * @see CvsRepository
 * @see SvnRepository
 *
 * @param string $repository
 * @return SourceRepository
 */
function getSourceRepository($repository, $project=null) {
	global $projectNamePattern;
	
	// We only care about source code repositories, skip websites.
	if (preg_match('/org\.eclipse\/www/', $repository)) return null;
	
	// EGit is a special case.
	if (preg_match('/^git:\/\/egit\.eclipse\.org(\/.*)$/', $repository)) return new EGitRepository($project, $repository);

	// Deal with Git. 
	if (preg_match('/\/gitroot((\/[\w\.\-]+)+)\/?$/', $repository, $matches)) return new GitRepository($project, $matches[1]);
	if (preg_match('/^http:\/\/git\.eclipse\.org\/c(\/.*)$/', $repository)) return new GitRepository($project, $matches[1]);
	
	// Deal with CVS.
	if (preg_match('/^\/cvsroot((\/[\w\-\.]+)+)\/?$/', $repository, $matches)) return new CvsRepository($project, $matches[1]);
	
	// Deal with SVN.  
	if (preg_match('/^(\/?svnroot)?\/?(\w+(\/[\w\-\.]+)+)\/?$/', $repository, $matches)) return new SvnRepository($project, $matches[2]);
	return null;
}

?>