<commit_before><?php
namespace Exedra\Application\Map;

/**
 * A factory that handle the route/level/finding and http request creation
 * This instance is injected into each level created
 */

class Factory
{
	/**
	 * Loader for lazy loading functionality
	 */
	protected $loader;

	/**
	 * Application instance
	 * @var \Exedra\Application\Application app
	 */
	protected $app;

	protected $registry = array();

	protected $reflections = array();

	/**
	 * Define explicitness of the routing.
	 * @var bool
	 */
	protected $isExplicit = false;

	public function __construct(\Exedra\Application\Application $app)
	{
		$this->app = $app;

		$this->useDefaultRouting();
	}

	/**
	 * Get application loader
	 * @return \Exedra\Loader
	 */
	public function getLoader()
	{
		return $this->app->loader;
	}

	public function isExplicit()
	{
		return $this->isExplicit;
	}

	/**
	 * Register default routing components
	 * @return self
	 */
	public function useDefaultRouting()
	{
		$this->isExplicit = true;

		return $this->register(array(
			'route' => '\Exedra\Application\Map\Route',
			'level' => '\Exedra\Application\Map\Level',
			'finding' => '\Exedra\Application\Map\Finding',
			'request' => '\Exedra\HTTP\ServerRequest',
			'exception' => '\Exception'));
	}

	/**
	 * Register Convenient routing components
	 * @return self
	 */
	public function useConvenientRouting()
	{
		$this->isExplicit = false;

		return $this->register(array(
			'route' => '\Exedra\Application\Map\Convenient\Route',
			'level' => '\Exedra\Application\Map\Convenient\Group'
			));
	}

	/**
	 * Register classname
	 * @param string name
	 * @param string classname
	 */
	public function register(array $registry)
	{
		foreach($registry as $name => $classname)
		{
			$this->registry[$name] = $classname;
			unset($this->reflections[$name]);
		}

		return $this;
	}

	/**
	 * General method to create classes from the registered list.
	 * @param string name
	 * @param array arguments
	 */
	public function create($name, array $arguments = array())
	{
		if(!isset($this->reflections[$name]))
			$this->reflections[$name] = new \ReflectionClass($this->registry[$name]);

		$reflection = $this->reflections[$name];

		return $reflection->newInstanceArgs($arguments);
	}

	/**
	 * Create route object
	 * @param \Exedra\Application\Map\Level level of where the route is based on
	 * @param string route name
	 * @param array parameters route parameter
	 * @return \Exedra\Application\Map\Route
	 */
	public function createRoute(Level $level, $name, array $parameters)
	{
		return $this->create('route', array($level, $name, $parameters));
	}

	/**
	 * Create level object
	 * @param \Exedra\Application\Map\Route route of where the level is based on
	 * @param array of routes
	 * @return \Exedra\Application\Map\Level
	 */
	public function createLevel(Route $route = null, array $routes = array())
	{
		return $this->create('level', array($this, $route, $routes));
		return new Level($this, $route, $routes);
	}

	/**
	 * Create level by pattern
	 * @param \Exedra\Application\Map\Route
	 * @param string pattern
	 * @return \Exedra\Application\Map\Level
	 */
	public function createLevelByPattern(Route $route = null, $pattern)
	{
		// has structure based path
		if(strpos($pattern, ':') !== FALSE)
		{
			list($structure, $path) = explode(':', $pattern);
			$loadParameter = array(
				'structure' => $structure,
				'path' => $path
				);
		}
		else
		{
			$loadParameter = $pattern;
		}

		$subroutes = $this->getLoader()->load($loadParameter);

		return $this->createLevel($route, $subroutes);
	}

	/**
	 * Create finding object
	 * @param \Exedra\Application\Map\Route result's route.
	 * @param array parameters
	 * @param \Exedra\HTTP\Request
	 * @return \Exedra\Application\Map\Finding
	 */
	public function createFinding(Route $route = null, array $parameters = null, \Exedra\HTTP\ServerRequest $request = null)
	{<commit_msg>path based subroutes now accept on \Closure<commit_after><?php
namespace Exedra\Application\Map;

/**
 * A factory that handle the route/level/finding and http request creation
 * This instance is injected into each level created
 */

class Factory
{
	/**
	 * Loader for lazy loading functionality
	 */
	protected $loader;

	/**
	 * Application instance
	 * @var \Exedra\Application\Application app
	 */
	protected $app;

	protected $registry = array();

	protected $reflections = array();

	/**
	 * Define explicitness of the routing.
	 * @var bool
	 */
	protected $isExplicit = false;

	public function __construct(\Exedra\Application\Application $app)
	{
		$this->app = $app;

		$this->useDefaultRouting();
	}

	/**
	 * Get application loader
	 * @return \Exedra\Loader
	 */
	public function getLoader()
	{
		return $this->app->loader;
	}

	public function isExplicit()
	{
		return $this->isExplicit;
	}

	/**
	 * Register default routing components
	 * @return self
	 */
	public function useDefaultRouting()
	{
		$this->isExplicit = true;

		return $this->register(array(
			'route' => '\Exedra\Application\Map\Route',
			'level' => '\Exedra\Application\Map\Level',
			'finding' => '\Exedra\Application\Map\Finding',
			'request' => '\Exedra\HTTP\ServerRequest',
			'exception' => '\Exception'));
	}

	/**
	 * Register Convenient routing components
	 * @return self
	 */
	public function useConvenientRouting()
	{
		$this->isExplicit = false;

		return $this->register(array(
			'route' => '\Exedra\Application\Map\Convenient\Route',
			'level' => '\Exedra\Application\Map\Convenient\Group'
			));
	}

	/**
	 * Register classname
	 * @param string name
	 * @param string classname
	 */
	public function register(array $registry)
	{
		foreach($registry as $name => $classname)
		{
			$this->registry[$name] = $classname;
			unset($this->reflections[$name]);
		}

		return $this;
	}

	/**
	 * General method to create classes from the registered list.
	 * @param string name
	 * @param array arguments
	 */
	public function create($name, array $arguments = array())
	{
		if(!isset($this->reflections[$name]))
			$this->reflections[$name] = new \ReflectionClass($this->registry[$name]);

		$reflection = $this->reflections[$name];

		return $reflection->newInstanceArgs($arguments);
	}

	/**
	 * Create route object
	 * @param \Exedra\Application\Map\Level level of where the route is based on
	 * @param string route name
	 * @param array parameters route parameter
	 * @return \Exedra\Application\Map\Route
	 */
	public function createRoute(Level $level, $name, array $parameters)
	{
		return $this->create('route', array($level, $name, $parameters));
	}

	/**
	 * Create level object
	 * @param \Exedra\Application\Map\Route route of where the level is based on
	 * @param array of routes
	 * @return \Exedra\Application\Map\Level
	 */
	public function createLevel(Route $route = null, array $routes = array())
	{
		return $this->create('level', array($this, $route, $routes));
		return new Level($this, $route, $routes);
	}

	/**
	 * Create level by pattern
	 * @param \Exedra\Application\Map\Route
	 * @param string pattern
	 * @return \Exedra\Application\Map\Level
	 */
	public function createLevelByPattern(Route $route = null, $pattern)
	{
		// has structure based path
		if(strpos($pattern, ':') !== FALSE)
		{
			list($structure, $path) = explode(':', $pattern);
			$loadParameter = array(
				'structure' => $structure,
				'path' => $path
				);
		}
		else
		{
			$loadParameter = $pattern;
		}

		$closure = $this->getLoader()->load($loadParameter);

		// expecting a Map\Level from this loaded file.
		if(!($closure instanceof \Closure))
			return $this->throwException('Expecting closure for the subroutes');

		$level = $this->createLevel($route);

		$closure($level);

		return $level;
	}

	/**
	 * Create finding object
	 * @param \Exedra\Application\Map\Route result's route.
	 * @param array parameters
	 * @param \Exedra\HTTP\Request
	 * @return \Exedra\Application\Map\Finding
	 */
	public function createFinding(Route $route = null, array $parameters = null, \Exedra\HTTP\ServerRequest $request = null)
	{
{'fraction_non_alphanumeric': 0.14912935323383084, 'fraction_numerical': 0.0, 'mean_word_length': 3.6695702671312427, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 66, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4103260', 'n_tokens_mistral': 2742, 'n_tokens_neox': 2462, 'n_words': 632}