/[Frey]/trunk/static/lib/Joose/Builder.js
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/static/lib/Joose/Builder.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 46 - (show annotations)
Wed Jul 2 10:28:49 2008 UTC (15 years, 10 months ago) by dpavlin
File MIME type: application/javascript
File size: 13601 byte(s)
added upstream Joose r4755

http://code2.0beta.co.uk/moose/svn/Joose/trunk/lib
1 // Could be refactored to a Joose.Class (by manually building the class)
2
3 /**
4 * Assorted tools to build a class
5 *
6 * The functions Class(), Module() and joosify() are global. All other methods
7 * may be used inside Class definitons like this:
8 *
9 * <pre>
10 * Module("com.test.me", function () {
11 * Class("MyClass", {
12 * isa: SuperClass,
13 * methods: {
14 * hello: function () { alert('world') }
15 * }
16 * })
17 * })
18 * </pre>
19 * @constructor
20 */
21 Joose.Builder = function () {
22 /** @ignore */
23 this.globalize = function () {
24 Joose.O.each(Joose.Builder.Globals, function (func, name) {
25 joose.top[name] = func
26 });
27 }
28 }
29
30 /** @ignore */
31 Joose.Builder.Globals = {
32 /**
33 * Global function that creates or extends a module
34 * @function
35 * @param name {string} Name of the module
36 * @param functionThatCreatesClassesAndRoles {function} Pass a function reference that calls Class(...) as often as you want. The created classes will be put into the module
37 * @name Module
38 */
39 /** @ignore */
40 Module: function (name, functionThatCreatesClassesAndRoles) {
41 return Joose.Module.setup(name, functionThatCreatesClassesAndRoles)
42 },
43
44 Role: function (name, props) {
45 if(!props.meta) {
46 props.meta = Joose.Role;
47 }
48 return Class(name, props)
49 },
50
51 Prototype: function (name, props) {
52 if(!props.meta) {
53 props.meta = Joose.Prototype;
54 }
55 return Class(name, props);
56 },
57
58 /**
59 * Global function that creates a class (If the class already exists it will be extended)
60 * @function
61 * @param name {string} Name of the the class
62 * @param props {object} Declaration if the class. The object keys are used as builder methods. The values are passed as arguments to the builder methods.
63 * @name Class
64 */
65 /** @ignore */
66 Class: function (name, props) {
67
68 var c = null;
69
70 if(name) {
71 var className = name;
72 if(joose.currentModule) {
73 className = joose.currentModule.getName() + "." + name
74 }
75 var root = joose.top;
76 var parts = className.split(".")
77
78 for(var i = 0; i < parts.length; i++) {
79 root = root[parts[i]]
80 }
81 c = root;
82 }
83
84 if(c == null) {
85
86 var metaClass;
87
88 /* Use the custom meta class if provided */
89 if(props && props.meta) {
90 metaClass = props.meta
91 delete props.meta
92 }
93 /* Otherwise use the meta class of the parent class (If there is one)
94 * If the parent class is Joose.Class, we don't change the meta class but use the default
95 * because that Joose.Class's meta class is only needed for bootstrapping
96 * purposes. */
97 else if(props && props.isa && props.isa != Joose.Class) {
98 metaClass = props.isa.meta.builder
99 //alert(name + metaClass + props.isa.meta)
100 }
101 /* Default meta class is Joose.Class */
102 else {
103 metaClass = Joose.Class;
104 }
105
106 var aClass = new metaClass();
107
108 aClass.builder = metaClass;
109
110 var c = aClass.createClass(name, null, joose.currentModule)
111
112 c.meta.builder = metaClass
113
114 var className = c.meta.className()
115
116 if(name && className) {
117 var root = joose.top;
118 var n = new String(className);
119 var parts = n.split(".");
120 for(var i = 0; i < parts.length - 1; i++) {
121 if(root[parts[i]] == null) {
122 root[parts[i]] = {};
123 }
124 root = root[parts[i]];
125 }
126 root[parts[parts.length - 1]] = c
127 }
128
129 }
130 joose.cc = c;
131 if(props) {
132 Joose.O.each(props, function (value, name) {
133 var builder = Joose.Builder.Builders[name];
134 if(!builder) {
135 throw new Error("Called invalid builder "+name+" while creating class "+c.meta.className())
136 }
137 var paras = value;
138 //if(! (paras instanceof Array )) {
139 // paras = [value]
140 //}
141 builder.call(Joose.Builder, paras)
142 })
143
144 c.meta.validateClass()
145
146 c.meta.buildComplete()
147 }
148
149 return c
150 },
151
152 Type: function (name, props) {
153 var t = Joose.TypeConstraint.newFromTypeBuilder(name, props);
154
155 var m = joose.currentModule
156
157 if(!m) {
158 Module("TYPE")
159 m = TYPE.meta;
160 }
161
162 m.addElement(t)
163 m.getContainer()[name] = t;
164 return t
165 },
166
167 /**
168 * Global function to turn a regular JavaScript constructor into a Joose.Class
169 * @function
170 * @param name {string} Name of the class
171 * @param props {function} The constructor
172 * @name joosify
173 */
174 /** @ignore */
175 joosify: function (standardClassName, standardClassObject) {
176 var c = standardClassObject;
177 var metaClass = new Joose.Class();
178 metaClass.builder = Joose.Class;
179
180 c.toString = function () { return joose.cc.meta.className() }
181 c = metaClass.createClass(standardClassName, c)
182
183 var meta = c.meta;
184
185 for(var name in standardClassObject.prototype) {
186 if(name == "meta") {
187 continue
188 }
189 var value = standardClassObject.prototype[name]
190 if(typeof(value) == "function") {
191 meta.addMethod(name, value)
192 } else {
193 var props = {};
194 if(typeof(value) != "undefined") {
195 props.init = value
196 }
197 meta.addAttribute(name, props)
198 }
199 }
200
201 return c
202 },
203
204 /** @ignore */
205 rw: "rw",
206 /** @ignore */
207 ro: "ro"
208 };
209 Joose.Builder.Builders = {
210
211 isAbstract: function (bool) {
212 joose.cc.meta.isAbstract = bool
213 },
214
215 /**
216 * Tells a role that the method name must be implemented by all classes that implement joose.cc role
217 * @function
218 * @param methodName {string} Name of the required method name
219 * @name requires
220 * @memberof Joose.Builder
221 */
222 /** @ignore */
223 requires: function (methodName) {
224 if(!joose.cc.meta.meta.isa(Joose.Role)) { // XXX should joose.cc be does?
225 throw("Keyword 'requires' only available classes with a meta class of type Joose.Role")
226 }
227 if(methodName instanceof Array) {
228 Joose.A.each(methodName, function (name) {
229 joose.cc.meta.addRequirement(name)
230 })
231 } else {
232 joose.cc.meta.addRequirement(methodName)
233 }
234 },
235
236 /**
237 * Class builder method
238 * Defines the super class of the class
239 * @function
240 * @param classObject {Joose.Class} The super class
241 * @name isa
242 * @memberof Joose.Builder
243 */
244 /** @ignore */
245 isa: function (classObject) {
246 joose.cc.meta.addSuperClass(classObject)
247 },
248 /**
249 * Class builder method
250 * Defines a role for the class
251 * @function
252 * @param classObject {Joose.Role} The role
253 * @name does
254 * @memberof Joose.Builder
255 */
256 /** @ignore */
257 does: function (role) {
258 if(role instanceof Array) {
259 Joose.A.each(role, function (aRole) {
260 joose.cc.meta.addRole(aRole)
261 })
262 } else {
263 joose.cc.meta.addRole(role)
264 }
265
266 },
267
268 /**
269 * Class builder method
270 * Defines attributes for the class
271 * @function
272 * @param classObject {object} Maps attribute names to properties (See Joose.Attribute)
273 * @name has
274 * @memberof Joose.Builder
275 */
276 /** @ignore */
277 has: function (map) {
278 if(typeof map == "string") {
279 var name = arguments[0];
280 var props = arguments[1];
281 joose.cc.meta.addAttribute(name, props)
282 } else { // name is a map
283 var me = joose.cc;
284 Joose.O.each(map, function (props, name) {
285 me.meta.addAttribute(name, props)
286 })
287 }
288 },
289
290 /**
291 * @ignore
292 */
293 method: function (name, func, props) {
294 joose.cc.meta.addMethod(name, func, props)
295 },
296
297 /**
298 * Class builder method
299 * Defines methods for the class
300 * @function
301 * @param classObject {object} Maps method names to function bodies
302 * @name methods
303 * @memberof Joose.Builder
304 */
305 /** @ignore */
306 methods: function (map) {
307 var me = joose.cc
308 Joose.O.each(map, function (func, name) {
309 me.meta.addMethod(name, func)
310 })
311 },
312
313 /**
314 * Class builder method
315 * Defines class methods for the class
316 * @function
317 * @param classObject {object} Maps class method names to function bodies
318 * @name classMethods
319 * @memberof Joose.Builder
320 */
321 /** @ignore */
322 classMethods: function (map) {
323 var me = joose.cc
324 Joose.O.each(map, function (func, name2) {
325 me.meta.addMethodObject(new Joose.ClassMethod(name2, func))
326 })
327 },
328
329 /**
330 * Class builder method
331 * Defines workers for the class (The class must have the meta class Joose.Gears)
332 * @function
333 * @param classObject {object} Maps method names to function bodies
334 * @name workers
335 * @memberof Joose.Builder
336 */
337 /** @ignore */
338 workers: function (map) {
339 var me = joose.cc
340 Joose.O.each(map, function (func, name) {
341 me.meta.addWorker(name, func)
342 })
343 },
344
345 /**
346 * Class builder method
347 * Defines before method modifieres for the class.
348 * The defined method modifiers will be called before the method of the super class.
349 * The return value of the method modifier will be ignored
350 * @function
351 * @param classObject {object} Maps method names to function bodies
352 * @name before
353 * @memberof Joose.Builder
354 */
355 /** @ignore */
356 before: function(map) {
357 var me = joose.cc
358 Joose.O.each(map, function (func, name) {
359 me.meta.wrapMethod(name, "before", func);
360 })
361 },
362
363 /**
364 * Class builder method
365 * Defines after method modifieres for the class.
366 * The defined method modifiers will be called after the method of the super class.
367 * The return value of the method modifier will be ignored
368 * @function
369 * @param classObject {object} Maps method names to function bodies
370 * @name after
371 * @memberof Joose.Builder
372 */
373 /** @ignore */
374 after: function(map) {
375 var me = joose.cc
376 Joose.O.each(map, function (func, name) {
377 me.meta.wrapMethod(name, "after", func);
378 })
379 },
380
381 /**
382 * Class builder method
383 * Defines around method modifieres for the class.
384 * The defined method modifiers will be called instead of the method of the super class.
385 * The orginial function is passed as an initial parameter to the new function
386 * @function
387 * @param classObject {object} Maps method names to function bodies
388 * @name around
389 * @memberof Joose.Builder
390 */
391 /** @ignore */
392 around: function(map) {
393 var me = joose.cc
394 Joose.O.each(map, function (func, name) {
395 me.meta.wrapMethod(name, "around", func);
396 })
397 },
398
399 /**
400 * Class builder method
401 * Defines override method modifieres for the class.
402 * The defined method modifiers will be called instead the method of the super class.
403 * You can call the method of the super class by calling joose.cc.SUPER(para1, para2)
404 * @function
405 * @param classObject {object} Maps method names to function bodies
406 * @name override
407 * @memberof Joose.Builder
408 */
409 /** @ignore */
410 override: function(map) {
411 var me = joose.cc
412 Joose.O.each(map, function (func, name) {
413 me.meta.wrapMethod(name, "override", func);
414 })
415 },
416
417 /**
418 * Class builder method
419 * Defines augment method modifieres for the class.
420 * These method modifiers will be called in "most super first" order
421 * The methods may call this.INNER() to call the augement method in it's sup class.
422 * @function
423 * @param classObject {object} Maps method names to function bodies
424 * @name augment
425 * @memberof Joose.Builder
426 */
427 /** @ignore */
428 augment: function(map) {
429 var me = joose.cc
430 Joose.O.each(map, function (func, name) {
431 me.meta.wrapMethod(name, "augment", func, function () {
432 me.meta.addMethod(name, func)
433 });
434 })
435 },
436
437 /**
438 * @ignore
439 */
440 decorates: function(map) {
441 var me = joose.cc
442 Joose.O.each(map, function (classObject, attributeName) {
443 me.meta.decorate(classObject, attributeName)
444 })
445 }
446
447 };
448
449 joose.init();

  ViewVC Help
Powered by ViewVC 1.1.26