source: branches/2.2/workflow/lib/factory/BaseFactory.php @ 3167

Revision 3167, 5.4 KB checked in by viani, 14 years ago (diff)

Ticket #1135 - Merged r1990:3166 from /trunk/workflow into /branches/2.2/workflow

  • Property svn:executable set to *
Line 
1<?php
2/**************************************************************************\
3* eGroupWare                                                               *
4* http://www.egroupware.org                                                *
5* --------------------------------------------                             *
6*  This program is free software; you can redistribute it and/or modify it *
7*  under the terms of the GNU General Public License as published by the   *
8*  Free Software Foundation; either version 2 of the License, or (at your  *
9*  option) any later version.                                              *
10\**************************************************************************/
11
12/**
13 * Base Factory abstract class.
14 * This class implements all the common behaviour of
15 * it's specialized classes (ProcessFactory and WorkflowFactory).
16 * The only class allowed to use it's methods should be the
17 * Factory frontend.
18 *
19 * @package Factory
20 * @license http://www.gnu.org/copyleft/gpl.html GPL
21 * @author Pedro Eugênio Rocha - pedro.eugenio.rocha@gmail.com
22 */
23abstract class BaseFactory {
24
25        /**
26         * @var array $_fileInfo Store what classes we can instantiate.
27         * @access private
28         */
29        private $_fileInfo;
30
31
32        /**
33         * Registers classes into '$_fileInfo' private
34         * atribute.
35         *
36         * @param string $className Class name.
37         * @param string $fileName Name of the file that contains the class definition.
38         * @param string $relativePath The path to the file, relative to $basePath.
39         * @param string $basePath Base path to append $relativePath. Optional.
40         * @access protected
41         * @return void
42         */
43        protected final function registerFileInfo($className, $fileName, $relativePath, $basePath = WF_SERVER_ROOT) {
44
45                /* default is to override */
46                $this->_fileInfo[$className] = array(   'filename' => $fileName,
47                                                                                                'path' => $relativePath,
48                                                                                                'basePath' => $basePath,
49                                                                                                'instance' => null);
50        }
51
52
53        /**
54         * Here we should do all the factory stuff.
55         * The classes instatiated here will be stored
56         * into our private object cache. If there is no
57         * object of the given type into the cache, 'newInstance'
58         * will be called. This method must deal with
59         * pointers (&) to avoid object duplications.
60         *
61         * @param string $className Name of the class.
62         * @param array $classArgs Parameters to the class's constructor.
63         * @access public
64         * @return object
65         */
66        public function &getInstance($className, $classArgs){
67
68                /* have we a class name? */
69                if (empty($className))
70                        return null;
71
72                /* recovering class data */
73                if ($entry = &$this->_getEntry($className)) {
74
75                        if (is_null($entry['instance'])) {
76
77                                /* we must instantiate it */
78                if (($obj = &$this->newInstance($className, $classArgs)) == null)
79                                        throw new Exception("Unable to instantiate '".$className."'");
80
81                                /* saving the object reference */
82                                $this->_setEntryInstance($className, $obj);
83                                return $obj;
84                        }
85                        return $entry['instance'];
86
87                }
88                /* class not allowed */
89                else
90                        throw new Exception("You are not allowed to instantiate class '".$className."'.");
91        }
92
93        /**
94         * Instantiating classes.
95         *
96         * @todo Maybe we don't have to use the reflection
97         *               class here. Future work...
98         * @param string $className Name of the class.
99         * @param array $classArgs Parameters to the class's constructor.
100         * @access public
101         * @return object
102         */
103        public function &newInstance($className, $classArgs){
104
105                /* have we a class name? */
106                if (empty($className))
107                        return null;
108
109                /* just to be sure. If this method fails, it will throw an exception anyway... */
110                if(!$this->_import($className))
111                        return null;
112
113                /**
114                 * Here we use this big white elephant (by big white elephant I mean php
115                 * reflection interface) just because we have to pass an unknown number
116                 * of parameters to the constructor of the class.
117                 * If you know a better way to do this, please update this code =D
118                 */
119                $reflectionObj = new ReflectionClass($className);
120
121                if (count($classArgs) == 0)
122                        return $reflectionObj->newInstance();
123                return $reflectionObj->newInstanceArgs($classArgs);
124        }
125
126
127        /**
128         * Private stuff. Handles the cache and information
129         * '$_fileInfo' array.
130         *
131         * @param string $className Key to search for into the internal cache.
132         * @access private
133         * @return array
134         */
135        private function &_getEntry($className){
136                return $this->_fileInfo[$className];
137        }
138
139
140        /**
141         * Stores the given object into the internal cache
142         * for upcoming requests.
143         *
144         * @param string $className Name of the class.
145         * @param object Object whose reference will be stored.
146         * @access private
147         * @return boolean
148         */
149        private function _setEntryInstance($className, &$obj){
150
151                if (is_array($this->_fileInfo[$className])) {
152                        $this->_fileInfo[$className]['instance'] = &$obj;
153                        return true;
154                }
155                return false;
156        }
157
158
159        /**
160         * Including (requiring_once ;P ) the file(s) itself. Ideally,
161         * it could be the only place to include files.
162         *
163         * @param string $className Key to search for into internal cache.
164         * @access private
165         * @return boolean
166         */
167        private function _import($className){
168
169                /* not found */
170                if (!($entry = $this->_getEntry($className)))
171                        throw new Exception('You are not allowed to instantiate \''.$className.'\' class.');
172
173                $fullPath = $entry['basePath'] . '/' . $entry['path'] . '/' . $entry['filename'];
174
175                /* file not found */
176                if (!file_exists($fullPath))
177                        throw new Exception("File '".$fullPath."' not found.");
178
179                /* including file */
180                require_once $fullPath;
181                return true;
182        }
183}
184?>
Note: See TracBrowser for help on using the repository browser.