1 /* ************************************************************************
3 qooxdoo - the new era of web development
8 2004-2007 1&1 Internet AG, Germany, http://www.1and1.org
11 LGPL: http://www.gnu.org/licenses/lgpl.html
12 EPL: http://www.eclipse.org/org/documents/epl-v10.php
13 See the LICENSE file in the project's top-level directory for details.
16 * Sebastian Werner (wpbasti)
17 * Andreas Ecker (ecker)
19 ************************************************************************ */
21 /* ************************************************************************
25 #resource(static:static)
27 ************************************************************************ */
30 * The qooxdoo root class. All other classes are direct or indirect subclasses of this one.
32 * This class contains methods for:
34 * <li> object management (creation and destruction) </li>
35 * <li> logging & debugging </li>
36 * <li> generic getter/setter </li>
37 * <li> user data </li>
39 * <li> internationalization </li>
42 * @param vAutoDispose {Boolean ? true} whether the object should be automatically disposed
44 qx.OO.defineClass("qx.core.Object", Object,
45 function(vAutoDispose)
47 this._hashCode = qx.core.Object._availableHashCode++;
49 if (vAutoDispose !== false)
51 this._dbKey = qx.core.Object._db.length;
52 qx.core.Object._db.push(this);
58 ---------------------------------------------------------------------------
60 ---------------------------------------------------------------------------
63 qx.Settings.setDefault("enableDisposerDebug", false);
69 /* ************************************************************************
70 Class data, properties and methods
71 ************************************************************************ */
73 qx.Class._availableHashCode = 0;
75 qx.Class._disposeAll = false;
79 * Returns an unique identifier for the given object. If such an identifier
80 * does not yet exist, create it.
82 * @param o {Object} the Object to get the hashcode for
83 * @return {Integer} unique identifier for the given object
85 qx.Class.toHashCode = function(o)
87 if(o._hashCode != null) {
91 return o._hashCode = qx.core.Object._availableHashCode++;
96 * Destructor. This method is called by qooxdoo on object destruction.
98 * Any class that holds resources like links to DOM nodes must overwrite
99 * this method and free these resources.
101 qx.Class.dispose = function()
103 // var logger = qx.log.Logger.getClassLogger(qx.core.Object);
104 // logger.debug("Disposing Application");
106 // var vStart = (new Date).valueOf();
107 qx.core.Object._disposeAll = true;
110 for (var i=qx.core.Object._db.length-1; i>=0; i--)
112 vObject = qx.core.Object._db[i];
114 if (vObject && vObject._disposed === false)
116 // logger.debug("Disposing: " + vObject);
121 // logger.debug("Done in: " + ((new Date).valueOf() - vStart) + "ms");
126 * Summary of allocated objects
128 * @return {String} summary of allocated objects.
130 qx.Class.summary = function()
136 for (var i=qx.core.Object._db.length-1; i>=0; i--)
138 vObject = qx.core.Object._db[i];
140 if (vObject && vObject._disposed === false)
142 if (vData[vObject.classname] == null)
144 vData[vObject.classname] = 1;
148 vData[vObject.classname]++;
157 for (var vClassName in vData) {
158 vArrData.push({ classname : vClassName, number : vData[vClassName] });
161 vArrData.sort(function(a, b) {
162 return b.number - a.number;
165 var vMsg = "Summary: (" + vCounter + " Objects)\n\n";
167 for (var i=0; i<vArrData.length; i++) {
168 vMsg += vArrData[i].number + ": " + vArrData[i].classname + "\n";
175 * Enable or disable the Object.
177 * The actual semantic of this property depends on concrete subclass of qx.core.Object.
179 qx.OO.addProperty({ name : "enabled", type : "boolean", defaultValue : true, getAlias : "isEnabled" });
186 /* ************************************************************************
187 Instance data, properties and methods
188 ************************************************************************ */
191 ---------------------------------------------------------------------------
193 ---------------------------------------------------------------------------
197 * Returns a string represantation of the qooxdoo object.
199 * @return {String} string representation of the object
201 qx.Proto.toString = function()
204 return "[object " + this.classname + "]";
207 return "[object Object]";
212 * Return unique hash code of object
214 * @return {Integer} unique hash code of the object
216 qx.Proto.toHashCode = function() {
217 return this._hashCode;
222 * Returns true if the object is disposed.
224 * @return {Boolean} wether the object has been disposed
226 qx.Proto.getDisposed = function() {
227 return this._disposed;
232 * Returns true if the object is disposed.
234 * @return {Boolean} wether the object has been disposed
236 qx.Proto.isDisposed = function() {
237 return this._disposed;
242 * Returns a settings from global setting definition
244 * @param vKey {String} the key
245 * @return {Object} value of the global setting
247 qx.Proto.getSetting = function(vKey) {
248 return qx.Settings.getValueOfClass(this.classname, vKey);
253 ---------------------------------------------------------------------------
255 ---------------------------------------------------------------------------
259 * Translate a message
260 * Mark the message for translation.
261 * @see qx.lang.String.format
263 * @param messageId {String} message id (may contain format strings)
264 * @param varargs {Object} variable number of argumes applied to the format string
265 * @return {qx.locale.LocalizedString}
267 qx.Proto.tr = function(messageId, varargs) {
268 var nlsManager = qx.locale.Manager;
269 return nlsManager.tr.apply(nlsManager, arguments);
274 * Translate a plural message
275 * Mark the messages for translation.
277 * Depending on the third argument the plursl or the singular form is chosen.
279 * @see qx.lang.String.format
281 * @param singularMessageId {String} message id of the singular form (may contain format strings)
282 * @param pluralMessageId {String} message id of the plural form (may contain format strings)
283 * @param count {Integer} if greater than 1 the plural form otherwhise the singular form is returned.
284 * @param varargs {Object} variable number of argumes applied to the format string
285 * @return {qx.locale.LocalizedString)
287 qx.Proto.trn = function(singularMessageId, pluralMessageId, count, varargs) {
288 var nlsManager = qx.locale.Manager;
289 return nlsManager.trn.apply(nlsManager, arguments);
294 * Mark the message for translation but return the original message.
296 * @param messageId {String} the message ID
297 * @return {String} messageId
299 qx.Proto.marktr = function(messageId) {
300 var nlsManager = qx.locale.Manager;
301 return nlsManager.marktr.apply(nlsManager, arguments);
305 ---------------------------------------------------------------------------
307 ---------------------------------------------------------------------------
311 * Returns the logger of this class.
313 * @return {qx.log.Logger} the logger of this class.
315 qx.Proto.getLogger = function() {
316 return qx.log.Logger.getClassLogger(this.constructor);
321 * Logs a debug message.
323 * @param msg {var} the message to log. If this is not a string, the
324 * object dump will be logged.
325 * @param exc {var ? null} the exception to log.
327 qx.Proto.debug = function(msg, exc) {
328 this.getLogger().debug(msg, this._hashCode, exc);
333 * Logs an info message.
335 * @param msg {var} the message to log. If this is not a string, the
336 * object dump will be logged.
337 * @param exc {var ? null} the exception to log.
339 qx.Proto.info = function(msg, exc) {
340 this.getLogger().info(msg, this._hashCode, exc);
345 * Logs a warning message.
347 * @param msg {var} the message to log. If this is not a string, the
348 * object dump will be logged.
349 * @param exc {var ? null} the exception to log.
351 qx.Proto.warn = function(msg, exc) {
352 this.getLogger().warn(msg, this._hashCode, exc);
357 * Logs an error message.
359 * @param msg {var} the message to log. If this is not a string, the
360 * object dump will be logged.
361 * @param exc {var ? null} the exception to log.
363 qx.Proto.error = function(msg, exc) {
364 this.getLogger().error(msg, this._hashCode, exc);
371 ---------------------------------------------------------------------------
372 COMMON SETTER/GETTER SUPPORT
373 ---------------------------------------------------------------------------
377 * Sets multiple properties at once by using a property list
379 * @param propertyValues {Object} A hash of key-value pairs.
381 qx.Proto.set = function(propertyValues)
383 if (typeof propertyValues !== "object") {
384 throw new Error("Please use a valid hash of property key-values pairs.");
387 for (var prop in propertyValues)
391 this[qx.OO.setter[prop]](propertyValues[prop]);
395 this.error("Setter of property '" + prop + "' returned with an error", ex);
403 * Gets multiple properties at once by using a property list
405 * @param propertyNames {String | Array | Map} list of the properties to get
406 * @param outputHint {String ? "array"} how should the values be returned. Possible values are "hash" and "array".
408 qx.Proto.get = function(propertyNames, outputHint)
410 switch(typeof propertyNames)
413 return this["get" + qx.lang.String.toFirstUp(propertyNames)]();
416 if (typeof propertyNames.length === "number")
418 if (outputHint == "hash")
422 propertyLength = propertyNames.length;
423 for (var i=0; i<propertyLength; i++)
426 h[propertyNames[i]] = this["get" + qx.lang.String.toFirstUp(propertyNames[i])]();
430 throw new Error("Could not get a valid value from property: " + propertyNames[i] + "! Is the property existing? (" + ex + ")");
438 propertyLength = propertyNames.length;
439 for (var i=0; i<propertyLength; i++)
442 propertyNames[i] = this["get" + qx.lang.String.toFirstUp(propertyNames[i])]();
446 throw new Error("Could not get a valid value from property: " + propertyNames[i] + "! Is the property existing? (" + ex + ")");
450 return propertyNames;
455 for (var i in propertyNames) {
456 propertyNames[i] = this["get" + qx.lang.String.toFirstUp(i)]();
459 return propertyNames;
463 throw new Error("Please use a valid array, hash or string as parameter!");
472 ---------------------------------------------------------------------------
474 ---------------------------------------------------------------------------
478 * Store user defined data inside the object.
480 * @param vKey {String} the key
481 * @param vValue {Object} the value of the user data
483 qx.Proto.setUserData = function(vKey, vValue)
485 if (!this._userData) {
489 this._userData[vKey] = vValue;
494 * Load user defined data from the object
496 * @param vKey {String} the key
497 * @return {Object} the user data
499 qx.Proto.getUserData = function(vKey)
501 if (!this._userData) {
505 return this._userData[vKey];
514 ---------------------------------------------------------------------------
516 ---------------------------------------------------------------------------
519 qx.Proto._disposed = false;
522 * Dispose this object
524 qx.Proto.dispose = function()
526 if (this.getDisposed()) {
533 for(var vKey in this._userData) {
534 this._userData[vKey] = null;
537 this._userData = null;
540 // Finally cleanup properties
541 if (this._objectproperties)
543 var a = this._objectproperties.split(",");
544 var d = qx.OO.values;
546 for (var i=0, l=a.length; i<l; i++) {
547 this[d[a[i]]] = null;
550 this._objectproperties = null;
553 if (this.getSetting("enableDisposerDebug"))
555 for (var vKey in this)
557 if (this[vKey] !== null && typeof this[vKey] === "object")
559 this.debug("Missing class implementation to dispose: " + vKey);
566 if (typeof CollectGarbage === "function") {
573 if(this._dbKey != this._hashCode) {
574 console.log("Disposing wrong entry: " + this._dbKey + " vs. " + this._hashCode);
578 // Delete Entry from Object DB
579 if (this._dbKey != null)
581 if (qx.core.Object._disposeAll)
583 qx.core.Object._db[this._dbKey] = null;
584 this._hashCode = null;
589 delete qx.core.Object._db[this._dbKey];
590 delete this._hashCode;
596 this._disposed = true;