source: sandbox/workflow/branches/609/lib/factory/BaseFactory.php @ 2278

Revision 2278, 4.7 KB checked in by pedroerp, 14 years ago (diff)

Ticket #609 - Corrigindo a passagem de referências de objetos na factory.

  • 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         * @access protected
37         * @return void
38         */
39        protected final function registerFileInfo($className, $fileName, $relativePath, $basePath = WF_SERVER_ROOT) {
40
41                /* default is to override */
42                $this->_fileInfo[$className] = array(   'filename' => $fileName,
43                                                                                                'path' => $relativePath,
44                                                                                                'basePath' => $basePath,
45                                                                                                'instance' => null);
46        }
47
48
49        /**
50         * Here we should do all the factory stuff.
51         * The classes instatiated here will be stored
52         * into our private object cache. If there is no
53         * object of the given type into the cache, 'newInstance'
54         * will be called. This method must deal with
55         * pointers (&) to avoid object duplications.
56         *
57         * @access public
58         * @return object
59         */
60        public function &getInstance($className, $classArgs){
61
62                /* have we a class name? */
63                if (empty($className))
64                        return null;
65
66                /* recovering class data */
67                if ($entry = &$this->_getEntry($className)) {
68
69                        if (is_null($entry['instance'])) {
70
71                                /* we must instantiate it */
72                if (($obj = &$this->newInstance($className, $classArgs)) == null)
73                                        throw new Exception("Unable to instantiate '".$className."'");
74
75                                /* saving the object reference */
76                                $this->_setEntryInstance($className, $obj);
77                                return $obj;
78                        }
79                        return $entry['instance'];
80
81                }
82                /* class not allowed */
83                else
84                        throw new Exception("You are not allowed to instantiate class '".$className."'.");
85        }
86
87        /**
88         * Instantiating classes.
89         *
90         * @todo Maybe we don't have to use the reflection
91         *               class here. Future work...
92         * @access public
93         * @return object
94         */
95        public function &newInstance($className, $classArgs){
96
97                /* have we a class name? */
98                if (empty($className))
99                        return null;
100
101                /* just to be sure. If this method fails, it will throw an exception anyway... */
102                if(!$this->_import($className))
103                        return null;
104
105                /**
106                 * Here we use this big white elephant (by big white elephant I mean php
107                 * reflection interface) just because we have to pass an unknown number
108                 * of parameters to the constructor of the class.
109                 * If you know a better way to do this, please update this code =D
110                 */
111                $reflectionObj = new ReflectionClass($className);
112
113                if (count($classArgs) == 0)
114                        return $reflectionObj->newInstance();
115                return $reflectionObj->newInstanceArgs($classArgs);
116        }
117
118
119        /**
120         * Private stuff. Handles the cache and information
121         * '$_fileInfo' array.
122         *
123         * @access private
124         * @return array
125         */
126        private function &_getEntry($className){
127                return $this->_fileInfo[$className];
128        }
129
130
131        /**
132         * Stores the given object into the internal cache
133         * for upcoming requests.
134         *
135         * @access private
136         * @return boolean
137         */
138        private function _setEntryInstance($className, &$obj){
139
140                if (is_array($this->_fileInfo[$className])) {
141                        $this->_fileInfo[$className]['instance'] = &$obj;
142                        return true;
143                }
144                return false;
145        }
146
147
148        /**
149         * Including (requiring_once ;P ) the file(s) itself. Ideally,
150         * it could be the only place to include files.
151         *
152         * @access private
153         * @return boolean
154         */
155        private function _import($className){
156
157                /* not found */
158                if (!($entry = $this->_getEntry($className)))
159                        throw new Exception('You are not allowed to instantiate \''.$className.'\' class.');
160
161                $fullPath = $entry['basePath'] . '/' . $entry['path'] . '/' . $entry['filename'];
162
163                /* file not found */
164                if (!file_exists($fullPath))
165                        throw new Exception("File '".$fullPath."' not found.");
166
167                /* including file */
168                require_once $fullPath;
169                return true;
170        }
171}
172?>
Note: See TracBrowser for help on using the repository browser.