You can subscribe to this list here.
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(10) |
Jul
(24) |
Aug
(93) |
Sep
(261) |
Oct
(257) |
Nov
(218) |
Dec
(95) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2008 |
Jan
(184) |
Feb
(87) |
Mar
(155) |
Apr
(398) |
May
(201) |
Jun
(35) |
Jul
(68) |
Aug
(92) |
Sep
(52) |
Oct
(111) |
Nov
(135) |
Dec
(116) |
2009 |
Jan
(225) |
Feb
(204) |
Mar
(113) |
Apr
(137) |
May
(220) |
Jun
(199) |
Jul
(196) |
Aug
(98) |
Sep
(100) |
Oct
(179) |
Nov
(164) |
Dec
(72) |
2010 |
Jan
(59) |
Feb
(61) |
Mar
(64) |
Apr
(159) |
May
(107) |
Jun
(252) |
Jul
(180) |
Aug
(96) |
Sep
(82) |
Oct
(58) |
Nov
(43) |
Dec
(53) |
2011 |
Jan
(39) |
Feb
(18) |
Mar
(33) |
Apr
(66) |
May
(48) |
Jun
(124) |
Jul
(112) |
Aug
(62) |
Sep
(45) |
Oct
(102) |
Nov
(47) |
Dec
(37) |
2012 |
Jan
(22) |
Feb
(18) |
Mar
(1) |
Apr
(5) |
May
(18) |
Jun
(13) |
Jul
(9) |
Aug
(38) |
Sep
(3) |
Oct
(7) |
Nov
(24) |
Dec
(6) |
2013 |
Jan
(1) |
Feb
(14) |
Mar
(1) |
Apr
(2) |
May
(3) |
Jun
(4) |
Jul
(9) |
Aug
(4) |
Sep
(7) |
Oct
|
Nov
(1) |
Dec
(4) |
2014 |
Jan
(9) |
Feb
(2) |
Mar
|
Apr
|
May
(4) |
Jun
(2) |
Jul
|
Aug
|
Sep
(6) |
Oct
|
Nov
(1) |
Dec
|
2015 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(1) |
Nov
|
Dec
|
2016 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(2) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <th...@us...> - 2013-02-13 17:12:45
|
Revision: 21829 http://sourceforge.net/p/qooxdoo-contrib/code/21829 Author: thron7 Date: 2013-02-13 17:12:42 +0000 (Wed, 13 Feb 2013) Log Message: ----------- minor change, testing Allura upgrade Modified Paths: -------------- trunk/qooxdoo-contrib/Translation/2.2/framework/de.po Modified: trunk/qooxdoo-contrib/Translation/2.2/framework/de.po =================================================================== --- trunk/qooxdoo-contrib/Translation/2.2/framework/de.po 2013-02-07 13:41:20 UTC (rev 21828) +++ trunk/qooxdoo-contrib/Translation/2.2/framework/de.po 2013-02-13 17:12:42 UTC (rev 21829) @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: qooxdoo framework\n" -"Report-Msgid-Bugs-To: \n" +"Report-Msgid-Bugs-To: tra...@qo...\n" "POT-Creation-Date: 2008-05-19 10:11+0200\n" "PO-Revision-Date: 2010-04-22 17:53+0100\n" "Last-Translator: Thomas Herchenroeder <thron7 AT users DOT sourceforge DOT net>\n" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2013-02-13 15:13:42
|
Revision: 21829 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21829&view=rev Author: thron7 Date: 2013-02-13 15:13:33 +0000 (Wed, 13 Feb 2013) Log Message: ----------- minor change, testing Allura upgrade Modified Paths: -------------- trunk/qooxdoo-contrib/Translation/2.2/framework/de.po Modified: trunk/qooxdoo-contrib/Translation/2.2/framework/de.po =================================================================== --- trunk/qooxdoo-contrib/Translation/2.2/framework/de.po 2013-02-07 13:41:20 UTC (rev 21828) +++ trunk/qooxdoo-contrib/Translation/2.2/framework/de.po 2013-02-13 15:13:33 UTC (rev 21829) @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: qooxdoo framework\n" -"Report-Msgid-Bugs-To: \n" +"Report-Msgid-Bugs-To: tra...@qo...\n" "POT-Creation-Date: 2008-05-19 10:11+0200\n" "PO-Revision-Date: 2010-04-22 17:53+0100\n" "Last-Translator: Thomas Herchenroeder <thron7 AT users DOT sourceforge DOT net>\n" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <d_w...@us...> - 2013-02-07 13:41:27
|
Revision: 21828 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21828&view=rev Author: d_wagner Date: 2013-02-07 13:41:20 +0000 (Thu, 07 Feb 2013) Log Message: ----------- added setter for config options Modified Paths: -------------- trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/Simulation.js Modified: trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/Simulation.js =================================================================== --- trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/Simulation.js 2013-01-08 16:57:06 UTC (rev 21827) +++ trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/Simulation.js 2013-02-07 13:41:20 UTC (rev 21828) @@ -229,6 +229,11 @@ } }; + this.setConfigSetting = function(prop, value) + { + __config[prop] = value; + }; + function addZero(val) { if (val < 10) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rst...@us...> - 2013-01-08 16:57:13
|
Revision: 21827 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21827&view=rev Author: rsternagel Date: 2013-01-08 16:57:06 +0000 (Tue, 08 Jan 2013) Log Message: ----------- minor translation update Modified Paths: -------------- trunk/qooxdoo-contrib/Translation/2.2/framework/cs.po trunk/qooxdoo-contrib/Translation/2.2/framework/de.po trunk/qooxdoo-contrib/Translation/2.2/framework/en.po trunk/qooxdoo-contrib/Translation/2.2/framework/es.po trunk/qooxdoo-contrib/Translation/2.2/framework/fr.po trunk/qooxdoo-contrib/Translation/2.2/framework/it.po trunk/qooxdoo-contrib/Translation/2.2/framework/nb.po trunk/qooxdoo-contrib/Translation/2.2/framework/nl.po trunk/qooxdoo-contrib/Translation/2.2/framework/pl.po trunk/qooxdoo-contrib/Translation/2.2/framework/pt.po trunk/qooxdoo-contrib/Translation/2.2/framework/ro.po trunk/qooxdoo-contrib/Translation/2.2/framework/sl.po trunk/qooxdoo-contrib/Translation/2.2/framework/sv.po Modified: trunk/qooxdoo-contrib/Translation/2.2/framework/cs.po =================================================================== --- trunk/qooxdoo-contrib/Translation/2.2/framework/cs.po 2012-12-15 17:45:36 UTC (rev 21826) +++ trunk/qooxdoo-contrib/Translation/2.2/framework/cs.po 2013-01-08 16:57:06 UTC (rev 21827) @@ -8,13 +8,11 @@ "PO-Revision-Date: 2012-08-27 09:23+0100\n" "Last-Translator: Lukáš Slánský <lu...@sl...>\n" "Language-Team: Lukáš Slánský <lu...@sl...>\n" -"Language: Czech\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" -"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "Language: Czech\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" msgid "%1 does not fit %2." msgstr "%1 neodpovídá %2." @@ -43,6 +41,9 @@ msgid "Automatic" msgstr "Automaticky" +msgid "Basic Colors" +msgstr "" + msgid "Cancel" msgstr "Storno" @@ -85,6 +86,9 @@ msgid "RGB" msgstr "RGB" +msgid "Recent Colors" +msgstr "" + msgid "Reset column widths" msgstr "Obnovit šířky sloupců" Modified: trunk/qooxdoo-contrib/Translation/2.2/framework/de.po =================================================================== --- trunk/qooxdoo-contrib/Translation/2.2/framework/de.po 2012-12-15 17:45:36 UTC (rev 21826) +++ trunk/qooxdoo-contrib/Translation/2.2/framework/de.po 2013-01-08 16:57:06 UTC (rev 21827) @@ -41,6 +41,9 @@ msgid "Automatic" msgstr "Automatisch" +msgid "Basic Colors" +msgstr "Grundfarben" + msgid "Cancel" msgstr "Abbruch" @@ -83,6 +86,9 @@ msgid "RGB" msgstr "RGB" +msgid "Recent Colors" +msgstr "Zuletzt benutzte Farben" + msgid "Reset column widths" msgstr "Spaltenbreite zurücksetzen" Modified: trunk/qooxdoo-contrib/Translation/2.2/framework/en.po =================================================================== --- trunk/qooxdoo-contrib/Translation/2.2/framework/en.po 2012-12-15 17:45:36 UTC (rev 21826) +++ trunk/qooxdoo-contrib/Translation/2.2/framework/en.po 2013-01-08 16:57:06 UTC (rev 21827) @@ -40,6 +40,9 @@ msgid "Automatic" msgstr "" +msgid "Basic Colors" +msgstr "" + msgid "Cancel" msgstr "" @@ -82,6 +85,9 @@ msgid "RGB" msgstr "" +msgid "Recent Colors" +msgstr "" + msgid "Reset column widths" msgstr "" Modified: trunk/qooxdoo-contrib/Translation/2.2/framework/es.po =================================================================== --- trunk/qooxdoo-contrib/Translation/2.2/framework/es.po 2012-12-15 17:45:36 UTC (rev 21826) +++ trunk/qooxdoo-contrib/Translation/2.2/framework/es.po 2013-01-08 16:57:06 UTC (rev 21827) @@ -41,6 +41,9 @@ msgid "Automatic" msgstr "Automático" +msgid "Basic Colors" +msgstr "" + msgid "Cancel" msgstr "Cancelar" @@ -83,6 +86,9 @@ msgid "RGB" msgstr "RGB" +msgid "Recent Colors" +msgstr "" + msgid "Reset column widths" msgstr "Reestablecer anchos de columnas" Modified: trunk/qooxdoo-contrib/Translation/2.2/framework/fr.po =================================================================== --- trunk/qooxdoo-contrib/Translation/2.2/framework/fr.po 2012-12-15 17:45:36 UTC (rev 21826) +++ trunk/qooxdoo-contrib/Translation/2.2/framework/fr.po 2013-01-08 16:57:06 UTC (rev 21827) @@ -39,6 +39,9 @@ msgid "Automatic" msgstr "Automatique" +msgid "Basic Colors" +msgstr "" + msgid "Cancel" msgstr "Annuler" @@ -81,6 +84,9 @@ msgid "RGB" msgstr "RVB" +msgid "Recent Colors" +msgstr "" + msgid "Reset column widths" msgstr "Réinitialiser la largeur des colonnes" @@ -254,8 +260,8 @@ msgid "one of one row" msgid_plural "%1 of %2 rows" -msgstr[0] "ligne une de une" -msgstr[1] "ligne %1 de %2" +msgstr[0] "une ligne sur une" +msgstr[1] "%1 lignes sur %2" msgid "one row" msgid_plural "%1 rows" Modified: trunk/qooxdoo-contrib/Translation/2.2/framework/it.po =================================================================== --- trunk/qooxdoo-contrib/Translation/2.2/framework/it.po 2012-12-15 17:45:36 UTC (rev 21826) +++ trunk/qooxdoo-contrib/Translation/2.2/framework/it.po 2013-01-08 16:57:06 UTC (rev 21827) @@ -41,6 +41,9 @@ msgid "Automatic" msgstr "Automatico" +msgid "Basic Colors" +msgstr "" + msgid "Cancel" msgstr "Annulla" @@ -83,6 +86,9 @@ msgid "RGB" msgstr "RGB" +msgid "Recent Colors" +msgstr "" + msgid "Reset column widths" msgstr "Ripristina le larghezze delle colonne" Modified: trunk/qooxdoo-contrib/Translation/2.2/framework/nb.po =================================================================== --- trunk/qooxdoo-contrib/Translation/2.2/framework/nb.po 2012-12-15 17:45:36 UTC (rev 21826) +++ trunk/qooxdoo-contrib/Translation/2.2/framework/nb.po 2013-01-08 16:57:06 UTC (rev 21827) @@ -40,6 +40,9 @@ msgid "Automatic" msgstr "Automatisk" +msgid "Basic Colors" +msgstr "" + msgid "Cancel" msgstr "Avbryt" @@ -82,6 +85,9 @@ msgid "RGB" msgstr "RGB" +msgid "Recent Colors" +msgstr "" + msgid "Reset column widths" msgstr "Nullstill kolonnebreddene" Modified: trunk/qooxdoo-contrib/Translation/2.2/framework/nl.po =================================================================== --- trunk/qooxdoo-contrib/Translation/2.2/framework/nl.po 2012-12-15 17:45:36 UTC (rev 21826) +++ trunk/qooxdoo-contrib/Translation/2.2/framework/nl.po 2013-01-08 16:57:06 UTC (rev 21827) @@ -39,6 +39,9 @@ msgid "Automatic" msgstr "Automatisch" +msgid "Basic Colors" +msgstr "" + msgid "Cancel" msgstr "Annuleer" @@ -81,6 +84,9 @@ msgid "RGB" msgstr "RGB" +msgid "Recent Colors" +msgstr "" + msgid "Reset column widths" msgstr "Kolombreedte herstellen" Modified: trunk/qooxdoo-contrib/Translation/2.2/framework/pl.po =================================================================== --- trunk/qooxdoo-contrib/Translation/2.2/framework/pl.po 2012-12-15 17:45:36 UTC (rev 21826) +++ trunk/qooxdoo-contrib/Translation/2.2/framework/pl.po 2013-01-08 16:57:06 UTC (rev 21827) @@ -40,6 +40,9 @@ msgid "Automatic" msgstr "Automatycznie" +msgid "Basic Colors" +msgstr "" + msgid "Cancel" msgstr "Anuluj" @@ -82,6 +85,9 @@ msgid "RGB" msgstr "RGB" +msgid "Recent Colors" +msgstr "" + msgid "Reset column widths" msgstr "Zresetuj szerokość kolumny" Modified: trunk/qooxdoo-contrib/Translation/2.2/framework/pt.po =================================================================== --- trunk/qooxdoo-contrib/Translation/2.2/framework/pt.po 2012-12-15 17:45:36 UTC (rev 21826) +++ trunk/qooxdoo-contrib/Translation/2.2/framework/pt.po 2013-01-08 16:57:06 UTC (rev 21827) @@ -40,6 +40,9 @@ msgid "Automatic" msgstr "Automático" +msgid "Basic Colors" +msgstr "" + msgid "Cancel" msgstr "Cancelar" @@ -82,6 +85,9 @@ msgid "RGB" msgstr "RGB" +msgid "Recent Colors" +msgstr "" + msgid "Reset column widths" msgstr "Repor a largura das colunas" Modified: trunk/qooxdoo-contrib/Translation/2.2/framework/ro.po =================================================================== --- trunk/qooxdoo-contrib/Translation/2.2/framework/ro.po 2012-12-15 17:45:36 UTC (rev 21826) +++ trunk/qooxdoo-contrib/Translation/2.2/framework/ro.po 2013-01-08 16:57:06 UTC (rev 21827) @@ -40,6 +40,9 @@ msgid "Automatic" msgstr "Automat" +msgid "Basic Colors" +msgstr "" + msgid "Cancel" msgstr "Anulează" @@ -82,6 +85,9 @@ msgid "RGB" msgstr "" +msgid "Recent Colors" +msgstr "" + msgid "Reset column widths" msgstr "Resetează lățimea coloanei" Modified: trunk/qooxdoo-contrib/Translation/2.2/framework/sl.po =================================================================== --- trunk/qooxdoo-contrib/Translation/2.2/framework/sl.po 2012-12-15 17:45:36 UTC (rev 21826) +++ trunk/qooxdoo-contrib/Translation/2.2/framework/sl.po 2013-01-08 16:57:06 UTC (rev 21827) @@ -43,6 +43,9 @@ msgid "Automatic" msgstr "Automatičen" +msgid "Basic Colors" +msgstr "" + msgid "Cancel" msgstr "Prekliči" @@ -85,6 +88,9 @@ msgid "RGB" msgstr "RGB" +msgid "Recent Colors" +msgstr "" + msgid "Reset column widths" msgstr "Resetiraj širino stolpca" Modified: trunk/qooxdoo-contrib/Translation/2.2/framework/sv.po =================================================================== --- trunk/qooxdoo-contrib/Translation/2.2/framework/sv.po 2012-12-15 17:45:36 UTC (rev 21826) +++ trunk/qooxdoo-contrib/Translation/2.2/framework/sv.po 2013-01-08 16:57:06 UTC (rev 21827) @@ -39,6 +39,9 @@ msgid "Automatic" msgstr "Automatiskt" +msgid "Basic Colors" +msgstr "" + msgid "Cancel" msgstr "Avbryt" @@ -81,6 +84,9 @@ msgid "RGB" msgstr "RGB" +msgid "Recent Colors" +msgstr "" + msgid "Reset column widths" msgstr "Återställ kolumnbredder" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sc...@us...> - 2012-12-15 17:45:42
|
Revision: 21826 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21826&view=rev Author: scro34 Date: 2012-12-15 17:45:36 +0000 (Sat, 15 Dec 2012) Log Message: ----------- Versions 0.1 & 0.2 removed Removed Paths: ------------- trunk/qooxdoo-contrib/SilverBlueTheme/0.1/ trunk/qooxdoo-contrib/SilverBlueTheme/0.2/ Property Changed: ---------------- trunk/qooxdoo-contrib/SilverBlueTheme/ Property changes on: trunk/qooxdoo-contrib/SilverBlueTheme ___________________________________________________________________ Added: svn:ignore + 0.1 0.2 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sc...@us...> - 2012-12-15 17:43:39
|
Revision: 21825 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21825&view=rev Author: scro34 Date: 2012-12-15 17:43:32 +0000 (Sat, 15 Dec 2012) Log Message: ----------- Versions 0.1 & 0.2 removed Removed Paths: ------------- trunk/qooxdoo-contrib/DarkTheme/0.1/ trunk/qooxdoo-contrib/DarkTheme/0.2/ Property Changed: ---------------- trunk/qooxdoo-contrib/DarkTheme/ Property changes on: trunk/qooxdoo-contrib/DarkTheme ___________________________________________________________________ Added: svn:ignore + 0.1 0.2 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <spa...@us...> - 2012-12-10 09:49:59
|
Revision: 21824 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21824&view=rev Author: spackers Date: 2012-12-10 09:49:49 +0000 (Mon, 10 Dec 2012) Log Message: ----------- added resetBootstrap to allow preserving bootstrap object between sessions Modified Paths: -------------- trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/ProxySessionTracker.java Modified: trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/ProxySessionTracker.java =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/ProxySessionTracker.java 2012-12-10 09:47:49 UTC (rev 21823) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/ProxySessionTracker.java 2012-12-10 09:49:49 UTC (rev 21824) @@ -273,8 +273,8 @@ * Resets the session, called when the application restarts */ /*package*/ void resetSession() { + resetBootstrap(); queue = null; - bootstrap = null; deliveredTypes.clear(); objectsById.clear(); objectIds.clear(); @@ -304,6 +304,13 @@ protected void initialiseBootstrap(Proxied bootstrap) { // Nothing } + + /** + * Called to reset the bootstrap instance for a new session + */ + protected void resetBootstrap() { + bootstrap = null; + } /** * Returns the bootstrap, creating one if necessary This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <spa...@us...> - 2012-12-10 09:47:58
|
Revision: 21823 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21823&view=rev Author: spackers Date: 2012-12-10 09:47:49 +0000 (Mon, 10 Dec 2012) Log Message: ----------- made backward compat check use eval to avoid parts problems Modified Paths: -------------- trunk/qooxdoo-contrib/ServerObjects/trunk/client/qso-lib/source/class/com/zenesis/qx/remote/ProxyManager.js Modified: trunk/qooxdoo-contrib/ServerObjects/trunk/client/qso-lib/source/class/com/zenesis/qx/remote/ProxyManager.js =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/client/qso-lib/source/class/com/zenesis/qx/remote/ProxyManager.js 2012-12-03 12:54:27 UTC (rev 21822) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/client/qso-lib/source/class/com/zenesis/qx/remote/ProxyManager.js 2012-12-10 09:47:49 UTC (rev 21823) @@ -87,7 +87,7 @@ }; } if (!qx.lang.Json) - qx.lang.Json = qx.util.Json; + qx.lang.Json = eval("qx.util.Json"); }, properties: { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <spa...@us...> - 2012-12-03 12:54:37
|
Revision: 21822 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21822&view=rev Author: spackers Date: 2012-12-03 12:54:27 +0000 (Mon, 03 Dec 2012) Log Message: ----------- fixed reference to qx.bom.element.Style Modified Paths: -------------- trunk/qooxdoo-contrib/UploadMgr/trunk/source/class/com/zenesis/qx/upload/FormHandler.js Modified: trunk/qooxdoo-contrib/UploadMgr/trunk/source/class/com/zenesis/qx/upload/FormHandler.js =================================================================== --- trunk/qooxdoo-contrib/UploadMgr/trunk/source/class/com/zenesis/qx/upload/FormHandler.js 2012-12-03 09:02:48 UTC (rev 21821) +++ trunk/qooxdoo-contrib/UploadMgr/trunk/source/class/com/zenesis/qx/upload/FormHandler.js 2012-12-03 12:54:27 UTC (rev 21822) @@ -171,7 +171,7 @@ id: "upload-form-" + file.getId() }); - qx.dom.Element.Style.setStyles(form, { + qx.bom.element.Style.setStyles(form, { display: 'none' }); var params = this._getMergedParams(file); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <spa...@us...> - 2012-12-03 09:03:02
|
Revision: 21821 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21821&view=rev Author: spackers Date: 2012-12-03 09:02:48 +0000 (Mon, 03 Dec 2012) Log Message: ----------- changed qx.bom.Element.create -> qx.dom.Element.create Modified Paths: -------------- trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/config.json trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/source/script/uploadmgr.demo.js trunk/qooxdoo-contrib/UploadMgr/trunk/source/class/com/zenesis/qx/upload/FormHandler.js Added Paths: ----------- trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/source/script/uploadmgr.demo.d88b4fb45db4.js Removed Paths: ------------- trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/source/script/uploadmgr.demo.0c43f625212e.js trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/source/script/uploadmgr.demo.10727727e37b.js trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/source/script/uploadmgr.demo.3b9f77b4afb0.js trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/source/script/uploadmgr.demo.4821091c8b73.js trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/source/script/uploadmgr.demo.585bfe46d962.js trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/source/script/uploadmgr.demo.8ac13fc6c2b9.js trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/source/script/uploadmgr.demo.9e6e97c144ae.js trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/source/script/uploadmgr.demo.dd1c84a96c8d.js trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/source/script/uploadmgr.demo.fe6652ba8a59.js Modified: trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/config.json =================================================================== --- trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/config.json 2012-11-29 12:29:56 UTC (rev 21820) +++ trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/config.json 2012-12-03 09:02:48 UTC (rev 21821) @@ -38,6 +38,7 @@ { "APPLICATION" : "uploadmgr.demo", "QOOXDOO_PATH" : "../../../../../../../../Local/WebContent/public/grasshopper/qooxdoo-trunk", + "XXQOOXDOO_PATH" : "../../../../../../../../../../../os/qooxdoo", "QXTHEME" : "uploadmgr.demo.theme.Theme", "API_EXCLUDE" : ["qx.test.*", "${APPLICATION}.theme.*", "${APPLICATION}.test.*", "${APPLICATION}.simulation.*"], "LOCALES" : [ "en" ], Deleted: trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/source/script/uploadmgr.demo.0c43f625212e.js =================================================================== --- trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/source/script/uploadmgr.demo.0c43f625212e.js 2012-11-29 12:29:56 UTC (rev 21820) +++ trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/source/script/uploadmgr.demo.0c43f625212e.js 2012-12-03 09:02:48 UTC (rev 21821) @@ -1,12479 +0,0 @@ -/* ************************************************************************ - - qooxdoo - the new era of web development - - http://qooxdoo.org - - Copyright: - 2004-2008 1&1 Internet AG, Germany, http://www.1und1.de - - License: - LGPL: http://www.gnu.org/licenses/lgpl.html - EPL: http://www.eclipse.org/org/documents/epl-v10.php - See the LICENSE file in the project's top-level directory for details. - - Authors: - * Sebastian Werner (wpbasti) - * Fabian Jakobs (fjakobs) - -************************************************************************ */ - -/** - * This mixin redirects all children handling methods to a child widget of the - * including class. This is e.g. used in {@link qx.ui.window.Window} to add - * child widgets directly to the window pane. - * - * The including class must implement the method <code>getChildrenContainer</code>, - * which has to return the widget, to which the child widgets should be added. - */ -qx.Mixin.define("qx.ui.core.MRemoteChildrenHandling", -{ - /* - ***************************************************************************** - MEMBERS - ***************************************************************************** - */ - - members : - { - /** - * Forward the call with the given function name to the children container - * - * @param functionName {String} name of the method to forward - * @param a1 {var} first argument of the method to call - * @param a2 {var} second argument of the method to call - * @param a3 {var} third argument of the method to call - * @return {var} The return value of the forward method - */ - __forward : function(functionName, a1, a2, a3) - { - var container = this.getChildrenContainer(); - if (container === this) { - functionName = "_" + functionName; - } - return (container[functionName])(a1, a2, a3); - }, - - - /** - * Returns the children list - * - * @return {LayoutItem[]} The children array (Arrays are - * reference types, please to not modify them in-place) - */ - getChildren : function() { - return this.__forward("getChildren"); - }, - - - /** - * Whether the widget contains children. - * - * @return {Boolean} Returns <code>true</code> when the widget has children. - */ - hasChildren : function() { - return this.__forward("hasChildren"); - }, - - - /** - * Adds a new child widget. - * - * The supported keys of the layout options map depend on the layout manager - * used to position the widget. The options are documented in the class - * documentation of each layout manager {@link qx.ui.layout}. - * - * @param child {LayoutItem} the item to add. - * @param options {Map?null} Optional layout data for item. - * @return {Widget} This object (for chaining support) - */ - add : function(child, options) { - return this.__forward("add", child, options); - }, - - - /** - * Remove the given child item. - * - * @param child {LayoutItem} the item to remove - * @return {Widget} This object (for chaining support) - */ - remove : function(child) { - return this.__forward("remove", child); - }, - - - /** - * Remove all children. - * - * @return {void} - */ - removeAll : function() { - return this.__forward("removeAll"); - }, - - - /** - * Returns the index position of the given item if it is - * a child item. Otherwise it returns <code>-1</code>. - * - * This method works on the widget's children list. Some layout managers - * (e.g. {@link qx.ui.layout.HBox}) use the children order as additional - * layout information. Other layout manager (e.g. {@link qx.ui.layout.Grid}) - * ignore the children order for the layout process. - * - * @param child {LayoutItem} the item to query for - * @return {Integer} The index position or <code>-1</code> when - * the given item is no child of this layout. - */ - indexOf : function(child) { - return this.__forward("indexOf", child); - }, - - - /** - * Add a child at the specified index - * - * This method works on the widget's children list. Some layout managers - * (e.g. {@link qx.ui.layout.HBox}) use the children order as additional - * layout information. Other layout manager (e.g. {@link qx.ui.layout.Grid}) - * ignore the children order for the layout process. - * - * @param child {LayoutItem} item to add - * @param index {Integer} Index, at which the item will be inserted - * @param options {Map?null} Optional layout data for item. - */ - addAt : function(child, index, options) { - this.__forward("addAt", child, index, options); - }, - - - /** - * Add an item before another already inserted item - * - * This method works on the widget's children list. Some layout managers - * (e.g. {@link qx.ui.layout.HBox}) use the children order as additional - * layout information. Other layout manager (e.g. {@link qx.ui.layout.Grid}) - * ignore the children order for the layout process. - * - * @param child {LayoutItem} item to add - * @param before {LayoutItem} item before the new item will be inserted. - * @param options {Map?null} Optional layout data for item. - */ - addBefore : function(child, before, options) { - this.__forward("addBefore", child, before, options); - }, - - - /** - * Add an item after another already inserted item - * - * This method works on the widget's children list. Some layout managers - * (e.g. {@link qx.ui.layout.HBox}) use the children order as additional - * layout information. Other layout manager (e.g. {@link qx.ui.layout.Grid}) - * ignore the children order for the layout process. - * - * @param child {LayoutItem} item to add - * @param after {LayoutItem} item, after which the new item will be inserted - * @param options {Map?null} Optional layout data for item. - */ - addAfter : function(child, after, options) { - this.__forward("addAfter", child, after, options); - }, - - - /** - * Remove the item at the specified index. - * - * This method works on the widget's children list. Some layout managers - * (e.g. {@link qx.ui.layout.HBox}) use the children order as additional - * layout information. Other layout manager (e.g. {@link qx.ui.layout.Grid}) - * ignore the children order for the layout process. - * - * @param index {Integer} Index of the item to remove. - * @return {qx.ui.core.LayoutItem} The removed item - */ - removeAt : function(index) { - return this.__forward("removeAt", index); - } - } -}); -/* ************************************************************************ - - qooxdoo - the new era of web development - - http://qooxdoo.org - - Copyright: - 2008 1&1 Internet AG, Germany, http://www.1und1.de - - License: - LGPL: http://www.gnu.org/licenses/lgpl.html - EPL: http://www.eclipse.org/org/documents/epl-v10.php - See the LICENSE file in the project's top-level directory for details. - - Authors: - * Sebastian Werner (wpbasti) - -************************************************************************ */ - -/** - * Generic selection manager to bring rich desktop like selection behavior - * to widgets and low-level interactive controls. - * - * The selection handling supports both Shift and Ctrl/Meta modifies like - * known from native applications. - */ -qx.Class.define("qx.ui.core.selection.Abstract", -{ - type : "abstract", - extend : qx.core.Object, - - - - /* - ***************************************************************************** - CONSTRUCTOR - ***************************************************************************** - */ - - construct : function() - { - this.base(arguments); - - // {Map} Internal selection storage - this.__selection = {}; - }, - - - - - /* - ***************************************************************************** - EVENTS - ***************************************************************************** - */ - - events : - { - /** Fires after the selection was modified. Contains the selection under the data property. */ - "changeSelection" : "qx.event.type.Data" - }, - - - - - - /* - ***************************************************************************** - PROPERTIES - ***************************************************************************** - */ - - properties : - { - /** - * Selects the selection mode to use. - * - * * single: One or no element is selected - * * multi: Multi items could be selected. Also allows empty selections. - * * additive: Easy Web-2.0 selection mode. Allows multiple selections without modifier keys. - * * one: If possible always exactly one item is selected - */ - mode : - { - check : [ "single", "multi", "additive", "one" ], - init : "single", - apply : "_applyMode" - }, - - - /** - * Enable drag selection (multi selection of items through - * dragging the mouse in pressed states). - * - * Only possible for the modes <code>multi</code> and <code>additive</code> - */ - drag : - { - check : "Boolean", - init : false - }, - - - /** - * Enable quick selection mode, where no click is needed to change the selection. - * - * Only possible for the modes <code>single</code> and <code>one</code>. - */ - quick : - { - check : "Boolean", - init : false - } - }, - - - - - - /* - ***************************************************************************** - MEMBERS - ***************************************************************************** - */ - - members : - { - __scrollStepX : 0, - __scrollStepY : 0, - __scrollTimer : null, - __frameScroll : null, - __lastRelX : null, - __lastRelY : null, - __frameLocation : null, - __dragStartX : null, - __dragStartY : null, - __inCapture : null, - __mouseX : null, - __mouseY : null, - __moveDirectionX : null, - __moveDirectionY : null, - __selectionModified : null, - __selectionContext : null, - __leadItem : null, - __selection : null, - __anchorItem : null, - __mouseDownOnSelected : null, - - // A flag that signals an user interaction, which means the selection change - // was triggered by mouse or keyboard [BUG #3344] - _userInteraction : false, - - __oldScrollTop : null, - - /* - --------------------------------------------------------------------------- - USER APIS - --------------------------------------------------------------------------- - */ - - /** - * Returns the selection context. One of <code>click</code>, - * <code>quick</code>, <code>drag</code> or <code>key</code> or - * <code>null</code>. - * - * @return {String} One of <code>click</code>, <code>quick</code>, - * <code>drag</code> or <code>key</code> or <code>null</code> - */ - getSelectionContext : function() { - return this.__selectionContext; - }, - - - /** - * Selects all items of the managed object. - * - * @return {void} - */ - selectAll : function() - { - var mode = this.getMode(); - if (mode == "single" || mode == "one") { - throw new Error("Can not select all items in selection mode: " + mode); - } - - this._selectAllItems(); - this._fireChange(); - }, - - - /** - * Selects the given item. Replaces current selection - * completely with the new item. - * - * Use {@link #addItem} instead if you want to add new - * items to an existing selection. - * - * @param item {Object} Any valid item - * @return {void} - */ - selectItem : function(item) - { - this._setSelectedItem(item); - - var mode = this.getMode(); - if (mode !== "single" && mode !== "one") - { - this._setLeadItem(item); - this._setAnchorItem(item); - } - - this._scrollItemIntoView(item); - this._fireChange(); - }, - - - /** - * Adds the given item to the existing selection. - * - * Use {@link #selectItem} instead if you want to replace - * the current selection. - * - * @param item {Object} Any valid item - * @return {void} - */ - addItem : function(item) - { - var mode = this.getMode(); - if (mode === "single" || mode === "one") { - this._setSelectedItem(item); - } - else - { - if (this._getAnchorItem() == null) { - this._setAnchorItem(item); - } - - this._setLeadItem(item); - this._addToSelection(item); - } - - this._scrollItemIntoView(item); - this._fireChange(); - }, - - - /** - * Removes the given item from the selection. - * - * Use {@link #clearSelection} when you want to clear - * the whole selection at once. - * - * @param item {Object} Any valid item - * @return {void} - */ - removeItem : function(item) - { - this._removeFromSelection(item); - - if (this.getMode() === "one" && this.isSelectionEmpty()) - { - var selected = this._applyDefaultSelection(); - - // Do not fire any event in this case. - if (selected == item) { - return; - } - } - - if (this.getLeadItem() == item) { - this._setLeadItem(null); - } - - if (this._getAnchorItem() == item) { - this._setAnchorItem(null); - } - - this._fireChange(); - }, - - - /** - * Selects an item range between two given items. - * - * @param begin {Object} Item to start with - * @param end {Object} Item to end at - * @return {void} - */ - selectItemRange : function(begin, end) - { - var mode = this.getMode(); - if (mode == "single" || mode == "one") { - throw new Error("Can not select multiple items in selection mode: " + mode); - } - - this._selectItemRange(begin, end); - - this._setAnchorItem(begin); - - this._setLeadItem(end); - this._scrollItemIntoView(end); - - this._fireChange(); - }, - - - /** - * Clears the whole selection at once. Also - * resets the lead and anchor items and their - * styles. - * - * @return {void} - */ - clearSelection : function() - { - if (this.getMode() == "one") - { - var selected = this._applyDefaultSelection(true); - if (selected != null) { - return; - } - } - - this._clearSelection(); - this._setLeadItem(null); - this._setAnchorItem(null); - - this._fireChange(); - }, - - - /** - * Replaces current selection with given array of items. - * - * Please note that in single selection scenarios it is more - * efficient to directly use {@link #selectItem}. - * - * @param items {Array} Items to select - */ - replaceSelection : function(items) - { - var mode = this.getMode(); - if (mode == "one" || mode === "single") - { - if (items.length > 1) { - throw new Error("Could not select more than one items in mode: " + mode + "!"); - } - - if (items.length == 1) { - this.selectItem(items[0]); - } else { - this.clearSelection(); - } - return; - } - else - { - this._replaceMultiSelection(items); - } - }, - - - /** - * Get the selected item. This method does only work in <code>single</code> - * selection mode. - * - * @return {Object} The selected item. - */ - getSelectedItem : function() - { - var mode = this.getMode(); - if (mode === "single" || mode === "one") - { - var result = this._getSelectedItem(); - return result != undefined ? result : null; - } - - throw new Error("The method getSelectedItem() is only supported in 'single' and 'one' selection mode!"); - }, - - - /** - * Returns an array of currently selected items. - * - * Note: The result is only a set of selected items, so the order can - * differ from the sequence in which the items were added. - * - * @return {Object[]} List of items. - */ - getSelection : function() { - return qx.lang.Object.getValues(this.__selection); - }, - - - /** - * Returns the selection sorted by the index in the - * container of the selection (the assigned widget) - * - * @return {Object[]} Sorted list of items - */ - getSortedSelection : function() - { - var children = this.getSelectables(); - var sel = qx.lang.Object.getValues(this.__selection); - - sel.sort(function(a, b) { - return children.indexOf(a) - children.indexOf(b); - }); - - return sel; - }, - - - /** - * Detects whether the given item is currently selected. - * - * @param item {var} Any valid selectable item - * @return {Boolean} Whether the item is selected - */ - isItemSelected : function(item) - { - var hash = this._selectableToHashCode(item); - return this.__selection[hash] !== undefined; - }, - - - /** - * Whether the selection is empty - * - * @return {Boolean} Whether the selection is empty - */ - isSelectionEmpty : function() { - return qx.lang.Object.isEmpty(this.__selection); - }, - - - /** - * Invert the selection. Select the non selected and deselect the selected. - */ - invertSelection: function() { - var mode = this.getMode(); - if (mode === "single" || mode === "one") { - throw new Error("The method invertSelection() is only supported in 'multi' and 'additive' selection mode!"); - } - - var selectables = this.getSelectables(); - for (var i = 0; i < selectables.length; i++) - { - this._toggleInSelection(selectables[i]); - } - - this._fireChange(); - }, - - - - /* - --------------------------------------------------------------------------- - LEAD/ANCHOR SUPPORT - --------------------------------------------------------------------------- - */ - - /** - * Sets the lead item. Generally the item which was last modified - * by the user (clicked on etc.) - * - * @param value {Object} Any valid item or <code>null</code> - * @return {void} - */ - _setLeadItem : function(value) - { - var old = this.__leadItem; - - if (old !== null) { - this._styleSelectable(old, "lead", false); - } - - if (value !== null) { - this._styleSelectable(value, "lead", true); - } - - this.__leadItem = value; - }, - - - /** - * Returns the current lead item. Generally the item which was last modified - * by the user (clicked on etc.) - * - * @return {Object} The lead item or <code>null</code> - */ - getLeadItem : function() { - return this.__leadItem !== null ? this.__leadItem : null; - }, - - - /** - * Sets the anchor item. This is the item which is the starting - * point for all range selections. Normally this is the item which was - * clicked on the last time without any modifier keys pressed. - * - * @param value {Object} Any valid item or <code>null</code> - * @return {void} - */ - _setAnchorItem : function(value) - { - var old = this.__anchorItem; - - if (old != null) { - this._styleSelectable(old, "anchor", false); - } - - if (value != null) { - this._styleSelectable(value, "anchor", true); - } - - this.__anchorItem = value; - }, - - - /** - * Returns the current anchor item. This is the item which is the starting - * point for all range selections. Normally this is the item which was - * clicked on the last time without any modifier keys pressed. - * - * @return {Object} The anchor item or <code>null</code> - */ - _getAnchorItem : function() { - return this.__anchorItem !== null ? this.__anchorItem : null; - }, - - - - - - /* - --------------------------------------------------------------------------- - BASIC SUPPORT - --------------------------------------------------------------------------- - */ - - /** - * Whether the given item is selectable. - * - * @param item {var} Any item - * @return {Boolean} <code>true</code> when the item is selectable - */ - _isSelectable : function(item) { - throw new Error("Abstract method call: _isSelectable()"); - }, - - - /** - * Finds the selectable instance from a mouse event - * - * @param event {qx.event.type.Mouse} The mouse event - * @return {Object|null} The resulting selectable - */ - _getSelectableFromMouseEvent : function(event) - { - var target = event.getTarget(); - // check for target (may be null when leaving the viewport) [BUG #4378] - if (target && this._isSelectable(target)) { - return target; - } - return null; - }, - - - /** - * Returns an unique hashcode for the given item. - * - * @param item {var} Any item - * @return {String} A valid hashcode - */ - _selectableToHashCode : function(item) { - throw new Error("Abstract method call: _selectableToHashCode()"); - }, - - - /** - * Updates the style (appearance) of the given item. - * - * @param item {var} Item to modify - * @param type {String} Any of <code>selected</code>, <code>anchor</code> or <code>lead</code> - * @param enabled {Boolean} Whether the given style should be added or removed. - * @return {void} - */ - _styleSelectable : function(item, type, enabled) { - throw new Error("Abstract method call: _styleSelectable()"); - }, - - - /** - * Enables capturing of the container. - * - * @return {void} - */ - _capture : function() { - throw new Error("Abstract method call: _capture()"); - }, - - - /** - * Releases capturing of the container - * - * @return {void} - */ - _releaseCapture : function() { - throw new Error("Abstract method call: _releaseCapture()"); - }, - - - - - - - /* - --------------------------------------------------------------------------- - DIMENSION AND LOCATION - --------------------------------------------------------------------------- - */ - - /** - * Returns the location of the container - * - * @return {Map} Map with the keys <code>top</code>, <code>right</code>, - * <code>bottom</code> and <code>left</code>. - */ - _getLocation : function() { - throw new Error("Abstract method call: _getLocation()"); - }, - - - /** - * Returns the dimension of the container (available scrolling space). - * - * @return {Map} Map with the keys <code>width</code> and <code>height</code>. - */ - _getDimension : function() { - throw new Error("Abstract method call: _getDimension()"); - }, - - - /** - * Returns the relative (to the container) horizontal location of the given item. - * - * @param item {var} Any item - * @return {Map} A map with the keys <code>left</code> and <code>right</code>. - */ - _getSelectableLocationX : function(item) { - throw new Error("Abstract method call: _getSelectableLocationX()"); - }, - - - /** - * Returns the relative (to the container) horizontal location of the given item. - * - * @param item {var} Any item - * @return {Map} A map with the keys <code>top</code> and <code>bottom</code>. - */ - _getSelectableLocationY : function(item) { - throw new Error("Abstract method call: _getSelectableLocationY()"); - }, - - - - - - - /* - --------------------------------------------------------------------------- - SCROLL SUPPORT - --------------------------------------------------------------------------- - */ - - /** - * Returns the scroll position of the container. - * - * @return {Map} Map with the keys <code>left</code> and <code>top</code>. - */ - _getScroll : function() { - throw new Error("Abstract method call: _getScroll()"); - }, - - - /** - * Scrolls by the given offset - * - * @param xoff {Integer} Horizontal offset to scroll by - * @param yoff {Integer} Vertical offset to scroll by - * @return {void} - */ - _scrollBy : function(xoff, yoff) { - throw new Error("Abstract method call: _scrollBy()"); - }, - - - /** - * Scrolls the given item into the view (make it visible) - * - * @param item {var} Any item - * @return {void} - */ - _scrollItemIntoView : function(item) { - throw new Error("Abstract method call: _scrollItemIntoView()"); - }, - - - - - - - /* - --------------------------------------------------------------------------- - QUERY SUPPORT - --------------------------------------------------------------------------- - */ - - /** - * Returns all selectable items of the container. - * - * @param all {boolean} true for all selectables, false for the - * selectables the user can interactively select - * @return {Array} A list of items - */ - getSelectables : function(all) { - throw new Error("Abstract method call: getSelectables()"); - }, - - - /** - * Returns all selectable items between the two given items. - * - * The items could be given in any order. - * - * @param item1 {var} First item - * @param item2 {var} Second item - * @return {Array} List of items - */ - _getSelectableRange : function(item1, item2) { - throw new Error("Abstract method call: _getSelectableRange()"); - }, - - - /** - * Returns the first selectable item. - * - * @return {var} The first selectable item - */ - _getFirstSelectable : function() { - throw new Error("Abstract method call: _getFirstSelectable()"); - }, - - - /** - * Returns the last selectable item. - * - * @return {var} The last selectable item - */ - _getLastSelectable : function() { - throw new Error("Abstract method call: _getLastSelectable()"); - }, - - - /** - * Returns a selectable item which is related to the given - * <code>item</code> through the value of <code>relation</code>. - * - * @param item {var} Any item - * @param relation {String} A valid relation: <code>above</code>, - * <code>right</code>, <code>under</code> or <code>left</code> - * @return {var} The related item - */ - _getRelatedSelectable : function(item, relation) { - throw new Error("Abstract method call: _getRelatedSelectable()"); - }, - - - /** - * Returns the item which should be selected on pageUp/pageDown. - * - * May also scroll to the needed position. - * - * @param lead {var} The current lead item - * @param up {Boolean?false} Which page key was pressed: - * <code>up</code> or <code>down</code>. - * @return {void} - */ - _getPage : function(lead, up) { - throw new Error("Abstract method call: _getPage()"); - }, - - - - - /* - --------------------------------------------------------------------------- - PROPERTY APPLY ROUTINES - --------------------------------------------------------------------------- - */ - - // property apply - _applyMode : function(value, old) - { - this._setLeadItem(null); - this._setAnchorItem(null); - - this._clearSelection(); - - // Mode "one" requires one selected item - if (value === "one") { - this._applyDefaultSelection(true); - } - - this._fireChange(); - }, - - - - - - - /* - --------------------------------------------------------------------------- - MOUSE SUPPORT - --------------------------------------------------------------------------- - */ - - /** - * This method should be connected to the <code>mouseover</code> event - * of the managed object. - * - * @param event {qx.event.type.Mouse} A valid mouse event - * @return {void} - */ - handleMouseOver : function(event) - { - // All browsers (except Opera) fire a native "mouseover" event when a scroll appears - // by keyboard interaction. We have to ignore the event to avoid a selection for - // "mouseover" (quick selection). For more details see [BUG #4225] - if(this.__oldScrollTop != null && - this.__oldScrollTop != this._getScroll().top) - { - this.__oldScrollTop = null; - return; - } - - // this is a method invoked by an user interaction, so be careful to - // set / clear the mark this._userInteraction [BUG #3344] - this._userInteraction = true; - - if (!this.getQuick()) { - this._userInteraction = false; - return; - } - - var mode = this.getMode(); - if (mode !== "one" && mode !== "single") { - this._userInteraction = false; - return; - } - - var item = this._getSelectableFromMouseEvent(event); - if (item === null) { - this._userInteraction = false; - return; - } - - this._setSelectedItem(item); - - // Be sure that item is in view - // This does not feel good when mouseover is used - // this._scrollItemIntoView(item); - - // Fire change event as needed - this._fireChange("quick"); - - this._userInteraction = false; - }, - - - /** - * This method should be connected to the <code>mousedown</code> event - * of the managed object. - * - * @param event {qx.event.type.Mouse} A valid mouse event - * @return {void} - */ - handleMouseDown : function(event) - { - // this is a method invoked by an user interaction, so be careful to - // set / clear the mark this._userInteraction [BUG #3344] - this._userInteraction = true; - - var item = this._getSelectableFromMouseEvent(event); - if (item === null) { - this._userInteraction = false; - return; - } - - // Read in keyboard modifiers - var isCtrlPressed = event.isCtrlPressed() || - (qx.core.Environment.get("os.name") == "osx" && event.isMetaPressed()); - var isShiftPressed = event.isShiftPressed(); - - // Clicking on selected items deselect on mouseup, not on mousedown - if (this.isItemSelected(item) && !isShiftPressed && !isCtrlPressed && !this.getDrag()) - { - this.__mouseDownOnSelected = item; - this._userInteraction = false; - return; - } - else - { - this.__mouseDownOnSelected = null; - } - - // Be sure that item is in view - this._scrollItemIntoView(item); - - // Action depends on selected mode - switch(this.getMode()) - { - case "single": - case "one": - this._setSelectedItem(item); - break; - - case "additive": - this._setLeadItem(item); - this._setAnchorItem(item); - this._toggleInSelection(item); - break; - - case "multi": - // Update lead item - this._setLeadItem(item); - - // Create/Update range selection - if (isShiftPressed) - { - var anchor = this._getAnchorItem(); - if (anchor === null) - { - anchor = this._getFirstSelectable(); - this._setAnchorItem(anchor); - } - - this._selectItemRange(anchor, item, isCtrlPressed); - } - - // Toggle in selection - else if (isCtrlPressed) - { - this._setAnchorItem(item); - this._toggleInSelection(item); - } - - // Replace current selection - else - { - this._setAnchorItem(item); - this._setSelectedItem(item); - } - - break; - } - - - // Drag selection - var mode = this.getMode(); - if ( - this.getDrag() && - mode !== "single" && - mode !== "one" && - !isShiftPressed && - !isCtrlPressed - ) - { - // Cache location/scroll data - this.__frameLocation = this._getLocation(); - this.__frameScroll = this._getScroll(); - - // Store position at start - this.__dragStartX = event.getDocumentLeft() + this.__frameScroll.left; - this.__dragStartY = event.getDocumentTop() + this.__frameScroll.top; - - // Switch to capture mode - this.__inCapture = true; - this._capture(); - } - - - // Fire change event as needed - this._fireChange("click"); - - this._userInteraction = false; - }, - - - /** - * This method should be connected to the <code>mouseup</code> event - * of the managed object. - * - * @param event {qx.event.type.Mouse} A valid mouse event - * @return {void} - */ - handleMouseUp : function(event) - { - // this is a method invoked by an user interaction, so be careful to - // set / clear the mark this._userInteraction [BUG #3344] - this._userInteraction = true; - - // Read in keyboard modifiers - var isCtrlPressed = event.isCtrlPressed() || - (qx.core.Environment.get("os.name") == "osx" && event.isMetaPressed()); - var isShiftPressed = event.isShiftPressed(); - - if (!isCtrlPressed && !isShiftPressed && this.__mouseDownOnSelected != null) - { - var item = this._getSelectableFromMouseEvent(event); - if (item === null || !this.isItemSelected(item)) { - this._userInteraction = false; - return; - } - - var mode = this.getMode(); - if (mode === "additive") - { - // Remove item from selection - this._removeFromSelection(item); - } - else - { - // Replace selection - this._setSelectedItem(item); - - if (this.getMode() === "multi") - { - this._setLeadItem(item); - this._setAnchorItem(item); - } - } - this._userInteraction = false; - } - - // Cleanup operation - this._cleanup(); - }, - - - /** - * This method should be connected to the <code>losecapture</code> event - * of the managed object. - * - * @param event {qx.event.type.Mouse} A valid mouse event - * @return {void} - */ - handleLoseCapture : function(event) { - this._cleanup(); - }, - - - /** - * This method should be connected to the <code>mousemove</code> event - * of the managed object. - * - * @param event {qx.event.type.Mouse} A valid mouse event - * @return {void} - */ - handleMouseMove : function(event) - { - // Only relevant when capturing is enabled - if (!this.__inCapture) { - return; - } - - - // Update mouse position cache - this.__mouseX = event.getDocumentLeft(); - this.__mouseY = event.getDocumentTop(); - - // this is a method invoked by an user interaction, so be careful to - // set / clear the mark this._userInteraction [BUG #3344] - this._userInteraction = true; - - // Detect move directions - var dragX = this.__mouseX + this.__frameScroll.left; - if (dragX > this.__dragStartX) { - this.__moveDirectionX = 1; - } else if (dragX < this.__dragStartX) { - this.__moveDirectionX = -1; - } else { - this.__moveDirectionX = 0; - } - - var dragY = this.__mouseY + this.__frameScroll.top; - if (dragY > this.__dragStartY) { - this.__moveDirectionY = 1; - } else if (dragY < this.__dragStartY) { - this.__moveDirectionY = -1; - } else { - this.__moveDirectionY = 0; - } - - - // Update scroll steps - var location = this.__frameLocation; - - if (this.__mouseX < location.left) { - this.__scrollStepX = this.__mouseX - location.left; - } else if (this.__mouseX > location.right) { - this.__scrollStepX = this.__mouseX - location.right; - } else { - this.__scrollStepX = 0; - } - - if (this.__mouseY < location.top) { - this.__scrollStepY = this.__mouseY - location.top; - } else if (this.__mouseY > location.bottom) { - this.__scrollStepY = this.__mouseY - location.bottom; - } else { - this.__scrollStepY = 0; - } - - - // Dynamically create required timer instance - if (!this.__scrollTimer) - { - this.__scrollTimer = new qx.event.Timer(100); - this.__scrollTimer.addListener("interval", this._onInterval, this); - } - - - // Start interval - this.__scrollTimer.start(); - - - // Auto select based on new cursor position - this._autoSelect(); - - event.stopPropagation(); - this._userInteraction = false; - }, - - - /** - * This method should be connected to the <code>addItem</code> event - * of the managed object. - * - * @param e {qx.event.type.Data} The event object - * @return {void} - */ - handleAddItem : function(e) - { - var item = e.getData(); - if (this.getMode() === "one" && this.isSelectionEmpty()) { - this.addItem(item); - } - }, - - - /** - * This method should be connected to the <code>removeItem</code> event - * of the managed object. - * - * @param e {qx.event.type.Data} The event object - * @return {void} - */ - handleRemoveItem : function(e) { - this.removeItem(e.getData()); - }, - - - - - /* - --------------------------------------------------------------------------- - MOUSE SUPPORT INTERNALS - --------------------------------------------------------------------------- - */ - - /** - * Stops all timers, release capture etc. to cleanup drag selection - */ - _cleanup : function() - { - if (!this.getDrag() && this.__inCapture) { - return; - } - - // Fire change event if needed - if (this.__selectionModified) { - this._fireChange("click"); - } - - // Remove flags - delete this.__inCapture; - delete this.__lastRelX; - delete this.__lastRelY; - - // Stop capturing - this._releaseCapture(); - - // Stop timer - if (this.__scrollTimer) { - this.__scrollTimer.stop(); - } - }, - - - /** - * Event listener for timer used by drag selection - * - * @param e {qx.event.type.Event} Timer event - */ - _onInterval : function(e) - { - // Scroll by defined block size - this._scrollBy(this.__scrollStepX, this.__scrollStepY); - - // TODO: Optimization: Detect real scroll changes first? - - // Update scroll cache - this.__frameScroll = this._getScroll(); - - // Auto select based on new scroll position and cursor - this._autoSelect(); - }, - - - /** - * Automatically selects items based on the mouse movement during a drag selection - */ - _autoSelect : function() - { - var inner = this._getDimension(); - - // Get current relative Y position and compare it with previous one - var relX = Math.max(0, Math.min(this.__mouseX - this.__frameLocation.left, inner.width)) + this.__frameScroll.left; - var relY = Math.max(0, Math.min(this.__mouseY - this.__frameLocation.top, inner.height)) + this.__frameScroll.top; - - // Compare old and new relative coordinates (for performance reasons) - if (this.__lastRelX === relX && this.__lastRelY === relY) { - return; - } - this.__lastRelX = relX; - this.__lastRelY = relY; - - // Cache anchor - var anchor = this._getAnchorItem(); - var lead = anchor; - - - // Process X-coordinate - var moveX = this.__moveDirectionX; - var nextX, locationX; - - while (moveX !== 0) - { - // Find next item to process depending on current scroll direction - nextX = moveX > 0 ? - this._getRelatedSelectable(lead, "right") : - this._getRelatedSelectable(lead, "left"); - - // May be null (e.g. first/last item) - if (nextX !== null) - { - locationX = this._getSelectableLocationX(nextX); - - // Continue when the item is in the visible area - if ( - (moveX > 0 && locationX.left <= relX) || - (moveX < 0 && locationX.right >= relX) - ) - { - lead = nextX; - continue; - } - } - - // Otherwise break - break; - } - - - // Process Y-coordinate - var moveY = this.__moveDirectionY; - var nextY, locationY; - - while (moveY !== 0) - { - // Find next item to process depending on current scroll direction - nextY = moveY > 0 ? - this._getRelatedSelectable(lead, "under") : - this._getRelatedSelectable(lead, "above"); - - // May be null (e.g. first/last item) - if (nextY !== null) - { - locationY = this._getSelectableLocationY(nextY); - - // Continue when the item is in the visible area - if ( - (moveY > 0 && locationY.top <= relY) || - (moveY < 0 && locationY.bottom >= relY) - ) - { - lead = nextY; - continue; - } - } - - // Otherwise break - break; - } - - - // Differenciate between the two supported modes - var mode = this.getMode(); - if (mode === "multi") - { - // Replace current selection with new range - this._selectItemRange(anchor, lead); - } - else if (mode === "additive") - { - // Behavior depends on the fact whether the - // anchor item is selected or not - if (this.isItemSelected(anchor)) { - this._selectItemRange(anchor, lead, true); - } else { - this._deselectItemRange(anchor, lead); - } - - // Improve performance. This mode does not rely - // on full ranges as it always extend the old - // selection/deselection. - this._setAnchorItem(lead); - } - - - // Fire change event as needed - this._fireChange("drag"); - }, - - - - - - - /* - --------------------------------------------------------------------------- - KEYBOARD SUPPORT - --------------------------------------------------------------------------- - */ - - /** - * {Map} All supported navigation keys - * - * @lint ignoreReferenceField(__navigationKeys) - */ - __navigationKeys : - { - Home : 1, - Down : 1 , - Right : 1, - PageDown : 1, - End : 1, - Up : 1, - Left : 1, - PageUp : 1 - }, - - - /** - * This method should be connected to the <code>keypress</code> event - * of the managed object. - * - * @param event {qx.event.type.KeySequence} A valid key sequence event - * @return {void} - */ - handleKeyPress : function(event) - { - // this is a method invoked by an user interaction, so be careful to - // set / clear the mark this._userInteraction [BUG #3344] - this._userInteraction = true; - - var current, next; - var key = event.getKeyIdentifier(); - var mode = this.getMode(); - - // Support both control keys on Mac - var isCtrlPressed = event.isCtrlPressed() || - (qx.core.Environment.get("os.name") == "osx" && event.isMetaPressed()); - var isShiftPressed = event.isShiftPressed(); - - var consumed = false; - - if (key === "A" && isCtrlPressed) - { - if (mode !== "single" && mode !== "one") - { - this._selectAllItems(); - consumed = true; - } - } - else if (key === "Escape") - { - if (mode !== "single" && mode !== "one") - { - this._clearSelection(); - consumed = true; - } - } - else if (key === "Space") - { - var lead = this.getLeadItem(); - if (lead != null && !isShiftPressed) - { - if (isCtrlPressed || mode === "additive") { - this._toggleInSelection(lead); - } else { - this._setSelectedItem(lead); - } - consumed = true; - } - } - else if (this.__navigationKeys[key]) - { - consumed = true; - if (mode === "single" || mode == "one") { - current = this._getSelectedItem(); - } else { - current = this.getLeadItem(); - } - - if (current !== null) - { - switch(key) - { - case "Home": - next = this._getFirstSelectable(); - break; - - case "End": - next = this._getLastSelectable(); - break; - - case "Up": - next = this._getRelatedSelectable(current, "above"); - break; - - case "Down": - next = this._getRelatedSelectable(current, "under"); - break; - - case "Left": - next = this._getRelatedSelectable(current, "left"); - break; - - case "Right": - next = this._getRelatedSelectable(current, "right"); - break; - - case "PageUp": - next = this._getPage(current, true); - break; - - case "PageDown": - next = this._getPage(current, false); - break; - } - } - else - { - switch(key) - { - case "Home": - case "Down": - case "Right": - case "PageDown": - next = this._getFirstSelectable(); - break; - - case "End": - case "Up": - case "Left": - case "PageUp": - next = this._getLastSelectable(); - break; - } - } - - // Process result - if (next !== null) - { - switch(mode) - { - case "single": - case "one": - this._setSelectedItem(next); - break; - - case "additive": - this._setLeadItem(next); - break; - - case "multi": - if (isShiftPressed) - { - var anchor = this._getAnchorItem(); - if (anchor === null) { - this._setAnchorItem(anchor = this._getFirstSelectable()); - } - - this._setLeadItem(next); - this._selectItemRange(anchor, next, isCtrlPressed); - } - else - { - this._setAnchorItem(next); - this._setLeadItem(next); - - if (!isCtrlPressed) { - this._setSelectedItem(next); - } - } - - break; - } - - this.__oldScrollTop = this._getScroll().top; - this._scrollItemIntoView(next); - } - } - - - if (consumed) - { - // Stop processed events - event.stop(); - - // Fire change event as needed - this._fireChange("key"); - } - this._userInteraction = false; - }, - - - - - - - /* - --------------------------------------------------------------------------- - SUPPORT FOR ITEM RANGES - --------------------------------------------------------------------------- - */ - - /** - * Adds all items to the selection - */ - _selectAllItems : function() - { - var range = this.getSelectables(); - for (var i=0, l=range.length; i<l; i++) { - this._addToSelection(range[i]); - } - }, - - - /** - * Clears current selection - */ - _clearSelection : function() - { - var selection = this.__selection; - for (var hash in selection) { - this._removeFromSelection(selection[hash]); - } - this.__selection = {}; - }, - - - /** - * Select a range from <code>item1</code> to <code>item2</code>. - * - * @param item1 {Object} Start with this item - * @param item2 {Object} End with this item - * @param extend {Boolean?false} Whether the current - * selection should be replaced or extended. - */ - _selectItemRange : function(item1, item2, extend) - { - var range = this._getSelectableRange(item1, item2); - - // Remove items which are not in the detected range - if (!extend) - { - var selected = this.__selection; - var mapped = this.__rangeToMap(range); - - for (var hash in selected) - { - if (!mapped[hash]) { - this._removeFromSelection(selected[hash]); - } - } - } - - // Add new items to the selection - for (var i=0, l=range.length; i<l; i++) { - this._addToSelection(range[i]); - } - }, - - - /** - * Deselect all items between <code>item1</code> and <code>item2</code>. - * - * @param item1 {Object} Start with this item - * @param item2 {Object} End with this item - */ - _deselectItemRange : function(item1, item2) - { - var range = this._getSelectableRange(item1, item2); - for (var i=0, l=range.length; i<l; i++) { - this._removeFromSelection(range[i]); - } - }, - - - /** - * Internal method to convert a range to a map of hash - * codes for faster lookup during selection compare routines. - * - * @param range {Array} List of selectable items - */ - __rangeToMap : function(range) - { - var mapped = {}; - var item; - - for (var i=0, l=range.length; i<l; i++) - { - item = range[i]; - mapped[this._selectableToHashCode(item)] = item; - } - - return mapped; - }, - - - - - - - /* - --------------------------------------------------------------------------- - SINGLE ITEM QUERY AND MODIFICATION - --------------------------------------------------------------------------- - */ - - /** - * Returns the first selected item. Only makes sense - * when using manager in single selection mode. - * - * @return {var} The selected item (or <code>null</code>) - */ - _getSelectedItem : function() - { - for (var hash in this.__selection) { - return this.__selection[hash]; - } - - return null; - }, - - - /** - * Replace current selection with given item. - * - * @param item {var} Any valid selectable item - * @return {void} - */ - _setSelectedItem : function(item) - { - if (this._isSelectable(item)) - { - // If already selected try to find out if this is the only item - var current = this.__selection; - var hash = this._selectableToHashCode(item); - - if (!current[hash] || qx.lang.Object.hasMinLength(current, 2)) - { - this._clearSelection(); - this._addToSelection(item); - } - } - }, - - - - - - - - /* - --------------------------------------------------------------------------- - MODIFY ITEM SELECTION - --------------------------------------------------------------------------- - */ - - /** - * Adds an item to the current selection. - * - * @param item {Object} Any item - */ - _addToSelection : function(item) - { - var hash = this._selectableToHashCode(item); - - if (this.__selection[hash] == null && this._isSelectable(item)) - { - this.__selection[hash] = item; - this._styleSelectable(item, "selected", true); - - this.__selectionModified = true; - } - }, - - - /** - * Toggles the item e.g. remove it when already selected - * or select it when currently not. - * - * @param item {Object} Any item - */ - _toggleInSelection : function(item) - { - var hash = this._selectableToHashCode(item); - - if (this.__selection[hash] == null) - { - this.__selection[hash] = item; - this._styleSelectable(item, "selected", true); - } - else - { - delete this.__selection[hash]; - this._styleSelectable(item, "selected", false); - } - - this.__selectionModified = true; - }, - - - /** - * Removes the given item from the current selection. - * - * @param item {Object} Any item - */ - _removeFromSelection : function(item) - { - var hash = this._selectableToHashCode(item); - - if (this.__selection[hash] != null) - { - delete this.__selection[hash]; - this._styleSelectable(item, "selected", false); - - this.__selectionModified = true; - } - }, - - - /** - * Replaces current selection with items from given array. - * - * @param items {Array} List of items to select - */ - _replaceMultiSelection : function(items) - { - var modified = false; - - // Build map from hash codes and filter non-selectables - var selectable, hash; - var incoming = {}; - for (var i=0, l=items.length; i<l; i++) - { - selectable = items[i]; - if (this._isSelectable(selectable)) - { - hash = this._selectableToHashCode(selectable); - incoming[hash] = selectable; - } - } - - // Remember last - var first = items[0]; - var last = selectable; - - // Clear old entries from map - var current = this.__selection; - for (var hash in current) - { - if (incoming[hash]) - { - // Reduce map to make next loop faster - delete incoming[hash]; - } - else - { - // update internal map - selectable = current[hash]; - delete current[hash]; - - // apply styling - this._styleSelectable(selectable, "selected", false); - - // remember that the selection has been modified - modified = true; - } - } - - // Add remaining selectables to selection - for (var hash in incoming) - { - // update internal map - selectable = current[hash] = incoming[hash]; - - // apply styling - this._styleSelectable(selectable, "selected", true); - - // remember that the selection has been modified - modified = true; - } - - // Do not do anything if selection is equal to previous one - if (!modified) { - return false; - } - - // Scroll last incoming item into view - this._scrollItemIntoView(last); - - // Reset anchor and lead item - this._setLeadItem(first); - this._setAnchorItem(first); - - // Finally fire change event - this.__selectionModified = true; - this._fireChange(); - }, - - - /** - * Fires the selection change event if the selection has - * been modified. - * - * @param context {String} One of <code>click</code>, <code>quick</code>, - * <code>drag</code> or <code>key</code> or <code>null</code> - */ - _fireChange : function(context) - { - if (this.__selectionModified) - { - // Store context - this.__selectionContext = context || null; - - // Fire data event which contains the current selection - this.fireDataEvent("changeSelection", this.getSelection()); - delete this.__selectionModified; - } - }, - - - /** - * Applies the default selection. The default item is the first item. - * - * @param force {Boolean} Whether the default selection sould forced. - * - * @return {var} The selected item. - */ - _applyDefaultSelection : function(force) - { - if (force === true || this.getMode() === "one" && this.isSelectionEmpty()) - { - var first = this._getFirstSelectable(); - if (first != null) { - this.selectItem(first); - } - return first; - } - return null; - } - }, - - - /* - ***************************************************************************** - DESTRUCTOR - ***************************************************************************** - */ - - destruct : function() - { - this._disposeObjects("__scrollTimer"); - this.__selection = this.__mouseDownOnSelected = this.__anchorItem = null; - this.__leadItem = null; - } -}); -/* ************************************************************************ - - qooxdoo - the new era of web development - - http://qooxdoo.org - - Copyright: - 2008 1&1 Internet AG, Germany, http://www.1und1.de - - License: - LGPL: http://www.gnu.org/licenses/lgpl.html - EPL: http://www.eclipse.org/org/documents/epl-v10.php - See the LICENSE file in the project's top-level directory for details. - - Authors: - * Sebastian Werner (wpbasti) - -************************************************************************ */ - -/** - * A selection manager, which handles the selection in widgets. - */ -qx.Class.define("qx.ui.core.selection.Widget", -{ - extend : qx.ui.core.selection.Abstract, - - - - /* - ***************************************************************************** - CONSTRUCTOR ... [truncated message content] |
From: <d_w...@us...> - 2012-11-29 12:30:07
|
Revision: 21820 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21820&view=rev Author: d_wagner Date: 2012-11-29 12:29:56 +0000 (Thu, 29 Nov 2012) Log Message: ----------- Fixed test for FF 3.6 Modified Paths: -------------- trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/testrunner/test_testrunner.js Modified: trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/testrunner/test_testrunner.js =================================================================== --- trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/testrunner/test_testrunner.js 2012-11-29 11:47:52 UTC (rev 21819) +++ trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/testrunner/test_testrunner.js 2012-11-29 12:29:56 UTC (rev 21820) @@ -34,7 +34,7 @@ simulation.Simulation.prototype.waitForSuiteState = function(state, timeout) { - var timeout = timeout || 60000; + timeout = timeout || 60000; var suiteStateCheck = suiteState + " == \"" + state + "\""; return this.waitForCondition(suiteStateCheck, timeout); }; @@ -53,7 +53,7 @@ failed : failedCount, skipped : skippedCount, successful : successfulCount - } + }; }; simulation.Simulation.prototype.getTestCount = function() @@ -75,6 +75,13 @@ this.log("Test suite not loaded within one minute, aborting!", "error"); return; } + + if (this.getEnvironment("browser.name") == "firefox" && + parseFloat(this.getEnvironment("browser.version")) < 4 ) + { + locators.stackTraceToggle = locators.stackTraceToggle.replace("//div[text()", "//*[@value"); + } + this.log("Suite loaded, running tests", "debug"); var tests = [ @@ -102,20 +109,20 @@ simulation.Simulation.prototype.testRunTests = function() { var testCountBefore = this.getTestCount(); - if (!testCountBefore > 0) { + if (testCountBefore === 0) { throw new Error("No tests queued!"); } this.qxClick(locators.toolbarButtonRun); if (!this.waitForSuiteState("finished")) { throw new Error("Test suite was not finished within one minute!"); } - if (!this.getTestCount() === 0) { + if (this.getTestCount() !== 0) { throw new Error("Suite is finished but not all tests were executed!"); } var resultCounts = this.getResultCounts(); - var totalResults = resultCounts.success + resultCounts.skipped + resultCounts.failed; - if (!totalResults == testCountBefore) { + var totalResults = resultCounts.successful + resultCounts.skipped + resultCounts.failed; + if (totalResults !== testCountBefore) { throw new Error("Got " + totalResults + " results for " + testCountBefore + " tests!"); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <d_w...@us...> - 2012-11-29 11:48:03
|
Revision: 21819 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21819&view=rev Author: d_wagner Date: 2012-11-29 11:47:52 +0000 (Thu, 29 Nov 2012) Log Message: ----------- Fixed test for FF 3.6 Modified Paths: -------------- trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/tutorial/test_tutorial.js Modified: trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/tutorial/test_tutorial.js =================================================================== --- trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/tutorial/test_tutorial.js 2012-11-28 15:20:20 UTC (rev 21818) +++ trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/tutorial/test_tutorial.js 2012-11-29 11:47:52 UTC (rev 21819) @@ -37,6 +37,18 @@ { this.__sel.windowMaximize(); this.__replaceCodeConfirmed = false; + + this.__isFF36 = false; + if (this.getEnvironment("browser.name") == "firefox" && + parseFloat(this.getEnvironment("browser.version")) < 4 ) + { + this.__isFF36 = true; + // qx uses labels instead of divs for the button text but '//label' + // doesn't find anything (?!?) + for (var locator in locators) { + locators[locator] = locators[locator].replace("//div[text()", "//*[@value"); + } + } var titles = this.getTutorialTitles(); for (var i=0,l=titles.length; i<l; i++) { @@ -119,8 +131,18 @@ }; simulation.Simulation.prototype.logJsError = function() { - var locator = locators.jsErrorMessage.replace(/'/g, "\\'"); - var getJSerror = "selenium.browserbot.findElement('" + locator + "').innerHTML"; + var locator, getJSerror; + if (this.__isFF36) { + locator = "//div[contains(@style, 'red')]"; + locator = locator.replace(/'/g, "\\'"); + getJSerror = "selenium.browserbot.findElement('" + locator + "').firstChild.value"; + } + else { + locator = locators.jsErrorMessage; + locator = locator.replace(/'/g, "\\'"); + getJSerror = "selenium.browserbot.findElement('" + locator + "').innerHTML"; + } + var jsError = String(this.__sel.getEval(getJSerror)); if (jsError.length > 0) { @@ -182,7 +204,7 @@ var getterFunc = 'var labels = []; var children = this.getChildren();' + 'for (var i=0; i<children.length; i++) {' + - ' if (children[i].getLabel) { ' + + ' if (children[i].getLabel && children[i].getEnabled()) { ' + ' labels.push(children[i].getLabel()); ' + ' } ' + '}' + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <d_w...@us...> - 2012-11-28 15:20:31
|
Revision: 21818 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21818&view=rev Author: d_wagner Date: 2012-11-28 15:20:20 +0000 (Wed, 28 Nov 2012) Log Message: ----------- fixed autorun URI Modified Paths: -------------- trunk/qooxdoo-contrib/Simulator/2.1/tool/selenium/simulation/unittests/test_unittests_website.js trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/unittests/test_unittests_website.js Modified: trunk/qooxdoo-contrib/Simulator/2.1/tool/selenium/simulation/unittests/test_unittests_website.js =================================================================== --- trunk/qooxdoo-contrib/Simulator/2.1/tool/selenium/simulation/unittests/test_unittests_website.js 2012-11-28 09:45:03 UTC (rev 21817) +++ trunk/qooxdoo-contrib/Simulator/2.1/tool/selenium/simulation/unittests/test_unittests_website.js 2012-11-28 15:20:20 UTC (rev 21818) @@ -54,7 +54,8 @@ } var uri = mySim.getConfigSetting("autHost") + "" + mySim.getConfigSetting("autPath"); - uri += '&autorun=1'; + var delimiter = uri.indexOf('?') == -1 ? '?' : '&'; + uri += delimiter + 'autorun=1'; mySim.__sel.open(uri); mySim.waitForElementPresent("//span[contains(text(), 'Test suite finished')]", 300000); Modified: trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/unittests/test_unittests_website.js =================================================================== --- trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/unittests/test_unittests_website.js 2012-11-28 09:45:03 UTC (rev 21817) +++ trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/unittests/test_unittests_website.js 2012-11-28 15:20:20 UTC (rev 21818) @@ -54,7 +54,8 @@ } var uri = mySim.getConfigSetting("autHost") + "" + mySim.getConfigSetting("autPath"); - uri += '&autorun=1'; + var delimiter = uri.indexOf('?') == -1 ? '?' : '&'; + uri += delimiter + 'autorun=1'; mySim.__sel.open(uri); mySim.waitForElementPresent("//span[contains(text(), 'Test suite finished')]", 300000); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <d_w...@us...> - 2012-11-28 09:45:09
|
Revision: 21817 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21817&view=rev Author: d_wagner Date: 2012-11-28 09:45:03 +0000 (Wed, 28 Nov 2012) Log Message: ----------- [BUG #7050] Fixed argument parsing Modified Paths: -------------- trunk/qooxdoo-contrib/Simulator/2.1/tool/selenium/simulation/Simulation.js Modified: trunk/qooxdoo-contrib/Simulator/2.1/tool/selenium/simulation/Simulation.js =================================================================== --- trunk/qooxdoo-contrib/Simulator/2.1/tool/selenium/simulation/Simulation.js 2012-11-28 09:43:18 UTC (rev 21816) +++ trunk/qooxdoo-contrib/Simulator/2.1/tool/selenium/simulation/Simulation.js 2012-11-28 09:45:03 UTC (rev 21817) @@ -177,26 +177,26 @@ * store them in a map. * * @private - * @param args {String} a space-delimited string of 'key=value' pairs + * @param args {Map} Map of arguments. Keys are index numbers. * @return {Map} a map of key-value pairs */ function getConfigFromArgs(args) { var conf = {}; - for (var i in args) { - if (args[i].indexOf("=") >0) { - var tempArr = args[i].split("="); - if (tempArr[1] == "true") { - conf[tempArr[0]] = true; + for (var prop in args) { + if (args[prop].indexOf("=") > 0) { + var key = args[prop].substr(0, args[prop].indexOf("=")); + var value = args[prop].substr(args[prop].indexOf("=") + 1); + if (value == "true") { + value = true; } - else if (tempArr[1] == "false") { - conf[tempArr[0]] = false; + else if (value == "false") { + value = false; } - else { - conf[tempArr[0]] = tempArr[1]; - } + conf[key] = value; } } + return conf; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <d_w...@us...> - 2012-11-28 09:43:29
|
Revision: 21816 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21816&view=rev Author: d_wagner Date: 2012-11-28 09:43:18 +0000 (Wed, 28 Nov 2012) Log Message: ----------- [BUG #7050] Fixed argument parsing Modified Paths: -------------- trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/Simulation.js Modified: trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/Simulation.js =================================================================== --- trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/Simulation.js 2012-11-28 08:21:38 UTC (rev 21815) +++ trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/Simulation.js 2012-11-28 09:43:18 UTC (rev 21816) @@ -177,26 +177,26 @@ * store them in a map. * * @private - * @param args {String} a space-delimited string of 'key=value' pairs + * @param args {Map} Map of arguments. Keys are index numbers. * @return {Map} a map of key-value pairs */ function getConfigFromArgs(args) { var conf = {}; - for (var i in args) { - if (args[i].indexOf("=") >0) { - var tempArr = args[i].split("="); - if (tempArr[1] == "true") { - conf[tempArr[0]] = true; + for (var prop in args) { + if (args[prop].indexOf("=") > 0) { + var key = args[prop].substr(0, args[prop].indexOf("=")); + var value = args[prop].substr(args[prop].indexOf("=") + 1); + if (value == "true") { + value = true; } - else if (tempArr[1] == "false") { - conf[tempArr[0]] = false; + else if (value == "false") { + value = false; } - else { - conf[tempArr[0]] = tempArr[1]; - } + conf[key] = value; } } + return conf; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <d_w...@us...> - 2012-11-28 08:21:44
|
Revision: 21815 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21815&view=rev Author: d_wagner Date: 2012-11-28 08:21:38 +0000 (Wed, 28 Nov 2012) Log Message: ----------- minor fixes Modified Paths: -------------- trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/unittests/test_unittests.js Modified: trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/unittests/test_unittests.js =================================================================== --- trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/unittests/test_unittests.js 2012-11-27 08:46:42 UTC (rev 21814) +++ trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/unittests/test_unittests.js 2012-11-28 08:21:38 UTC (rev 21815) @@ -57,7 +57,7 @@ var lastLoadedPackage, lastRunningPackage; var loadCycles = 0; var runCycles = 0; - + var getSuiteState = selWin + "." + qxAppInst + ".runner.getTestSuiteState()"; var suiteStateCheck = getSuiteState + " !== \"loading\""; var suiteReady = this.waitForCondition(suiteStateCheck, 120000); @@ -65,14 +65,15 @@ this.log("Test suite not loaded within two minutes, aborting!", "error"); } var getViewStatus = selWin + "." + qxAppInst + ".runner.view.getStatus()"; - + while (true) { Packages.java.lang.Thread.sleep(accessInterval); //Selenium doesn't like to execute the same command multiple times this.__sel.getSpeed(); var suiteState = String(this.getEval(getSuiteState)); var viewStatus = String(this.getEval(getViewStatus)); - + var match, msg; + print("========================================================="); switch (suiteState) { case "error": @@ -86,16 +87,17 @@ this.logResult(); return; } + break; case "loading": - var match = viewStatus.match(/Loading package (.*)/i); + match = viewStatus.match(/Loading package (.*)/i); if (match && match.length > 1) { var loadingPackage = match[1]; print(suiteState + " " + loadingPackage); - + if (lastLoadedPackage && lastLoadedPackage == loadingPackage) { loadCycles++; var loadTime = (loadCycles * accessInterval); - var msg = "Package " + loadingPackage + " loading for " + + msg = "Package " + loadingPackage + " loading for " + (loadTime / 1000) + "s"; this.log(msg, "debug"); print(msg); @@ -113,16 +115,16 @@ } break; case "running": - var match = viewStatus.match(/Running package (.*)/i); + match = viewStatus.match(/Running package (.*)/i); if (match && match.length > 1) { var runningPackage = match[1]; print(suiteState + " " + runningPackage); - + if (lastRunningPackage && lastRunningPackage == runningPackage) { - var packageRunTimeout = this.getConfigSetting("packageRunTimeout") + var packageRunTimeout = this.getConfigSetting("packageRunTimeout"); runCycles++; var runTime = (runCycles * accessInterval); - var msg = "Package " + runningPackage + " running for " + + msg = "Package " + runningPackage + " running for " + (runTime / 1000) + "s"; this.log(msg, "debug"); print(msg); @@ -140,7 +142,7 @@ } break; default: - var msg = "Unexpected suite state: " + suiteState + " View status: " + + msg = "Unexpected suite state: " + suiteState + " View status: " + viewStatus; this.log(msg, "warn"); return; @@ -155,7 +157,7 @@ var errors = selenium.qxStoredVars['autWindow'].qx.core.Init.getApplication().runner.view.getFormattedAutErrors(); return selenium.qxStoredVars['autWindow'].qx.lang.Json.stringify(errors); }; - + this.addOwnFunction("getAutErrors", autErrorGetter); var autErrors = ""; try { @@ -165,7 +167,7 @@ this.log("Couldn't get AUT errors " + ex.message, "warn"); return; } - + if (autErrors.length != "") { var errArr = eval(autErrors); for (var i=0,l=errArr.length; i<l; i++) { @@ -238,7 +240,7 @@ if (mySim.getConfigSetting("debug")) { print("Test run finished successfully."); } - + var totalErrors = mySim.getTotalErrorsLogged() + mySim.getTotalWarningsLogged(); mySim.log("Tests with warnings or errors: " + totalErrors, "info"); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <d_w...@us...> - 2012-11-27 08:46:53
|
Revision: 21814 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21814&view=rev Author: d_wagner Date: 2012-11-27 08:46:42 +0000 (Tue, 27 Nov 2012) Log Message: ----------- deleted obsolete tests Removed Paths: ------------- trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/custom/ trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/portal/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <d_w...@us...> - 2012-11-23 15:44:12
|
Revision: 21813 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21813&view=rev Author: d_wagner Date: 2012-11-23 15:44:05 +0000 (Fri, 23 Nov 2012) Log Message: ----------- some changes to accomodate legacy IEs Modified Paths: -------------- trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/widgetbrowser/test_widgetbrowser.js Modified: trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/widgetbrowser/test_widgetbrowser.js =================================================================== --- trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/widgetbrowser/test_widgetbrowser.js 2012-11-20 09:18:09 UTC (rev 21812) +++ trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/widgetbrowser/test_widgetbrowser.js 2012-11-23 15:44:05 UTC (rev 21813) @@ -30,7 +30,7 @@ tabContainer : '/qx.ui.container.SlideBar/qx.ui.core.scroll.ScrollPane/qx.ui.container.Composite', themeSelectBox : 'qxh=child[0]/[@classname="widgetbrowser.view.Header"]/qx.ui.form.SelectBox', themeListItem : 'qxh=*/qx.ui.popup.Popup/qx.ui.form.List/[@label="THEME"]', - stateButtonLocator : 'qxhv=qx.ui.container.Composite/*/qx.ui.tabview.TabView/*/[@label="STATE"]' + stateButtonLocator : 'qxhv=qx.ui.container.Composite/qx.ui.container.Scroll/[@classname="widgetbrowser.view.TabView"]/[@classname="widgetbrowser.view.TabPage"]/child[1]/[@label="STATE"]' }; simulation.Simulation.prototype.runTest = function() @@ -43,6 +43,9 @@ this.logGlobalErrors(); this.clearGlobalErrorStore(); + var legacyIe = this.getEnvironment("engine.name") == "mshtml" && + this.getEnvironment("browser.documentmode") < 9; + var tabNames = this.getTabNames(); var themeNames = this.getThemeNames(); @@ -50,6 +53,11 @@ var theme = themeNames[i]; this.selectTheme(theme); for (var j = tabNames.length - 1; j >= 0; j--) { + // IE running in an Application Compatibility VPC Image-based VM will crash + // when trying to destroy a Flash object + if (tabNames[j] == "Embed" && legacyIe) { + continue; + } this.testTab(tabNames[j]); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <d_w...@us...> - 2012-11-20 09:18:23
|
Revision: 21812 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21812&view=rev Author: d_wagner Date: 2012-11-20 09:18:09 +0000 (Tue, 20 Nov 2012) Log Message: ----------- Maximize window before testing Modified Paths: -------------- trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/tutorial/test_tutorial.js Modified: trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/tutorial/test_tutorial.js =================================================================== --- trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/tutorial/test_tutorial.js 2012-11-20 08:18:29 UTC (rev 21811) +++ trunk/qooxdoo-contrib/Simulator/trunk/tool/selenium/simulation/tutorial/test_tutorial.js 2012-11-20 09:18:09 UTC (rev 21812) @@ -35,6 +35,7 @@ simulation.Simulation.prototype.runTest = function() { + this.__sel.windowMaximize(); this.__replaceCodeConfirmed = false; var titles = this.getTutorialTitles(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <spa...@us...> - 2012-11-20 08:18:40
|
Revision: 21811 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21811&view=rev Author: spackers Date: 2012-11-20 08:18:29 +0000 (Tue, 20 Nov 2012) Log Message: ----------- replaces support for AppFile, see FileApi and contrib docs Added Paths: ----------- trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/FileApi.java trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/FileApiProvider.java Added: trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/FileApi.java =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/FileApi.java (rev 0) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/FileApi.java 2012-11-20 08:18:29 UTC (rev 21811) @@ -0,0 +1,510 @@ +package com.zenesis.qx.remote; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.apache.log4j.Logger; + +import com.zenesis.qx.remote.annotations.ExplicitProxyOnly; +import com.zenesis.qx.remote.annotations.Method; +import com.zenesis.qx.remote.annotations.Property; + +/** + * Provides a filing system API within a fixed root; unlike the AppFile implementation, any collection + * of file information is not shipped back to the client as Proxied instances because this can build + * up a large amount of tracked instances on the server that are difficult to free up. + * + * @author john + * + */ +@ExplicitProxyOnly +public class FileApi implements Proxied { + + private static final Logger log = Logger.getLogger(FileApi.FileType.class); + + /* + * Type of file in FileInfo + */ + public enum FileType { + FILE, FOLDER + } + + /* + * Holds extended info about a file; this is not a Proxied object because we do not + * want it's instance to be tracked (otherwise it will remain in server memory for + * the duration of the session) + */ + public static final class FileInfo { + public final String name; + public final String absolutePath; + public final FileType type; + public final long size; + public final long lastModified; + public final boolean exists; + + protected FileInfo(File file, String rootAbsPath) { + this.name = file.getName(); + this.type = file.isDirectory() ? FileType.FOLDER : FileType.FILE; + this.size = file.length(); + this.lastModified = file.lastModified(); + this.exists = file.exists(); + String absPath = file.getAbsolutePath(); + if (!absPath.startsWith(rootAbsPath)) + throw new IllegalArgumentException("File is not within root, rootAbsPath=" + rootAbsPath + ", file=" + file.getAbsolutePath()); + absolutePath = file.getAbsolutePath().substring(rootAbsPath.length() - 1); + } + } + + /* + * Filter used to select candidate files for listFilenames/listFileInfo + */ + protected static final FileFilter LIST_FILES_FILTER = new FileFilter() { + @Override + public boolean accept(File file) { + return (file.isDirectory() || file.isFile()) && !file.isHidden() && file.getName().charAt(0) != '.'; + } + }; + + // Map of mime types vs filename extensions + private static HashMap<String, String[]> s_mimeTypes; + + // Root folder + private final File rootDir; + + // Root URL + @Property + private final String rootUrl; + + // Absolute path of the root folder, with trailing slash + private final String rootAbsPath; + + // List of active uploads, indexed by ID + private HashMap<String, UploadingFile> uploading = new HashMap<String, UploadingFile>(); + + /** + * Constructor + * @param rootDir + * @throws IOException + */ + public FileApi(File rootDir, String rootUrl) { + rootDir.mkdirs(); + if (!rootDir.exists() || !rootDir.isDirectory()) + throw new IllegalArgumentException("FileApi must have a root directory, not " + rootDir.getAbsolutePath()); + this.rootDir = rootDir.getAbsoluteFile(); + rootAbsPath = rootDir.getAbsolutePath() + File.separatorChar; + if (rootUrl != null) { + if (rootUrl.length() == 0 || rootUrl.charAt(rootUrl.length() - 1) != '/') + rootUrl += '/'; + } + this.rootUrl = rootUrl; + } + + /** + * Returns a File for a given path; the path must be within the root, otherwise null is returned + * @param path + * @return a File, or null if the path was outside of the root + */ + public File getFile(String path) { + if (path.length() > 0 && path.charAt(path.length() - 1) == '/') + path = path.substring(0, path.length() - 1); + int pos; + while ((pos = path.indexOf("//")) > -1) + path = path.substring(0, pos) + path.substring(pos + 1); + File file = new File(rootDir, path).getAbsoluteFile(); + if (!isValidFile(file)) { + log.warn("Invalid path=" + path + ", rootDir=" + rootAbsPath); + return null; + } + return file; + } + + /** + * Checks whether the file is valid (ie within the root folder) + * @param file + * @return + */ + public boolean isValidFile(File file) { + String absPath = file.getAbsolutePath(); + if (file.isDirectory()) + absPath += '/'; + if (!absPath.startsWith(rootAbsPath)) + return false; + return true; + } + + /** + * Returns a list of FileInfo for the contents of a directory + * @param path + * @return null if the path was not a valid directory + */ + @Method + public FileInfo[] listFileInfos(String path) { + File dir = getFile(path); + if (dir == null || !dir.isDirectory()) + return null; + ArrayList<FileInfo> result = new ArrayList<FileInfo>(); + for (File file : dir.listFiles(LIST_FILES_FILTER)) + result.add(new FileInfo(file, rootAbsPath)); + return result.toArray(new FileInfo[result.size()]); + } + + /** + * Returns a list of filenames in a directory + * @param path + * @return null if the path was not a valid directory + */ + @Method + public String[] listFilenames(String path) { + File dir = getFile(path); + if (dir == null || !dir.isDirectory()) + return null; + ArrayList<String> result = new ArrayList<String>(); + for (File file : dir.listFiles(LIST_FILES_FILTER)) + result.add(file.getName()); + return result.toArray(new String[result.size()]); + } + + /** + * Returns FileInfo for a given file/folder + * @param path + * @return null of the path was not valid + */ + @Method + public FileInfo getFileInfo(String path) { + File file = getFile(path); + if (file == null) + return null; + return new FileInfo(file, rootAbsPath); + } + + /** + * Returns FileInfo for a given file + * @param file + * @return null if the file is not within the root folder + */ + public FileInfo getFileInfo(File file) { + if (!isValidFile(file)) + return null; + return new FileInfo(file, rootAbsPath); + } + + /** + * Renames the file; typically only works on the same physical filing system and will fail + * if the dest already exists + * @param strSrc + * @param strDest + * @return false if the rename failed + */ + @Method + public boolean renameTo(String strSrc, String strDest) { + File src = getFile(strSrc); + File dest = getFile(strDest); + if (src == null || dest == null) + return false; + dest.getParentFile().mkdirs(); + return src.renameTo(dest); + } + + /** + * Moves the file; works across filing systems and tries to complete if at all possible. If the + * source filing system is readonly, it will be a copy. Returns false if one or both paths were invalid + * @param strSrc + * @param strDest + * @return true if it succeeded + * @throws IOException + */ + @Method + public boolean moveTo(String strSrc, String strDest) throws IOException { + File src = getFile(strSrc); + File dest = getFile(strDest); + if (src == null || dest == null) + return false; + moveTo(src, dest); + return true; + } + + /** + * Copies the file; works across filing systems and tries to complete if at all possible. Returns false if + * one or both paths were invalid + * @param strSrc + * @param strDest + * @return true if it succeeded + * @throws IOException + */ + @Method + public boolean copyTo(String strSrc, String strDest) throws IOException { + File src = getFile(strSrc); + File dest = getFile(strDest); + if (src == null || dest == null) + return false; + copyTo(src, dest); + return true; + } + + /** + * Deletes a file; the path must refer to a file or an empty directory + * @param path + * @return false if the path was invalid or could not be deleted + */ + @Method + public boolean deleteFile(String path) { + File file = getFile(path); + if (file == null) + return false; + return file.delete(); + } + + /** + * Deletes a file, or if a directory will delete recursively + * @param path + * @return false if the path was invalid or could not be deleted + */ + @Method + public boolean deleteRecursive(String path) { + File file = getFile(path); + if (file == null) + return false; + if (file.isFile()) + return file.delete(); + deleteRecursiveInternal(file); + return !file.exists(); + } + + /** + * Creates a directory and any parent folders + * @param path + * @return false if the path was invalid or the directory could not be created (eg a file with the same + * name already exists); true if the directory was created or if it already existed + */ + @Method + public FileInfo createFolder(String path) { + File file = getFile(path); + if (file != null) { + file.mkdirs(); + if (file.exists() && file.isDirectory()) + return getFileInfo(file); + } + return null; + } + + /** + * Tests whether a file exists + * @param path + * @return false if it does not exist or the path was invalid + */ + @Method + public boolean exists(String path) { + File file = getFile(path); + return file != null && file.exists(); + } + + /** + * Detects the type of the file + * @param path + * @return + */ + @Method + public FileType getType(String path) { + File file = getFile(path); + if (file == null) + return null; + return file.isDirectory() ? FileType.FOLDER : file.isFile() ? FileType.FILE : null; + } + + /** + * Called when an upload begins + * @param upfile + * @throws IOException + */ + public void beginUploadingFile(UploadingFile upfile) throws IOException { + uploading.put(upfile.getUploadId(), upfile); + } + + /** + * Called when an upload completes + * @param upfile + * @param success + * @return + * @throws IOException + */ + public File endUploadingFile(UploadingFile upfile, boolean success) throws IOException { + if (!success) { + uploading.remove(upfile.getUploadId()); + return null; + } + + String uploadFolder = null; + Object obj = upfile.getParams().get("uploadFolder"); + if (obj instanceof String) { + uploadFolder = (String)obj; + } else { + uploadFolder = "/"; + } + + File dest = getFile(uploadFolder + "/" + upfile.getOriginalName()); + moveTo(upfile.getFile(), dest); + return dest; + } + + /** + * Returns the UploadingFile2 instance for a given upload ID (if it's still uploading) + * @param uploadId + * @return + */ + public UploadingFile getUploadingFile(String uploadId) { + UploadingFile upfile = uploading.get(uploadId); + return upfile; + } + + /** + * Removes a file from the list of currently uploading files + * @param uploadId + */ + public void clearUploadedFile(String uploadId) { + uploading.remove(uploadId); + } + + /** + * Moves a file or directory if at all possible, copying and deleting the original if necessary. Supports + * recursively moving folders as well as files + * @param src + * @param dest + * @throws IOException + */ + protected void moveTo(File src, File dest) throws IOException { + if (src.isDirectory()) { + if (dest.isFile()) + throw new IOException("Cannot move " + src.getAbsolutePath() + " to " + dest.getAbsolutePath() + " because dest is a file"); + dest.mkdirs(); + if (!dest.exists()) + throw new IOException("Cannot create folder " + dest.getAbsolutePath()); + File[] files = src.listFiles(); + boolean ok = true; + for (File file : files) { + moveTo(file, new File(dest, file.getName())); + if (file.exists()) + ok = false; + } + if (ok) + src.delete(); + return; + } + + if (!src.isFile()) + throw new IOException("Not a file or directory: " + src.getAbsolutePath()); + + if (dest.exists()) { + if (dest.isDirectory()) + dest = new File(dest, src.getName()); + if (dest.exists()) + dest.delete(); + } + + if (dest.renameTo(dest)) + return; + + copyTo(src, dest); + src.delete(); + } + + /** + * Copies a file or directory if at all possible, copying and deleting the original if necessary. Supports + * recursively copying folders as well as files + * @param src + * @param dest + * @throws IOException + */ + protected void copyTo(File src, File dest) throws IOException { + if (src.isFile()) { + if (dest.isDirectory()) + throw new IOException("Cannot copy " + src.getAbsolutePath() + " to " + dest.getAbsolutePath() + " because dest is a directory"); + FileOutputStream os = null; + FileInputStream is = null; + dest.getParentFile().mkdirs(); + try { + os = new FileOutputStream(dest); + is = new FileInputStream(src); + byte[] buffer = new byte[1024 * 32]; + int len; + while ((len = is.read(buffer)) > -1) + os.write(buffer, 0, len); + is.close(); + is = null; + os.close(); + os = null; + }catch(IOException e) { + if (is != null) + try { is.close(); } catch(IOException e2) {} + if (os != null) + try { os.close(); } catch(IOException e2) {} + throw e; + } + } else { + if (dest.isFile()) + throw new IOException("Cannot copy " + src.getAbsolutePath() + " to " + dest.getAbsolutePath() + " because dest is a file"); + dest.mkdirs(); + File[] files = src.listFiles(); + if (files != null) + for (int i = 0; i < files.length; i++) { + File destChild = new File(dest, files[i].getName()); + copyTo(files[i], destChild); + } + } + } + + /** + * Does a recursive delete of the directory + * @param dir + */ + protected void deleteRecursiveInternal(File dir) { + File[] files = dir.listFiles(); + if (files != null) + for (File file : files) + if (file.isDirectory()) + deleteRecursiveInternal(file); + else + file.delete(); + dir.delete(); + } + + /** + * @return the rootDir + */ + public File getRootDir() { + return rootDir; + } + + /** + * @return the rootUrl + */ + public String getRootUrl() { + return rootUrl; + } + + /** + * Returns the mapping between mime type and file extensions + * @return + */ + @Method(cacheResult=true) + public Map<String, String[]> getMimeTypes() { + if (s_mimeTypes == null) + return Collections.EMPTY_MAP; + return s_mimeTypes; + } + + /** + * Sets the global mime types lookup; the map should contain MIME type (eg "text/plain") as keys and + * an array of extensions as the value, the extensions should include the "." + * @param mimeTypes + */ + public static void setMimeTypes(HashMap<String, String[]> mimeTypes) { + s_mimeTypes = mimeTypes; + } +} Added: trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/FileApiProvider.java =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/FileApiProvider.java (rev 0) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/FileApiProvider.java 2012-11-20 08:18:29 UTC (rev 21811) @@ -0,0 +1,21 @@ +package com.zenesis.qx.remote; + +import java.io.File; +import java.io.IOException; + +import com.zenesis.qx.remote.annotations.DoNotProxy; + +/** + * This interface must be implemented by Bootstrap objects which can be uploaded to + * by the UploadHandler + * + * @author "John Spackman <joh...@ze...>" + */ +public interface FileApiProvider extends Proxied { + + /** + * Returns a FileApi instance, eg for handling uploads + * @return + */ + public FileApi getFileApi(); +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <spa...@us...> - 2012-11-20 08:17:30
|
Revision: 21810 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21810&view=rev Author: spackers Date: 2012-11-20 08:17:21 +0000 (Tue, 20 Nov 2012) Log Message: ----------- replaces support for AppFile, see FileApi and contrib docs Modified Paths: -------------- trunk/qooxdoo-contrib/ServerObjects/trunk/client/demoapp/Manifest.json trunk/qooxdoo-contrib/ServerObjects/trunk/client/qso-lib/Manifest.json trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/json/JsonSerialiserFactory.java trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/BasicBootstrap.java trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/ProxyManager.java trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/ProxyPropertyImpl.java trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/ProxySessionTracker.java trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/UploadHandler.java trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/UploadingFile.java trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/test/com/zenesis/qx/remote/explorer/FileExplorer.java Removed Paths: ------------- trunk/qooxdoo-contrib/ServerObjects/trunk/Documentation.doc trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/AppFile.java trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/UploadHandler.java.save trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/UploadReceiver.java Deleted: trunk/qooxdoo-contrib/ServerObjects/trunk/Documentation.doc =================================================================== (Binary files differ) Modified: trunk/qooxdoo-contrib/ServerObjects/trunk/client/demoapp/Manifest.json =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/client/demoapp/Manifest.json 2012-11-20 08:14:54 UTC (rev 21809) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/client/demoapp/Manifest.json 2012-11-20 08:17:21 UTC (rev 21810) @@ -18,7 +18,7 @@ ], "version" : "trunk", - "qooxdoo-versions": ["1.1"] + "qooxdoo-versions": ["1.6", "2.0", "2.1" ] }, "provides" : Modified: trunk/qooxdoo-contrib/ServerObjects/trunk/client/qso-lib/Manifest.json =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/client/qso-lib/Manifest.json 2012-11-20 08:14:54 UTC (rev 21809) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/client/qso-lib/Manifest.json 2012-11-20 08:17:21 UTC (rev 21810) @@ -18,7 +18,7 @@ ], "version" : "trunk", - "qooxdoo-versions": ["1.5"] + "qooxdoo-versions": ["1.6", "2.0", "2.1" ] }, "provides" : Modified: trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/json/JsonSerialiserFactory.java =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/json/JsonSerialiserFactory.java 2012-11-20 08:14:54 UTC (rev 21809) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/json/JsonSerialiserFactory.java 2012-11-20 08:17:21 UTC (rev 21810) @@ -31,8 +31,10 @@ import java.text.SimpleDateFormat; import java.util.Date; +import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.JsonGenerator; import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.impl.JsonWriteContext; import org.codehaus.jackson.map.BeanProperty; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.JsonSerializer; @@ -42,6 +44,7 @@ import org.codehaus.jackson.map.SerializerProvider; import org.codehaus.jackson.map.ser.BeanSerializerFactory; import org.codehaus.jackson.type.JavaType; +import org.codehaus.jackson.util.CharTypes; public class JsonSerialiserFactory extends BeanSerializerFactory { @@ -63,6 +66,62 @@ } }; + private static final JsonSerializer SER_STRING = new JsonSerializer<String>() { + + final char[] HEX_CHARS = "0123456789ABCDEF".toCharArray(); + final int[] ESCAPE_CODES = CharTypes.get7BitOutputEscapes(); + + private void writeUnicodeEscape(JsonGenerator gen, char c) + throws IOException { + gen.writeRaw('\\'); + gen.writeRaw('u'); + gen.writeRaw(HEX_CHARS[(c >> 12) & 0xF]); + gen.writeRaw(HEX_CHARS[(c >> 8) & 0xF]); + gen.writeRaw(HEX_CHARS[(c >> 4) & 0xF]); + gen.writeRaw(HEX_CHARS[c & 0xF]); + } + + private void writeShortEscape(JsonGenerator gen, char c) + throws IOException { + gen.writeRaw('\\'); + gen.writeRaw(c); + } + + @Override + public void serialize(String str, JsonGenerator gen, SerializerProvider provider) throws IOException { + int status = ((JsonWriteContext) gen.getOutputContext()) .writeValue(); + switch (status) { + case JsonWriteContext.STATUS_OK_AFTER_COLON: + gen.writeRaw(':'); + break; + + case JsonWriteContext.STATUS_OK_AFTER_COMMA: + gen.writeRaw(','); + break; + + case JsonWriteContext.STATUS_EXPECT_NAME: + throw new JsonGenerationException("Can not write string value here"); + } + gen.writeRaw('"'); + for (char c : str.toCharArray()) { + if (c >= 0x80) + writeUnicodeEscape(gen, c); // use generic escaping for all + // non US-ASCII characters + else { + // use escape table for first 128 characters + int code = (c < ESCAPE_CODES.length ? ESCAPE_CODES[c] : 0); + if (code == 0) + gen.writeRaw(c); // no escaping + else if (code < 0) + writeUnicodeEscape(gen, (char) (-code - 1)); // generic escaping + else + writeShortEscape(gen, (char) code); // short escaping (\n \t ...) + } + } + gen.writeRaw('"'); + } + }; + private static final JsonSerializer SER_ENUM = new JsonSerializer<Enum>() { /* (non-Javadoc) @@ -86,6 +145,8 @@ if (Date.class.isAssignableFrom(origType.getRawClass())) return SER_DATE; + if (String.class.isAssignableFrom(origType.getRawClass())) + return SER_STRING; if (origType.isEnumType()) return SER_ENUM; Deleted: trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/AppFile.java =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/AppFile.java 2012-11-20 08:14:54 UTC (rev 21809) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/AppFile.java 2012-11-20 08:17:21 UTC (rev 21810) @@ -1,550 +0,0 @@ -package com.zenesis.qx.remote; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Date; - -import org.apache.log4j.Logger; - -import com.zenesis.qx.remote.Proxied; -import com.zenesis.qx.remote.ProxyManager; -import com.zenesis.qx.remote.annotations.DoNotProxy; -import com.zenesis.qx.remote.annotations.Properties; -import com.zenesis.qx.remote.annotations.Property; - -/** - * Represents a file on the disk that can be accessed by the application - * - * @author "John Spackman <joh...@ze...>" - */ -@Properties({ - @Property(value="children", onDemand=true, event="changeChildren", arrayType=AppFile.class, expire="expireChildren"), - @Property("contentType"), - @Property("folder"), - @Property("lastModified"), - @Property(value="name", event="changeName"), - @Property("parent"), - @Property("readOnly"), - @Property("size"), - @Property("url"), - @Property("thumbnailUrl") -}) -public class AppFile implements Proxied { - - private static final Logger log = Logger.getLogger(AppFile.class); - - private File file; - private AppFile parent; - private String url; - - private String name; - private boolean readOnly; - private Date lastModified; - private long size; - private ArrayList<AppFile> children; - - /** - * Constructor - * @param file - * @param parent - */ - public AppFile(File file, String url) { - this(null, file, url); - } - - /** - * Constructor - * @param file - * @param parent - */ - public AppFile(AppFile parent, File file, String url) { - super(); - this.file = file; - this.url = url; - this.parent = parent; - - name = file.getName(); - readOnly = !file.canWrite(); - lastModified = new Date(file.lastModified()); - size = file.length(); - } - - /** - * @param file - * @param parent - */ - protected AppFile(File file, AppFile parent) { - super(); - this.file = file; - this.parent = parent; - this.url = addPath(parent.url, file.getName()); - - name = file.getName(); - readOnly = !file.canWrite(); - lastModified = new Date(file.lastModified()); - size = file.length(); - } - - /** - * Creates a child folder - * @param path - * @return - */ - public AppFile createFolder(String path) { - if (!file.isDirectory()) - return null; - if (path.contains("..")) - throw new IllegalArgumentException("Invalid filename " + path + " (double dots are not allowed)"); - if (path.length() > 1 && path.charAt(1) == ':') - throw new IllegalArgumentException("Invalid filename " + path + " (drive specifications are not allowed)"); - if (path.indexOf('/') > -1) - throw new IllegalArgumentException("Invalid filename " + path + " (paths are not allowed)"); - File dir = new File(file, path); - if (!dir.mkdir()) - throw new IllegalArgumentException("Invalid filename " + path + " (could not create directory)"); - AppFile child = new AppFile(dir, this); - if (children != null) - children.add(child); - ProxyManager.propertyChanged(this, "children", children, children); - return child; - } - - /** - * Adds a file to the folder; if copy is true the file is copied, otherwise it is moved - * into this folder. - * @param file - * @param copy if true, the file is copied, not moved - * @param makeUniqueName if true and a file with that name already exists, it is renamed to - * avoid a collision, otherwise the target file is replaced - * @return - */ - public AppFile addFile(File newFile, String desiredName, boolean copy, boolean makeUniqueName) throws IOException { - String absPath = newFile.getAbsolutePath(); - if (!newFile.exists()) - throw new FileNotFoundException(absPath); - file.mkdirs(); - if (!file.isDirectory()) - throw new IOException("Cannot add a file to " + file.getAbsolutePath() + " because it is not a directory"); - - File dest; - boolean fileWasReplaced = false; - if (desiredName == null) - desiredName = file.getName(); - - // Check if it is already in our directory - if (newFile.getParentFile().getAbsolutePath().equals(this.file.getAbsolutePath())) - dest = newFile; - - // Otherwise copy or move it - else { - dest = new File(file, desiredName); - - // Check for name collisions - if (dest.exists()) { - if (makeUniqueName) { - // Break out the name body and the extension - String name = dest.getName(); - String ext; - int pos = name.lastIndexOf('.'); - if (pos < 0) - ext = ""; - else { - ext = name.substring(pos); - name = name.substring(0, pos); - } - - // Loop until we find a unique name - for (int index = 1; dest.exists(); index++) - dest = new File(file, name + '-' + index + ext); - } else - fileWasReplaced = true; - } - - // Try and move it first, but fallback to copying the file - if (!copy) { - if (fileWasReplaced) - dest.delete(); - if (!newFile.renameTo(dest)) - copy = true; - } - - // Copy the file - if (copy) { - FileOutputStream os = new FileOutputStream(dest); - FileInputStream is = new FileInputStream(newFile); - try { - byte[] buffer = new byte[8 * 1024]; // 8K is Tomcat6 default and best optimized - int len; - while ((len = is.read(buffer)) > -1) - os.write(buffer, 0, len); - }finally { - try { os.close(); } catch(IOException e) {} - try { is.close(); } catch(IOException e) {} - } - } - } - - // Try and find the child - boolean alreadyLoadedChildren = this.children != null; - getChildren(); - for (int i = 0; i < children.size(); i++) { - AppFile child = children.get(i); - if (child.getName().equalsIgnoreCase(dest.getName())) - return child; - } - - // If the call to getChildren() loaded the list, then we're done - the file has disappeared - // while we looked for it - if (!alreadyLoadedChildren) - return null; - - // Add the new file to the list - AppFile newChild = new AppFile(dest, this); - children.add(newChild); - ProxyManager.propertyChanged(this, "children", children, children); - - return newChild; - } - - /** - * Returns the difference between this file and the given directory, i.e. a path - * which when added to the directory <code>dir</code> will produce this file. - * @param dir the directory to be reached from - * @return the relative path - */ - public String getRelativePath(AppFile dir) { - String dirPath = dir.getFile().getAbsolutePath(); - String myPath = file.getAbsolutePath(); - boolean isCaseSensitive = !new File(file.getName().toUpperCase()).equals(new File(file.getName().toLowerCase())); - if (!isCaseSensitive) { - dirPath = dirPath.toLowerCase(); - myPath = myPath.toLowerCase(); - } - - // Check for easy ancestor relatives - if (myPath.startsWith(dirPath)) { - String str = myPath.substring(dirPath.length()); - if (str.length() > 0 && str.charAt(0) == File.separatorChar) - str = str.substring(1); - return str; - } - - String strRoot = ""; - - // Check for file on different root (i.e. different drive on windows) - File[] roots = File.listRoots(); - for (int i = 0; i < roots.length; i++) { - strRoot = roots[i].getAbsolutePath(); - if (myPath.startsWith(strRoot)) { - // Different root? Then an explicit path is the only way - if (!dirPath.startsWith(strRoot)) - return myPath; - - // Remove the common root - myPath = myPath.substring(strRoot.length()); - dirPath = dirPath.substring(strRoot.length()); - break; - } - } - - /* - * (1) Easy parent dir - done above - * Dir: /a/b/c - * My: /a/b/c/d/e - * Res: d/e - * - * (2) Partial path - * Dir: /a/b/c - * My: /a/d/e - * Res: ../../d/e - * - * Dir: /a/b/c/d/e - * My: /a/x/y - * Res: ../../../../x/y - * - * (3) Nothing in common - * Dir: /a/b/c - * My: /x/y/z - * Res: /x/y/z - * - * (4) Trick question, same dir - * Dir: /a/b - * My: /a/b/c - * Res: c - */ - String[] dirSegs = dirPath.split(File.separator); - String[] mySegs = myPath.split(File.separator); - - // Nothing in common? Retyurn the absolute path - if (dirSegs.length == 0 || mySegs.length == 0 || !dirSegs[0].equals(mySegs[0])) - return strRoot + myPath; - - // Look for the first disparity - int firstMismatch = 1; - while (firstMismatch < dirSegs.length && firstMismatch < mySegs.length) { - if (!dirSegs[firstMismatch].equals(mySegs[firstMismatch])) - break; - firstMismatch++; - } - - StringBuilder sb = new StringBuilder(); - - // Add dots to make it back to the common relative - int dots = dirSegs.length - firstMismatch; - for (int i = 0; i < dots; i++) - sb.append("..").append(File.separatorChar); - - // Add the remainder - for (int i = firstMismatch; i < mySegs.length; i++) { - if (i != firstMismatch) - sb.append(File.separatorChar); - sb.append(mySegs[i]); - } - - // Done - return sb.toString(); - } - - /** - * Returns the actual, underlying file - * @return - */ - @DoNotProxy - public File getFile() { - return file; - } - - /** - * Returns the MIME content type for the file, based on extension - * @return - */ - public String getContentType() { - return ProxyManager.getInstance().getContentType(file); - } - - /** - * Name of the file - * @return - */ - public String getName() { - return name; - } - - /** - * @return the url - */ - public String getUrl() { - return url; - } - - /** - * @return the url - */ - public String getThumbnailUrl() { - return url + "?gh:size=200x200&enlarge=false"; - } - - /** - * Renames the file - * @param name - */ - public boolean rename(String name) { - if (parent == null) - return false; - if (name.equals(this.name)) - return true; - File to = new File(file.getParentFile(), name); - if (to.exists() || !file.renameTo(to)) - return false; - this.file = to; - this.url = ProxyManager.changeProperty(this, "url", addPath(parent.url, file.getName()), this.url); - return true; - } - - /** - * Gets a list of children, caching the result - * @return - */ - public ArrayList<AppFile> getChildren() { - if (children != null || !file.isDirectory()) - return children; - loadChildren(); - return children; - } - - /** - * Flushes the cached value for the children property - * @param property - */ - public void expireChildren(ProxyProperty property) { - children = null; - } - - /** - * Loads the children, discarding any existing children - */ - private void loadChildren() { - if (children == null) - children = new ArrayList<AppFile>(); - else - children.clear(); - - File[] files = file.listFiles(); - if (files != null) { - for (File child : files) { - if (!child.getName().startsWith(".")) - children.add(new AppFile(child, this)); - } - } - } - - /** - * Returns a child with the given name, or null if the file could not be found - * @param name - * @return - */ - public AppFile getChild(String name) { - File file = new File(this.file, name); - if (!isAncestorOf(file)) - throw new IllegalArgumentException("Cannot find file " + file.getAbsolutePath() + " because it is not in a sub fodler"); - if (!file.exists()) - return null; - String[] segs = name.split("/"); - AppFile curAppFile = this; - for (String seg : segs) - curAppFile = curAppFile.getChildImpl(seg); - return curAppFile; - } - - /** - * Finds a child, and integrates it with this - * @param name - * @return - */ - protected AppFile getChildImpl(String name) { - if (name.indexOf('/') > -1 || name.indexOf('\\') > -1) - throw new IllegalArgumentException("Cannot get child called '" + name + "', paths are not supported"); - if (children == null) { - File file = new File(this.file, name); - if (!file.exists()) - return null; - return new AppFile(this, file, addPath(url, name)); - } else { - for (AppFile child : children) { - if (child.getName().equalsIgnoreCase(name)) - return child; - } - File file = new File(this.file, name); - if (!file.exists()) - return null; - AppFile child = new AppFile(this, file, addPath(url, name)); - children.add(child); - return child; - } - } - - /** - * Tests whether this is a ancestor (parent, grand parent, etc) of the given file - * @param file - * @return - */ - protected boolean isAncestorOf(File file) { - String tpath; - String fpath; - try { - tpath = this.file.getCanonicalFile().getAbsolutePath(); - }catch(IOException e) { - log.error("Error getting canoninical path for this=" + this.file.getAbsolutePath() + ": " + e.getMessage()); - return false; - } - try { - fpath = file.getCanonicalFile().getAbsolutePath(); - }catch(IOException e) { - log.error("Error getting canoninical path for file=" + file.getAbsolutePath() + ": " + e.getMessage()); - return false; - } - if (!fpath.startsWith(fpath)) - return false; - return fpath.length() == tpath.length() || fpath.charAt(tpath.length()) == File.separatorChar; - } - - /** - * @return the parent - */ - public AppFile getParent() { - return parent; - } - - /** - * Sets the read-only attribute - * @return - */ - public boolean isReadOnly() { - return readOnly; - } - - /** - * Returns the read-only attribute - * @param readOnly - */ - public void setReadOnly(boolean readOnly) { - this.readOnly = readOnly; - } - - /** - * Returns the date it was last modified - * @return - */ - public Date getLastModified() { - return lastModified; - } - - /** - * Returns the file size - * @return - */ - public long getSize() { - return size; - } - - /** - * @return true if the file is a directory - */ - public boolean isFolder() { - return file.isDirectory(); - } - - /** - * Deletes the file - */ - public void deleteFile() { - file.delete(); - } - - /** - * Appends the name to the base, taking care not to duplicate slashes - * @param base - * @param name - * @return - */ - private String addPath(String base, String name) { - String str = base; - if (!str.endsWith("/")) - str += "/"; - str += name; - return str; - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - @DoNotProxy - public String toString() { - return file.toString(); - } -} Modified: trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/BasicBootstrap.java =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/BasicBootstrap.java 2012-11-20 08:14:54 UTC (rev 21809) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/BasicBootstrap.java 2012-11-20 08:17:21 UTC (rev 21810) @@ -10,6 +10,7 @@ import com.zenesis.qx.remote.annotations.Properties; import com.zenesis.qx.remote.annotations.Property; import com.zenesis.qx.remote.annotations.Remote; +import com.zenesis.qx.remote.annotations.Remote.Toggle; /** * Basic implementation of a Bootstrap object, which provides methods for handling uploading. @@ -20,17 +21,11 @@ * * @author "John Spackman <joh...@ze...>" */ -@Properties({ - @Property(value="appFilesRoot", readOnly=Remote.Toggle.TRUE), - @Property("uploadFolder") -}) -public class BasicBootstrap implements UploadReceiver { +public class BasicBootstrap implements FileApiProvider { - private AppFile appFilesRoot; - private AppFile uploadFolder; - private HashMap<String, UploadingFile> uploading = new HashMap<String, UploadingFile>(); - private boolean restrictUploadFolder = true; - + @Property(readOnly=Toggle.TRUE) + private FileApi fileApi; + /** * Constructor */ @@ -41,9 +36,9 @@ /** * @param appFilesRoot */ - public BasicBootstrap(AppFile appFilesRoot) { + public BasicBootstrap(FileApi fileApi) { super(); - this.appFilesRoot = appFilesRoot; + this.fileApi = fileApi; } /** @@ -56,170 +51,20 @@ public void loadProxyType(Object data) throws ClassNotFoundException { ProxyManager.loadProxyType(data); } - - /** - * Converts <code>file</code>into an <code>AppFile</code>; the file must be within the root folder - * @param file - * @return - */ - @DoNotProxy - public AppFile getAppFile(File file) throws IllegalArgumentException { - AppFile appFile = getAppFilesRoot(); - if (appFile == null) - throw new IllegalArgumentException("Cannot convert file because there is no app files root"); - - // Check it's within the root folder - String strRF = appFile.getFile().getAbsolutePath().toLowerCase(); - String strF = file.getAbsolutePath().toLowerCase(); - int lenRF = strRF.length(); - if (!strF.startsWith(strRF) || (strF.length() > lenRF && "\\/".indexOf(strF.charAt(lenRF)) < 0)) - throw new IllegalArgumentException("Cannot convert " + strF + " because it is outside the root folder"); - - // Exact match for the app root - if (lenRF == strF.length()) - return appFile; - - // Walk the tree to find the child - strF = strF.substring(lenRF + 1).replace('\\', '/'); - StringTokenizer st = new StringTokenizer(strF, "/"); - while (st.hasMoreTokens()) { - String name = st.nextToken(); - appFile = appFile.getChild(name); - if (appFile == null) - return null; - } - - return appFile; - } - - /** - * Returns the AppFile for a given download URL (i.e. AppFile.getUrl() matches the result of this method) - * @param partialUrl - * @return null if the file cannot be found - */ - public AppFile getAppFileFromURL(String partialUrl) { - AppFile appFile = getAppFilesRoot(); - if (appFile == null) - throw new IllegalArgumentException("Cannot convert file because there is no app files root"); - - int pos = partialUrl.indexOf('?'); - if (pos > 0) - partialUrl = partialUrl.substring(0, pos); - partialUrl = partialUrl.replace('\\', '/'); - - if (partialUrl.startsWith("/") && !partialUrl.startsWith(appFile.getUrl())) - throw new IllegalArgumentException("Cannot get AppFile because the url " + partialUrl + " is not inside the app files root"); - partialUrl = partialUrl.substring(appFile.getUrl().length()); - - StringTokenizer st = new StringTokenizer(partialUrl, "/"); - while (st.hasMoreTokens()) { - String name = st.nextToken(); - appFile = appFile.getChild(name); - if (appFile == null) - return null; - } - - return appFile; - } - - /* (non-Javadoc) - * @see com.zenesis.qx.remote.UploadReceiver#beginUploadingFile(com.zenesis.qx.remote.UploadingFile) - */ - @Override - public void beginUploadingFile(UploadingFile upfile) throws IOException { - uploading.put(upfile.getUploadId(), upfile); - } /* (non-Javadoc) - * @see com.zenesis.qx.remote.UploadReceiver#endUploadingFile(com.zenesis.qx.remote.UploadingFile, boolean) + * @see com.zenesis.qx.remote.FileApiProvider#getFileApi() */ @Override - public AppFile endUploadingFile(UploadingFile upfile, boolean success) throws IOException { - if (!success) { - uploading.remove(upfile.getUploadId()); - return null; - } - - Object obj = upfile.getParams().get("uploadFolder"); - AppFile uploadFolder = (AppFile)obj; - if (uploadFolder != null) { - if (isRestrictUploadFolder() && getAppFilesRoot() != null) { - String strUF = uploadFolder.getFile().getAbsolutePath().replace('\\', '/'); - String strRF = getAppFilesRoot().getFile().getAbsolutePath().replace('\\', '/'); - if (strRF.charAt(strRF.length() - 1) != '/') - strRF += "/"; - if (strUF.charAt(strUF.length() - 1) != '/') - strUF += "/"; - if (!strUF.startsWith(strRF)) - throw new IOException("Cannot upload " + upfile + " because the upload folder is outside the root folder"); - } - } else - uploadFolder = getUploadFolder(); - if (uploadFolder == null) - throw new IOException("Cannot upload " + upfile + " because there is no root to upload to"); - AppFile appFile = uploadFolder.addFile(upfile.getFile(), upfile.getOriginalName(), false, false); - return appFile; + public FileApi getFileApi() { + return fileApi; } - /* (non-Javadoc) - * @see com.zenesis.qx.remote.UploadReceiver#getUploadingFile(java.lang.String) - */ - @Override - public UploadingFile getUploadingFile(String uploadId) { - UploadingFile upfile = uploading.get(uploadId); - return upfile; - } - - /* (non-Javadoc) - * @see com.zenesis.qx.remote.UploadReceiver#clearUploadedFile(java.lang.String) - */ - @Override - public void clearUploadedFile(String uploadId) { - uploading.remove(uploadId); - } - /** - * @return the restrictUploadFolder + * @param fileApi the fileApi to set */ - public boolean isRestrictUploadFolder() { - return restrictUploadFolder; + public void setFileApi(FileApi fileApi) { + this.fileApi = fileApi; } - - /** - * @param restrictUploadFolder the restrictUploadFolder to set - */ - @DoNotProxy - public void setRestrictUploadFolder(boolean restrictUploadFolder) { - this.restrictUploadFolder = restrictUploadFolder; - } - - /** - * @return the appFilesRoot - */ - public AppFile getAppFilesRoot() { - return appFilesRoot; - } - - /** - * @param appFilesRoot the appFilesRoot to set - */ - public void setAppFilesRoot(AppFile appFilesRoot) { - this.appFilesRoot = appFilesRoot; - } - - /** - * @return the uploadFolder - */ - public AppFile getUploadFolder() { - return uploadFolder; - } - - /** - * @param uploadFolder the uploadFolder to set - */ - public void setUploadFolder(AppFile uploadFolder) { - this.uploadFolder = uploadFolder; - } - } Modified: trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/ProxyManager.java =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/ProxyManager.java 2012-11-20 08:14:54 UTC (rev 21809) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/ProxyManager.java 2012-11-20 08:17:21 UTC (rev 21810) @@ -487,8 +487,46 @@ tracker.invalidateCache((Proxied)obj); } } + + /** + * Forgets an object + * @param keyObject + */ + public static void forget(Proxied keyObject) { + ProxySessionTracker tracker = getTracker(); + if (tracker == null) + return; + tracker.forget(keyObject); + } /** + * Forgets objects + * @param keyObjects + */ + public static void forget(Proxied[] keyObjects) { + ProxySessionTracker tracker = getTracker(); + if (tracker == null) + return; + for (Proxied obj : keyObjects) + tracker.forget(obj); + } + + /** + * forgets objects + * @param keyObjects + */ + public static void forget(Iterable list) { + ProxySessionTracker tracker = getTracker(); + if (tracker == null) + return; + for (Iterator iter = list.iterator(); iter.hasNext(); ) { + Object obj = iter.next(); + if (obj instanceof Proxied) + tracker.forget((Proxied)obj); + } + } + + /** * Sends a class definition to the server * @param clazz */ Modified: trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/ProxyPropertyImpl.java =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/ProxyPropertyImpl.java 2012-11-20 08:14:54 UTC (rev 21809) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/ProxyPropertyImpl.java 2012-11-20 08:17:21 UTC (rev 21810) @@ -240,7 +240,7 @@ } catch(IllegalAccessException e) { throw new IllegalArgumentException("Cannot write property " + name + " in class " + clazz + " in object " + proxied + ": " + e.getMessage(), e); } catch(IllegalArgumentException e) { - throw new IllegalArgumentException("Failed to set value for property " + name + " in class " + clazz + " to value " + value, e); + throw new IllegalArgumentException("Failed to set value for property " + name + " in class " + clazz + " to value " + value + ", method=" + setMethod + ", field=" + field, e); } } Modified: trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/ProxySessionTracker.java =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/ProxySessionTracker.java 2012-11-20 08:14:54 UTC (rev 21809) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/ProxySessionTracker.java 2012-11-20 08:17:21 UTC (rev 21810) @@ -378,6 +378,19 @@ } /** + * Causes the tracker to forget about the Proxied object + * @param proxied + */ + public synchronized void forget(Proxied proxied) { + Integer id = objectIds.get(proxied); + if (id != null) { + objectIds.remove(proxied); + objectsById.remove(id); + invalidObjects.remove(proxied); + } + } + + /** * When the client creates an instance of a Proxied class addClientObject is used * to obtain an ID for it and add it to the lists of objects * @param proxied Modified: trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/UploadHandler.java =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/UploadHandler.java 2012-11-20 08:14:54 UTC (rev 21809) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/UploadHandler.java 2012-11-20 08:17:21 UTC (rev 21810) @@ -31,6 +31,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -47,10 +49,12 @@ import com.oreilly.servlet.multipart.ParamPart; import com.oreilly.servlet.multipart.Part; import com.zenesis.qx.remote.CommandId.CommandType; +import com.zenesis.qx.remote.FileApi.FileInfo; import com.zenesis.qx.remote.RequestHandler.ExceptionDetails; /** - * Handles file uploads and attaches them to a ProxySessionTracker + * Handles file uploads and attaches them to a ProxySessionTracker. NOTE:: The ProxySessionTracker.getBootstrapObject() + * MUST BE an instance of FileApiProvider * * @author "John Spackman <joh...@ze...>" */ @@ -106,7 +110,7 @@ response.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE, "Upload is too big: " + request.getContentLength() + " exceeds " + maxUploadSize); return; } - response.setContentType("text/html"); + response.setContentType("text/html; charset=utf-8"); // Accumulate POST parameters HashMap<String, Object> params = new HashMap<String, Object>(); @@ -133,20 +137,36 @@ tracker.getObjectMapper().writeValue(response.getWriter(), tracker.getQueue()); } - private void receiveOctetStream(HttpServletRequest request) throws IOException { + /** + * Receives an uploaded file from an application/octet-stream (ie Ajax upload) + * @param request + * @throws IOException + */ + protected void receiveOctetStream(HttpServletRequest request) throws IOException { String filename = request.getHeader("X-File-Name"); int pos = filename.lastIndexOf('/'); if (pos > -1) filename = filename.substring(pos + 1); File file = ProxyManager.getInstance().createTemporaryFile(filename); UploadingFile uploading = new UploadingFile("0", file, filename, Collections.EMPTY_MAP); - ArrayList<AppFile> files = new ArrayList<AppFile>(); - files.add(receiveFile(request.getInputStream(), uploading)); + ArrayList<FileApi.FileInfo> files = new ArrayList<FileApi.FileInfo>(); + file = receiveFile(request.getInputStream(), uploading); + FileApi api = ((FileApiProvider)tracker.getBootstrap()).getFileApi(); + FileApi.FileInfo info = api.getFileInfo(file); + if (info != null) + files.add(info); tracker.getQueue().queueCommand(CommandId.CommandType.FUNCTION_RETURN, null, null, files); } - private void receiveMultipart(HttpServletRequest request, HttpServletResponse response, HashMap<String, Object> params) throws IOException { - ArrayList<AppFile> files = new ArrayList<AppFile>(); + /** + * Receives uploaded file(s) from a multi-part request + * @param request + * @param response + * @param params + * @throws IOException + */ + protected void receiveMultipart(HttpServletRequest request, HttpServletResponse response, HashMap<String, Object> params) throws IOException { + ArrayList<FileApi.FileInfo> files = new ArrayList<FileApi.FileInfo>(); MultipartParser parser = new MultipartParser(request, Integer.MAX_VALUE, true, true, null); Part part; @@ -162,14 +182,15 @@ * This is a quick hack for getting server objects passed as parameters * */ - try { - if (value != null) { + if (value != null) { + try { int serverId = Integer.parseInt((String)value); if (serverId > -1) value = tracker.getProxied(serverId); + } catch(IllegalArgumentException e) { + if (value instanceof String) + value = URLDecoder.decode((String)value, "utf-8"); } - } catch(IllegalArgumentException e) { - // Nothing } params.put(name, value); @@ -188,17 +209,26 @@ log.info("Starting receive of " + file.getAbsolutePath()); UploadingFile uploading = new UploadingFile(uploadId, file, fileName, params); - AppFile appFile = receiveFile(filePart.getInputStream(), uploading); - files.add(appFile); + File receivedFile = receiveFile(filePart.getInputStream(), uploading); + FileInfo info = getFileApi().getFileInfo(receivedFile); + if (info != null) + files.add(info); } } tracker.getQueue().queueCommand(CommandId.CommandType.FUNCTION_RETURN, null, null, files); } - private AppFile receiveFile(InputStream is, UploadingFile uploading) throws IOException { - UploadReceiver receiver = (UploadReceiver)tracker.getBootstrap(); + /** + * Called to handle the uploading of the file and passing it to the FileApi + * @param is + * @param uploading + * @return + * @throws IOException + */ + protected File receiveFile(InputStream is, UploadingFile uploading) throws IOException { + FileApi api = getFileApi(); - receiver.beginUploadingFile(uploading); + api.beginUploadingFile(uploading); FileOutputStream os = null; File file = uploading.getFile(); @@ -215,12 +245,11 @@ os.close(); os = null; log.info("Receive complete"); - AppFile appFile = receiver.endUploadingFile(uploading, true); - return appFile; + return api.endUploadingFile(uploading, true); }catch(IOException e) { log.error("Failed to upload " + file.getName() + ": " + e.getMessage(), e); - receiver.endUploadingFile(uploading, false); + api.endUploadingFile(uploading, false); file.delete(); if (is != null) try { @@ -240,6 +269,15 @@ } /** + * Returns the FileApi instance to use + * @return + */ + protected FileApi getFileApi() { + FileApi api = ((FileApiProvider)tracker.getBootstrap()).getFileApi(); + return api; + } + + /** * Helper function which converts a query string into a map of * parameters * @param query @@ -258,6 +296,11 @@ name = name.substring(0, pos); } + try { + value = URLDecoder.decode(value, "utf-8"); + } catch (UnsupportedEncodingException e) { + log.error(e.getMessage(), e); + } params.put(name, value); } } Deleted: trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/UploadHandler.java.save =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/UploadHandler.java.save 2012-11-20 08:14:54 UTC (rev 21809) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/UploadHandler.java.save 2012-11-20 08:17:21 UTC (rev 21810) @@ -1,202 +0,0 @@ -/** - * ************************************************************************ - * - * server-objects - a contrib to the Qooxdoo project that makes server - * and client objects operate seamlessly; like Qooxdoo, server objects - * have properties, events, and methods all of which can be access from - * either server or client, regardless of where the original object was - * created. - * - * http://qooxdoo.org - * - * Copyright: - * 2010 Zenesis Limited, http://www.zenesis.com - * - * License: - * LGPL: http://www.gnu.org/licenses/lgpl.html - * EPL: http://www.eclipse.org/org/documents/epl-v10.php - * - * This software is provided under the same licensing terms as Qooxdoo, - * please see the LICENSE file in the Qooxdoo project's top-level directory - * for details. - * - * Authors: - * * John Spackman (joh...@ze...) - * - * ************************************************************************ - */ -package com.zenesis.qx.remote; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.StringTokenizer; -import java.util.Map.Entry; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.log4j.Logger; - -import com.oreilly.servlet.multipart.FilePart; -import com.oreilly.servlet.multipart.MultipartParser; -import com.oreilly.servlet.multipart.ParamPart; -import com.oreilly.servlet.multipart.Part; - -/** - * Handles file uploads and attaches them to a ProxySessionTracker - * - * @author "John Spackman <joh...@ze...>" - */ -public class UploadHandler { - - private static final Logger log = Logger.getLogger(UploadHandler.class); - - public static final int MAX_UPLOAD_SIZE = 1024 * 1024 * 50; // 50Mb - - private final ProxySessionTracker tracker; - private long maxUploadSize = MAX_UPLOAD_SIZE; - - /** - * @param tracker - */ - public UploadHandler(ProxySessionTracker tracker) { - super(); - this.tracker = tracker; - } - - public void processUpload(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - String contentType = request.getContentType(); - if (contentType == null || !contentType.startsWith("multipart/form-data")) { - log.error("Unsuitable content type: " + contentType); - response.setStatus(HttpServletResponse.SC_BAD_REQUEST, "Unsuitable content type " + contentType); - return; - } - - HashMap<String, Object> result = new HashMap<String, Object>(); - ArrayList<HashMap<String, Object>> files = new ArrayList<HashMap<String,Object>>(); - result.put("files", files); - - File file = null; - try { - // Create the parser and figure out our maximum upload size - MultipartParser parser = new MultipartParser(request, Integer.MAX_VALUE, true, true, null); - if (maxUploadSize > -1 && request.getContentLength() > maxUploadSize) { - log.error("Upload is too big: " + request.getContentLength() + " exceeds " + maxUploadSize); - response.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE, "Upload is too big: " + request.getContentLength() + " exceeds " + maxUploadSize); - return; - } - - HashMap<String, String> params = new HashMap<String, String>(); - - // Get query parameters - if (request.getQueryString() != null) - parseQuery(params, request.getQueryString()); - - // Read the parts in the upload - Part part; - while ((part = parser.readNextPart()) != null) { - String name = part.getName(); - - // It's a parameter part, add the parameters to the request object - if (part.isParam()) { - ParamPart paramPart = (ParamPart) part; - String value = paramPart.getStringValue(); - params.put(name, String.valueOf(value)); - - // Otherwise it's a file - } else if (part.isFile()) { - String uploadId = params.get("uploadId"); - - // Get the group and serial number - log.info("Received upload with id " + uploadId); - - FilePart filePart = (FilePart) part; - String fileName = filePart.getFileName(); - if (fileName == null) - fileName = "unnamed-upload"; - file = ProxyManager.getInstance().createTemporaryFile(fileName); - filePart.setRenamePolicy(null); - UploadingFile uploading = new UploadingFile(uploadId, file); - tracker.beginUploadingFile(uploading); - - log.info("Starting receive of " + file.getAbsolutePath()); - FileOutputStream os = null; - InputStream is = null; - try { - os = new FileOutputStream(file); - is = filePart.getInputStream(); - byte[] buffer = new byte[32 * 1024]; - int length; - while ((length = is.read(buffer)) > -1) { - uploading.addBytesUploaded(length); - os.write(buffer, 0, length); - } - is.close(); - is = null; - os.close(); - os = null; - log.info("Receive complete"); - tracker.endUploadingFile(uploading, true); - }catch(IOException e) { - tracker.endUploadingFile(uploading, false); - file.delete(); - if (is != null) - try { - is.close(); - } catch(IOException e2) { - - } - if (os != null) - try { - os.close(); - } catch(IOException e2) { - - } - throw e; - } - } - } - }catch(IOException e) { - String str; - if (file != null) - str = "Failed to upload " + file.getName() + ": " + e.getMessage(); - else - str = "Error during upload: " + e.getMessage(); - log.error(str, e); - result.put("status", "aborted"); - result.put("cause", str); - } - result.put("status", "complete"); - String str = tracker.toJSON(result); - response.getWriter().write(str); - response.setStatus(HttpServletResponse.SC_OK); - } - - /** - * Helper function which converts a query string into a map of - * parameters - * @param query - * @return - */ - private static void parseQuery(HashMap<String, String> params, String query) { - if (query == null || query.length() == 0) - return; - StringTokenizer st = new StringTokenizer(query, "&"); - while (st.hasMoreTokens()) { - String name = st.nextToken(); - String value = ""; - int pos = name.indexOf('='); - if (pos > -1) { - value = name.substring(pos + 1); - name = name.substring(0, pos); - } - - params.put(name, value); - } - } -} Deleted: trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/UploadReceiver.java =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/UploadReceiver.java 2012-11-20 08:14:54 UTC (rev 21809) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/UploadReceiver.java 2012-11-20 08:17:21 UTC (rev 21810) @@ -1,47 +0,0 @@ -package com.zenesis.qx.remote; - -import java.io.IOException; - -import com.zenesis.qx.remote.annotations.DoNotProxy; - -/** - * This interface must be implemented by Bootstrap objects which can be uploaded to - * by the UploadHandler - * - * @author "John Spackman <joh...@ze...>" - */ -public interface UploadReceiver extends Proxied { - - /** - * Called when a file starts uploading; the file must be kept - * until endUploadingFile is called. - * @param upfile - */ - @DoNotProxy - public void beginUploadingFile(UploadingFile upfile) throws IOException; - - /** - * Called when a file upload has completed; if the file failed to upload, the - * UploadingFile will no longer be accessible from getUploadingFile - * @param upfile - * @param success - * @return if non-null, the AppFile object to return to the client - */ - @DoNotProxy - public AppFile endUploadingFile(UploadingFile upfile, boolean success) throws IOException; - - /** - * Called to get the details of a file which is being uploaded; if the file has - * failed to upload then this method will return null. - * @param uploadId - * @return the file with a given id, or null if it has finsihed uploading - */ - public UploadingFile getUploadingFile(String uploadId); - - /** - * Called to remove an instance of UploadingFile from the list, i.e. when the client - * no longer needs to report progress and the file has been moved somewhere. - * @param uploadId - */ - public void clearUploadedFile(String uploadId); -} Modified: trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/UploadingFile.java =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/UploadingFile.java 2012-11-20 08:14:54 UTC (rev 21809) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/java/com/zenesis/qx/remote/UploadingFile.java 2012-11-20 08:17:21 UTC (rev 21810) @@ -18,7 +18,6 @@ * @author "John Spackman <joh...@ze...>" */ @Properties({ - @Property(value="appFile", readOnly=Remote.Toggle.TRUE), @Property(value="bytesUploaded", onDemand=true), @Property("uploadId") }) @@ -37,10 +36,6 @@ // The name on the users PC private String originalName; - // After the upload is complete, the file can be wrapped by AppFile so that it can be - // given to the client - private AppFile appFile; - // Number of bytes to go private long bytesUploaded; @@ -65,20 +60,6 @@ } /** - * @return the appFile - */ - public AppFile getAppFile() { - return appFile; - } - - /** - * @param appFile the appFile to set - */ - public void setAppFile(AppFile appFile) { - this.appFile = ProxyManager.changeProperty(this, "appFile", appFile, this.appFile); - } - - /** * @return the uploadId */ public String getUploadId() { Modified: trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/test/com/zenesis/qx/remote/explorer/FileExplorer.java =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/test/com/zenesis/qx/remote/explorer/FileExplorer.java 2012-11-20 08:14:54 UTC (rev 21809) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/server/src/test/com/zenesis/qx/remote/explorer/FileExplorer.java 2012-11-20 08:17:21 UTC (rev 21810) @@ -27,8 +27,8 @@ */ package com.zenesis.qx.remote.explorer; -import com.zenesis.qx.remote.AppFile; import com.zenesis.qx.remote.BasicBootstrap; +import com.zenesis.qx.remote.FileApi; /** * Bootstrap class for FileExplorer demo @@ -38,10 +38,7 @@ public class FileExplorer extends BasicBootstrap { public FileExplorer() { - super(); - AppFile root = new AppFile(FileExplorerServlet.getInstance().getRoot(), "/public/all-files"); - setAppFilesRoot(root); - setUploadFolder(root); + super(new FileApi(FileExplorerServlet.getInstance().getRoot(), "/public/all-files")); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <spa...@us...> - 2012-11-20 08:15:03
|
Revision: 21809 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21809&view=rev Author: spackers Date: 2012-11-20 08:14:54 +0000 (Tue, 20 Nov 2012) Log Message: ----------- replaces support for AppFile, see FileApi and contrib docs Modified Paths: -------------- trunk/qooxdoo-contrib/ServerObjects/trunk/client/qso-lib/source/class/com/zenesis/qx/remote/Proxy.js trunk/qooxdoo-contrib/ServerObjects/trunk/client/qso-lib/source/class/com/zenesis/qx/remote/ProxyManager.js Modified: trunk/qooxdoo-contrib/ServerObjects/trunk/client/qso-lib/source/class/com/zenesis/qx/remote/Proxy.js =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/client/qso-lib/source/class/com/zenesis/qx/remote/Proxy.js 2012-11-20 08:13:17 UTC (rev 21808) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/client/qso-lib/source/class/com/zenesis/qx/remote/Proxy.js 2012-11-20 08:14:54 UTC (rev 21809) @@ -153,9 +153,9 @@ __storePropertyOnDemand: function(propDef, value) { var oldValue; if (this.$$proxyUser && (oldValue = this.$$proxyUser[propDef.name])) { - if (propDef.array = "wrap") { + if (propDef.array = "wrap" && propDef.changeListenerId) { oldValue.removeListenerById(propDef.changeListenerId); - delete propDef.changeListenerId; + propDef.changeListenerId = null; } delete this.$$proxyUser[propDef.name]; } Modified: trunk/qooxdoo-contrib/ServerObjects/trunk/client/qso-lib/source/class/com/zenesis/qx/remote/ProxyManager.js =================================================================== --- trunk/qooxdoo-contrib/ServerObjects/trunk/client/qso-lib/source/class/com/zenesis/qx/remote/ProxyManager.js 2012-11-20 08:13:17 UTC (rev 21808) +++ trunk/qooxdoo-contrib/ServerObjects/trunk/client/qso-lib/source/class/com/zenesis/qx/remote/ProxyManager.js 2012-11-20 08:14:54 UTC (rev 21809) @@ -183,7 +183,7 @@ var statusCode = evt.getStatusCode(); if (statusCode == 200) { - txt = qx.lang.String.trim(txt); + txt = txt.trim(); try { //this.debug("received: txt=" + txt); if (!txt.length) @@ -205,7 +205,7 @@ * Called to handle the response from an upload */ uploadResponse: function(txt) { - txt = qx.lang.String.trim(txt); + txt = txt.trim(); try { //this.debug("received: txt=" + txt); if (!txt.length) @@ -800,7 +800,7 @@ else if (def.array && def.array == "wrap") { var current = serverObject["get" + upname](); if (value != null) - value = qx.lang.Array.toArray(value); + value = qx.lang.Array.cast(value, Array); if (current == null) { var arr = new qx.data.Array(); arr.append(value); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <spa...@us...> - 2012-11-20 08:13:28
|
Revision: 21808 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21808&view=rev Author: spackers Date: 2012-11-20 08:13:17 +0000 (Tue, 20 Nov 2012) Log Message: ----------- The appfile branch is the last release of ServerObject to support AppFile as a mechanism for access files on the server; please see FileApi and the contrib documentation for upgrade instructions Added Paths: ----------- trunk/qooxdoo-contrib/ServerObjects/branches/appfile/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <spa...@us...> - 2012-11-19 16:38:18
|
Revision: 21807 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21807&view=rev Author: spackers Date: 2012-11-19 16:38:08 +0000 (Mon, 19 Nov 2012) Log Message: ----------- fixes for lint with 2.1 Modified Paths: -------------- trunk/qooxdoo-contrib/UploadMgr/trunk/Manifest.json trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/Manifest.json trunk/qooxdoo-contrib/UploadMgr/trunk/source/class/com/zenesis/qx/upload/XhrHandler.js Modified: trunk/qooxdoo-contrib/UploadMgr/trunk/Manifest.json =================================================================== --- trunk/qooxdoo-contrib/UploadMgr/trunk/Manifest.json 2012-11-19 15:51:55 UTC (rev 21806) +++ trunk/qooxdoo-contrib/UploadMgr/trunk/Manifest.json 2012-11-19 16:38:08 UTC (rev 21807) @@ -18,7 +18,7 @@ ], "version" : "trunk", - "qooxdoo-versions": [ "1.5", "1.6", "1.6.1", "2.0" ] + "qooxdoo-versions": [ "1.5", "1.6", "1.6.1", "2.0", "2.1" ] }, "provides" : Modified: trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/Manifest.json =================================================================== --- trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/Manifest.json 2012-11-19 15:51:55 UTC (rev 21806) +++ trunk/qooxdoo-contrib/UploadMgr/trunk/demo/default/Manifest.json 2012-11-19 16:38:08 UTC (rev 21807) @@ -18,7 +18,7 @@ ], "version" : "trunk", - "qooxdoo-versions": ["1.6", "1.6.1", "2.0" ] + "qooxdoo-versions": ["1.6", "1.6.1", "2.0", "2.1" ] }, "provides" : Modified: trunk/qooxdoo-contrib/UploadMgr/trunk/source/class/com/zenesis/qx/upload/XhrHandler.js =================================================================== --- trunk/qooxdoo-contrib/UploadMgr/trunk/source/class/com/zenesis/qx/upload/XhrHandler.js 2012-11-19 15:51:55 UTC (rev 21806) +++ trunk/qooxdoo-contrib/UploadMgr/trunk/source/class/com/zenesis/qx/upload/XhrHandler.js 2012-11-19 16:38:08 UTC (rev 21807) @@ -25,10 +25,10 @@ * John Spackman (joh...@ze...) ************************************************************************/ -/* -#ignore(File) -#ignore(FileReader) -#ignore(FormData) +/** + * @ignore(File) + * @ignore(FileReader) + * @ignore(FormData) */ /** * Implementation of AbstractHandler that uses XMLHttpRequest; this is based on work This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sc...@us...> - 2012-11-19 15:52:01
|
Revision: 21806 http://qooxdoo-contrib.svn.sourceforge.net/qooxdoo-contrib/?rev=21806&view=rev Author: scro34 Date: 2012-11-19 15:51:55 +0000 (Mon, 19 Nov 2012) Log Message: ----------- Demo application (trunk) runs under qx 2.1 now Modified Paths: -------------- trunk/qooxdoo-contrib/SilverBlueTheme/trunk/Manifest.json trunk/qooxdoo-contrib/SilverBlueTheme/trunk/config.json trunk/qooxdoo-contrib/SilverBlueTheme/trunk/demo/default/Manifest.json trunk/qooxdoo-contrib/SilverBlueTheme/trunk/demo/default/config.json trunk/qooxdoo-contrib/SilverBlueTheme/trunk/source/class/silverbluetheme/theme/Appearance.js trunk/qooxdoo-contrib/SilverBlueTheme/trunk/source/class/silverbluetheme/theme/Decoration.js Modified: trunk/qooxdoo-contrib/SilverBlueTheme/trunk/Manifest.json =================================================================== --- trunk/qooxdoo-contrib/SilverBlueTheme/trunk/Manifest.json 2012-11-19 15:50:56 UTC (rev 21805) +++ trunk/qooxdoo-contrib/SilverBlueTheme/trunk/Manifest.json 2012-11-19 15:51:55 UTC (rev 21806) @@ -18,7 +18,7 @@ ], "version" : "trunk", - "qooxdoo-versions": ["2.0"] + "qooxdoo-versions": ["2.0", "2.1"] }, "provides" : Modified: trunk/qooxdoo-contrib/SilverBlueTheme/trunk/config.json =================================================================== --- trunk/qooxdoo-contrib/SilverBlueTheme/trunk/config.json 2012-11-19 15:50:56 UTC (rev 21805) +++ trunk/qooxdoo-contrib/SilverBlueTheme/trunk/config.json 2012-11-19 15:51:55 UTC (rev 21806) @@ -29,7 +29,7 @@ { "APPLICATION" : "silverbluetheme", "APPLICATION_MAIN_CLASS" : "${APPLICATION}.demo.Demo", - "QOOXDOO_PATH" : "../../qooxdoo/2.0.1", + "QOOXDOO_PATH" : "../../qooxdoo/2.1", "QXTHEME" : "silverbluetheme.theme.Theme", "API_EXCLUDE" : ["qx.test.*", "silverbluetheme.demo.*", "${APPLICATION}.theme.*", "${APPLICATION}.test.*"], "LOCALES" : [ "en" ], Modified: trunk/qooxdoo-contrib/SilverBlueTheme/trunk/demo/default/Manifest.json =================================================================== --- trunk/qooxdoo-contrib/SilverBlueTheme/trunk/demo/default/Manifest.json 2012-11-19 15:50:56 UTC (rev 21805) +++ trunk/qooxdoo-contrib/SilverBlueTheme/trunk/demo/default/Manifest.json 2012-11-19 15:51:55 UTC (rev 21806) @@ -18,7 +18,7 @@ ], "version" : "trunk", - "qooxdoo-versions": ["2.0"] + "qooxdoo-versions": ["2.0", "2.1"] }, "provides" : Modified: trunk/qooxdoo-contrib/SilverBlueTheme/trunk/demo/default/config.json =================================================================== --- trunk/qooxdoo-contrib/SilverBlueTheme/trunk/demo/default/config.json 2012-11-19 15:50:56 UTC (rev 21805) +++ trunk/qooxdoo-contrib/SilverBlueTheme/trunk/demo/default/config.json 2012-11-19 15:51:55 UTC (rev 21806) @@ -33,7 +33,7 @@ "let" : { "APPLICATION" : "silverbluetheme.demo", - "QOOXDOO_PATH" : "../../../../qooxdoo/2.0.1", + "QOOXDOO_PATH" : "../../../../qooxdoo/2.1", "QXTHEME" : "silverbluetheme.SilverBlueTheme", "API_EXCLUDE" : ["qx.test.*", "${APPLICATION}.theme.*", "${APPLICATION}.test.*"], "LOCALES" : [ "en" ], Modified: trunk/qooxdoo-contrib/SilverBlueTheme/trunk/source/class/silverbluetheme/theme/Appearance.js =================================================================== --- trunk/qooxdoo-contrib/SilverBlueTheme/trunk/source/class/silverbluetheme/theme/Appearance.js 2012-11-19 15:50:56 UTC (rev 21805) +++ trunk/qooxdoo-contrib/SilverBlueTheme/trunk/source/class/silverbluetheme/theme/Appearance.js 2012-11-19 15:51:55 UTC (rev 21806) @@ -46,6 +46,15 @@ }, "app-header-label": "label", + + "app-splitpane" : { + alias : "splitpane", + style : function(states) { + return { + padding: 0 + } + } + }, /* --------------------------------------------------------------------------- Modified: trunk/qooxdoo-contrib/SilverBlueTheme/trunk/source/class/silverbluetheme/theme/Decoration.js =================================================================== --- trunk/qooxdoo-contrib/SilverBlueTheme/trunk/source/class/silverbluetheme/theme/Decoration.js 2012-11-19 15:50:56 UTC (rev 21805) +++ trunk/qooxdoo-contrib/SilverBlueTheme/trunk/source/class/silverbluetheme/theme/Decoration.js 2012-11-19 15:51:55 UTC (rev 21806) @@ -588,7 +588,8 @@ style: { baseImage: "decoration/shadow/shadow.png", - insets: [0, 21, 8, -7] + // insets: [0, 21, 8, -7] + insets: [4, 8, 8, 8] } }, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |