Moved package webui to web.ui.
authorMarco Zanon <info@marcozanon.com>
Tue, 24 Jan 2012 17:24:04 +0000 (17:24 +0000)
committerMarco Zanon <info@marcozanon.com>
Tue, 24 Jan 2012 17:24:04 +0000 (17:24 +0000)
132 files changed:
src/java/com/marcozanon/macaco/web/ui/MApplicationServletWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MBrowserPageRequestPreprocessingWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MDisplayWidgetNotFoundWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MDownloaderNotFoundWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MInvalidRemoteIpAddressWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MInvalidRequestWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MInvalidResourceWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MInvalidSecurityIdWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MMessagingWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MNoBrowserPageWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MNoCellContentWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MNoLogFilterWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MNoProcessableMessageWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MNoViewContentWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MNoViewWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MNoWidgetIdWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MNullPropertyWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MResponseWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MSecurityWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MSetupWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MUnexpectedMessageWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MUniqueWidgetIdNotAvailableWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MValidationWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MViewNotUnloadableWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MViewThreadStoppingWebRuntimeException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebApplicationContext.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebApplicationServlet.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebBorder.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebBreadcrumbs.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebBrowserPage.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebCellWidget.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebCheckBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebColor.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebComboBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebDateBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebDatetimeBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebDirectWidget.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebDisplayWidget.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebDownloader.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebExtendedTextBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebFont.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebGridLayout.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebGridLayoutCell.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebImage.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebImageButton.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebLabel.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebMeasure.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebMessage.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebNumberBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebPasswordBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebRuntimeException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebSimpleTextBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebString.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebTable.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebTableCell.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebTextBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebTimeBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebUploader.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebVerticalMenu.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebVerticalMenuItem.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebView.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebWidget.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebWysiwygBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MWebXhtmlLabel.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/web/ui/MXhtmlUnsafeStringWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/webui/MApplicationServletWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MBrowserPageRequestPreprocessingWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MDisplayWidgetNotFoundWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MDownloaderNotFoundWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MInvalidRemoteIpAddressWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MInvalidRequestWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MInvalidResourceWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MInvalidSecurityIdWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MMessagingWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MNoBrowserPageWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MNoCellContentWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MNoLogFilterWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MNoProcessableMessageWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MNoViewContentWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MNoViewWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MNoWidgetIdWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MNullPropertyWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MResponseWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MSecurityWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MSetupWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MUnexpectedMessageWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MUniqueWidgetIdNotAvailableWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MValidationWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MViewNotUnloadableWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MViewThreadStoppingWebRuntimeException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebApplicationContext.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebApplicationServlet.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebBorder.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebBreadcrumbs.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebBrowserPage.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebCellWidget.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebCheckBox.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebColor.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebComboBox.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebDateBox.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebDatetimeBox.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebDirectWidget.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebDisplayWidget.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebDownloader.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebExtendedTextBox.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebFont.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebGridLayout.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebGridLayoutCell.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebImage.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebImageButton.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebLabel.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebMeasure.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebMessage.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebNumberBox.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebPasswordBox.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebRuntimeException.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebSimpleTextBox.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebString.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebTable.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebTableCell.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebTextBox.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebTimeBox.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebUploader.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebVerticalMenu.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebVerticalMenuItem.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebView.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebWidget.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebWysiwygBox.java [deleted file]
src/java/com/marcozanon/macaco/webui/MWebXhtmlLabel.java [deleted file]
src/java/com/marcozanon/macaco/webui/MXhtmlUnsafeStringWebException.java [deleted file]

diff --git a/src/java/com/marcozanon/macaco/web/ui/MApplicationServletWebException.java b/src/java/com/marcozanon/macaco/web/ui/MApplicationServletWebException.java
new file mode 100644 (file)
index 0000000..86ae8f6
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MApplicationServletWebException extends MWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MApplicationServletWebException() {
+        super();
+    }
+
+    public MApplicationServletWebException(String message) {
+        super(message);
+    }
+
+    public MApplicationServletWebException(Throwable error) {
+        super(error);
+    }
+
+    public MApplicationServletWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MBrowserPageRequestPreprocessingWebException.java b/src/java/com/marcozanon/macaco/web/ui/MBrowserPageRequestPreprocessingWebException.java
new file mode 100644 (file)
index 0000000..707a9e9
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MBrowserPageRequestPreprocessingWebException extends MWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MBrowserPageRequestPreprocessingWebException() {
+        super();
+    }
+
+    public MBrowserPageRequestPreprocessingWebException(String message) {
+        super(message);
+    }
+
+    public MBrowserPageRequestPreprocessingWebException(Throwable error) {
+        super(error);
+    }
+
+    public MBrowserPageRequestPreprocessingWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MDisplayWidgetNotFoundWebException.java b/src/java/com/marcozanon/macaco/web/ui/MDisplayWidgetNotFoundWebException.java
new file mode 100644 (file)
index 0000000..84cd8ea
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MDisplayWidgetNotFoundWebException extends MSecurityWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MDisplayWidgetNotFoundWebException() {
+        super();
+    }
+
+    public MDisplayWidgetNotFoundWebException(String message) {
+        super(message);
+    }
+
+    public MDisplayWidgetNotFoundWebException(Throwable error) {
+        super(error);
+    }
+
+    public MDisplayWidgetNotFoundWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MDownloaderNotFoundWebException.java b/src/java/com/marcozanon/macaco/web/ui/MDownloaderNotFoundWebException.java
new file mode 100644 (file)
index 0000000..f0a462b
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MDownloaderNotFoundWebException extends MSecurityWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MDownloaderNotFoundWebException() {
+        super();
+    }
+
+    public MDownloaderNotFoundWebException(String message) {
+        super(message);
+    }
+
+    public MDownloaderNotFoundWebException(Throwable error) {
+        super(error);
+    }
+
+    public MDownloaderNotFoundWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MInvalidRemoteIpAddressWebException.java b/src/java/com/marcozanon/macaco/web/ui/MInvalidRemoteIpAddressWebException.java
new file mode 100644 (file)
index 0000000..5bb0f3f
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MInvalidRemoteIpAddressWebException extends MSecurityWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MInvalidRemoteIpAddressWebException() {
+        super();
+    }
+
+    public MInvalidRemoteIpAddressWebException(String message) {
+        super(message);
+    }
+
+    public MInvalidRemoteIpAddressWebException(Throwable error) {
+        super(error);
+    }
+
+    public MInvalidRemoteIpAddressWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MInvalidRequestWebException.java b/src/java/com/marcozanon/macaco/web/ui/MInvalidRequestWebException.java
new file mode 100644 (file)
index 0000000..4f06cb8
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MInvalidRequestWebException extends MSecurityWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MInvalidRequestWebException() {
+        super();
+    }
+
+    public MInvalidRequestWebException(String message) {
+        super(message);
+    }
+
+    public MInvalidRequestWebException(Throwable error) {
+        super(error);
+    }
+
+    public MInvalidRequestWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MInvalidResourceWebException.java b/src/java/com/marcozanon/macaco/web/ui/MInvalidResourceWebException.java
new file mode 100644 (file)
index 0000000..0e70c2c
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MInvalidResourceWebException extends MSecurityWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MInvalidResourceWebException() {
+        super();
+    }
+
+    public MInvalidResourceWebException(String message) {
+        super(message);
+    }
+
+    public MInvalidResourceWebException(Throwable error) {
+        super(error);
+    }
+
+    public MInvalidResourceWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MInvalidSecurityIdWebException.java b/src/java/com/marcozanon/macaco/web/ui/MInvalidSecurityIdWebException.java
new file mode 100644 (file)
index 0000000..1e1ec25
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MInvalidSecurityIdWebException extends MSecurityWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MInvalidSecurityIdWebException() {
+        super();
+    }
+
+    public MInvalidSecurityIdWebException(String message) {
+        super(message);
+    }
+
+    public MInvalidSecurityIdWebException(Throwable error) {
+        super(error);
+    }
+
+    public MInvalidSecurityIdWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MMessagingWebException.java b/src/java/com/marcozanon/macaco/web/ui/MMessagingWebException.java
new file mode 100644 (file)
index 0000000..097a3c4
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MMessagingWebException extends MWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MMessagingWebException() {
+        super();
+    }
+
+    public MMessagingWebException(String message) {
+        super(message);
+    }
+
+    public MMessagingWebException(Throwable error) {
+        super(error);
+    }
+
+    public MMessagingWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MNoBrowserPageWebException.java b/src/java/com/marcozanon/macaco/web/ui/MNoBrowserPageWebException.java
new file mode 100644 (file)
index 0000000..f0e47d2
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MNoBrowserPageWebException extends MSetupWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MNoBrowserPageWebException() {
+        super();
+    }
+
+    public MNoBrowserPageWebException(String message) {
+        super(message);
+    }
+
+    public MNoBrowserPageWebException(Throwable error) {
+        super(error);
+    }
+
+    public MNoBrowserPageWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MNoCellContentWebException.java b/src/java/com/marcozanon/macaco/web/ui/MNoCellContentWebException.java
new file mode 100644 (file)
index 0000000..e3bd444
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MNoCellContentWebException extends MSetupWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MNoCellContentWebException() {
+        super();
+    }
+
+    public MNoCellContentWebException(String message) {
+        super(message);
+    }
+
+    public MNoCellContentWebException(Throwable error) {
+        super(error);
+    }
+
+    public MNoCellContentWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MNoLogFilterWebException.java b/src/java/com/marcozanon/macaco/web/ui/MNoLogFilterWebException.java
new file mode 100644 (file)
index 0000000..e424d3e
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MNoLogFilterWebException extends MSetupWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MNoLogFilterWebException() {
+        super();
+    }
+
+    public MNoLogFilterWebException(String message) {
+        super(message);
+    }
+
+    public MNoLogFilterWebException(Throwable error) {
+        super(error);
+    }
+
+    public MNoLogFilterWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MNoProcessableMessageWebException.java b/src/java/com/marcozanon/macaco/web/ui/MNoProcessableMessageWebException.java
new file mode 100644 (file)
index 0000000..5146729
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MNoProcessableMessageWebException extends MWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MNoProcessableMessageWebException() {
+        super();
+    }
+
+    public MNoProcessableMessageWebException(String message) {
+        super(message);
+    }
+
+    public MNoProcessableMessageWebException(Throwable error) {
+        super(error);
+    }
+
+    public MNoProcessableMessageWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MNoViewContentWebException.java b/src/java/com/marcozanon/macaco/web/ui/MNoViewContentWebException.java
new file mode 100644 (file)
index 0000000..3690edd
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MNoViewContentWebException extends MSetupWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MNoViewContentWebException() {
+        super();
+    }
+
+    public MNoViewContentWebException(String message) {
+        super(message);
+    }
+
+    public MNoViewContentWebException(Throwable error) {
+        super(error);
+    }
+
+    public MNoViewContentWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MNoViewWebException.java b/src/java/com/marcozanon/macaco/web/ui/MNoViewWebException.java
new file mode 100644 (file)
index 0000000..3aff282
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MNoViewWebException extends MSetupWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MNoViewWebException() {
+        super();
+    }
+
+    public MNoViewWebException(String message) {
+        super(message);
+    }
+
+    public MNoViewWebException(Throwable error) {
+        super(error);
+    }
+
+    public MNoViewWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MNoWidgetIdWebException.java b/src/java/com/marcozanon/macaco/web/ui/MNoWidgetIdWebException.java
new file mode 100644 (file)
index 0000000..3401615
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MNoWidgetIdWebException extends MSetupWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MNoWidgetIdWebException() {
+        super();
+    }
+
+    public MNoWidgetIdWebException(String message) {
+        super(message);
+    }
+
+    public MNoWidgetIdWebException(Throwable error) {
+        super(error);
+    }
+
+    public MNoWidgetIdWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MNullPropertyWebException.java b/src/java/com/marcozanon/macaco/web/ui/MNullPropertyWebException.java
new file mode 100644 (file)
index 0000000..041a14a
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MNullPropertyWebException extends MWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MNullPropertyWebException() {
+        super();
+    }
+
+    public MNullPropertyWebException(String message) {
+        super(message);
+    }
+
+    public MNullPropertyWebException(Throwable error) {
+        super(error);
+    }
+
+    public MNullPropertyWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MResponseWebException.java b/src/java/com/marcozanon/macaco/web/ui/MResponseWebException.java
new file mode 100644 (file)
index 0000000..7587320
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MResponseWebException extends MWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MResponseWebException() {
+        super();
+    }
+
+    public MResponseWebException(String message) {
+        super(message);
+    }
+
+    public MResponseWebException(Throwable error) {
+        super(error);
+    }
+
+    public MResponseWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MSecurityWebException.java b/src/java/com/marcozanon/macaco/web/ui/MSecurityWebException.java
new file mode 100644 (file)
index 0000000..6f89d12
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public abstract class MSecurityWebException extends MWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MSecurityWebException() {
+        super();
+    }
+
+    public MSecurityWebException(String message) {
+        super(message);
+    }
+
+    public MSecurityWebException(Throwable error) {
+        super(error);
+    }
+
+    public MSecurityWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MSetupWebException.java b/src/java/com/marcozanon/macaco/web/ui/MSetupWebException.java
new file mode 100644 (file)
index 0000000..53f7cdb
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public abstract class MSetupWebException extends MWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MSetupWebException() {
+        super();
+    }
+
+    public MSetupWebException(String message) {
+        super(message);
+    }
+
+    public MSetupWebException(Throwable error) {
+        super(error);
+    }
+
+    public MSetupWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MUnexpectedMessageWebException.java b/src/java/com/marcozanon/macaco/web/ui/MUnexpectedMessageWebException.java
new file mode 100644 (file)
index 0000000..636c84d
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MUnexpectedMessageWebException extends MSecurityWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MUnexpectedMessageWebException() {
+        super();
+    }
+
+    public MUnexpectedMessageWebException(String message) {
+        super(message);
+    }
+
+    public MUnexpectedMessageWebException(Throwable error) {
+        super(error);
+    }
+
+    public MUnexpectedMessageWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MUniqueWidgetIdNotAvailableWebException.java b/src/java/com/marcozanon/macaco/web/ui/MUniqueWidgetIdNotAvailableWebException.java
new file mode 100644 (file)
index 0000000..75d72c6
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MUniqueWidgetIdNotAvailableWebException extends MSetupWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MUniqueWidgetIdNotAvailableWebException() {
+        super();
+    }
+
+    public MUniqueWidgetIdNotAvailableWebException(String message) {
+        super(message);
+    }
+
+    public MUniqueWidgetIdNotAvailableWebException(Throwable error) {
+        super(error);
+    }
+
+    public MUniqueWidgetIdNotAvailableWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MValidationWebException.java b/src/java/com/marcozanon/macaco/web/ui/MValidationWebException.java
new file mode 100644 (file)
index 0000000..cbccd1e
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MValidationWebException extends MWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MValidationWebException() {
+        super();
+    }
+
+    public MValidationWebException(String message) {
+        super(message);
+    }
+
+    public MValidationWebException(Throwable error) {
+        super(error);
+    }
+
+    public MValidationWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MViewNotUnloadableWebException.java b/src/java/com/marcozanon/macaco/web/ui/MViewNotUnloadableWebException.java
new file mode 100644 (file)
index 0000000..45099ed
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MViewNotUnloadableWebException extends MSetupWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MViewNotUnloadableWebException() {
+        super();
+    }
+
+    public MViewNotUnloadableWebException(String message) {
+        super(message);
+    }
+
+    public MViewNotUnloadableWebException(Throwable error) {
+        super(error);
+    }
+
+    public MViewNotUnloadableWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MViewThreadStoppingWebRuntimeException.java b/src/java/com/marcozanon/macaco/web/ui/MViewThreadStoppingWebRuntimeException.java
new file mode 100644 (file)
index 0000000..cb6873a
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MViewThreadStoppingWebRuntimeException extends MWebRuntimeException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MViewThreadStoppingWebRuntimeException() {
+        super();
+    }
+
+    public MViewThreadStoppingWebRuntimeException(String message) {
+        super(message);
+    }
+
+    public MViewThreadStoppingWebRuntimeException(Throwable error) {
+        super(error);
+    }
+
+    public MViewThreadStoppingWebRuntimeException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebApplicationContext.java b/src/java/com/marcozanon/macaco/web/ui/MWebApplicationContext.java
new file mode 100644 (file)
index 0000000..553d3c4
--- /dev/null
@@ -0,0 +1,266 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.MInformation;
+import com.marcozanon.macaco.MObject;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.net.MalformedURLException;
+import java.net.URL;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+public abstract class MWebApplicationContext extends MObject {
+
+    protected MWebApplicationServlet applicationServlet = null;
+    protected HttpServletRequest request = null;
+    protected HttpServletResponse response = null;
+
+    protected String responseContentType = null;
+    protected byte[] responseContent = new byte[0];
+
+    protected boolean roamingMode = false;
+
+    /* */
+
+    public MWebApplicationContext(MWebApplicationServlet applicationServlet, HttpServletRequest request, HttpServletResponse response) {
+        super();
+        //
+        if (null == applicationServlet) {
+            throw new IllegalArgumentException("Invalid 'applicationServlet': null.");
+        }
+        //
+        this.applicationServlet = applicationServlet;
+        this.refreshReferences(request, response);
+    }
+
+    protected void refreshReferences(HttpServletRequest request, HttpServletResponse response) {
+        if (null == request) {
+            throw new IllegalArgumentException("Invalid 'request': null.");
+        }
+        if (null == response) {
+            throw new IllegalArgumentException("Invalid 'response': null.");
+        }
+        //
+        this.request = request;
+        this.response = response;
+    }
+
+    /* Application servlet */
+
+    public MWebApplicationServlet getApplicationServletReference() {
+        return this.applicationServlet;
+    }
+
+    /* Request */
+
+    public HttpServletRequest getRequestReference() {
+        return this.request;
+    }
+
+    /* Response */
+
+    public HttpServletResponse getResponseReference() {
+        return this.response;
+    }
+
+    /* Session */
+
+    public HttpSession getSessionReference() {
+        return this.getRequestReference().getSession(false);
+    }
+
+    /* Response content */
+
+    protected void setResponseContentType(String responseContentType) {
+        if ((null == responseContentType) || ("".equals(responseContentType))) {
+            throw new IllegalArgumentException("Invalid 'responseContentType': null or empty.");
+        }
+        //
+        this.responseContentType = responseContentType;
+    }
+
+    protected String getResponseContentType() {
+        return this.responseContentType;
+    }
+
+    protected void clearResponseContent() {
+        this.responseContentType = null;
+        this.responseContent = new byte[0];
+    }
+
+    protected void addPlainTextResponseContent(String responseContent) throws MResponseWebException {
+        if ((null == responseContent) || ("".equals(responseContent))) {
+            throw new IllegalArgumentException("Invalid 'responseContent': null or empty.");
+        }
+        //
+        try {
+            this.addPlainTextResponseContent(responseContent.getBytes(MInformation.TEXT_ENCODING));
+        }
+        catch (UnsupportedEncodingException exception) { // cannot happen
+        }
+    }
+
+    protected void addPlainTextResponseContent(byte[] responseContent) throws MResponseWebException {
+        String currentResponseContentType = this.getResponseContentType();
+        if ((null != currentResponseContentType) && (!MInformation.HttpContentType.PLAIN.toString().equals(currentResponseContentType))) {
+            throw new MResponseWebException(String.format("Could not add plain text response content: content type already set to: %s.", currentResponseContentType));
+        }
+        //
+        this.setResponseContentType(MInformation.HttpContentType.PLAIN.toString());
+        this.addResponseContent(responseContent);
+    }
+
+    protected void setXhtmlResponseContent(String responseContent) throws MResponseWebException {
+        if ((null == responseContent) || ("".equals(responseContent))) {
+            throw new IllegalArgumentException("Invalid 'responseContent': null or empty.");
+        }
+        //
+        try {
+            this.setXhtmlResponseContent(responseContent.getBytes(MInformation.TEXT_ENCODING));
+        }
+        catch (UnsupportedEncodingException exception) { // cannot happen
+        }
+    }
+
+    protected void setXhtmlResponseContent(byte[] responseContent) throws MResponseWebException {
+        String currentResponseContentType = this.getResponseContentType();
+        if ((null != currentResponseContentType) && (!MInformation.HttpContentType.XHTML.toString().equals(currentResponseContentType))) { // XHtml can only override plain text
+            throw new MResponseWebException(String.format("Could not set Xhtml response content: content type already set to: %s.", currentResponseContentType));
+        }
+        //
+        this.clearResponseContent();
+        this.setResponseContentType(MInformation.HttpContentType.XHTML.toString());
+        this.addResponseContent(responseContent);
+    }
+
+    protected void setRawResponseContent(byte[] responseContent, String responseContentType) throws MResponseWebException {
+        String currentResponseContentType = this.getResponseContentType();
+        if (null != currentResponseContentType) {
+            throw new MResponseWebException(String.format("Could not set raw response content: content type already set to: %s.", currentResponseContentType));
+        }
+        //
+        this.setResponseContentType(responseContentType);
+        this.addResponseContent(responseContent);
+    }
+
+    protected void addResponseContent(byte[] responseContent) {
+        if (null == responseContent) {
+            throw new IllegalArgumentException("Invalid 'responseContent': null.");
+        }
+        //
+        byte[] tmp = new byte[this.responseContent.length + responseContent.length];
+        System.arraycopy(this.responseContent, 0, tmp, 0, this.responseContent.length);
+        System.arraycopy(responseContent, 0, tmp, this.responseContent.length, responseContent.length);
+        this.responseContent = tmp;
+    }
+
+    protected byte[] getResponseContent() {
+        byte[] tmp = new byte[this.responseContent.length];
+        System.arraycopy(this.responseContent, 0, tmp, 0, this.responseContent.length);
+        return tmp;
+    }
+
+    /* Notification area */
+
+    public void addNotificationAreaMessage(boolean error, String message) throws MResponseWebException {
+        this.addNotificationAreaMessage(error, message, false);
+    }
+
+    public void addNotificationAreaMessage(boolean error, String message, boolean framedOutput) throws MResponseWebException {
+        if ((null == message) || ("".equals(message))) {
+            throw new IllegalArgumentException("Invalid 'message': null or empty.");
+        }
+        //
+        if (framedOutput) {
+            String NL = System.getProperty("line.separator");
+            StringBuilder content = new StringBuilder("");
+            content.append(String.format("<?xml version=\"1.0\" encoding=\"%s\" ?>", MInformation.TEXT_ENCODING) + NL);
+            content.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" + NL);
+            content.append("<html xmlns=\"http://www.w3.org/1999/xhtml\">" + NL);
+            content.append(NL);
+            content.append("    <head>" + NL);
+            content.append(String.format("        <meta http-equiv=\"Content-type\" content=\"application/xhtml+xml; charset=%s\" />", MInformation.TEXT_ENCODING) + NL);
+            content.append("        <title />" + NL);
+            content.append("    </head>" + NL);
+            content.append(NL);
+            content.append("    <body>" + NL);
+            content.append("        <script type=\"text/javascript\">" + NL);
+            content.append("        // <![CDATA[" + NL);
+            content.append(String.format("            parent.m_notificationArea.addMessage(%s, '%s');", error, MWebString.getJavascriptEscapedString(MWebString.getXhtmlEscapedString(message))));
+            content.append("        // ]]>" + NL);
+            content.append("        </script>" + NL);
+            content.append("    </body>" + NL);
+            content.append(NL);
+            content.append("</html>" + NL);
+            try {
+                HttpServletResponse response = this.getResponseReference();
+                response.setContentType(MInformation.HttpContentType.XHTML.toString());
+                Writer writer = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), MInformation.TEXT_ENCODING));
+                writer.write(content.toString());
+                writer.flush();
+                writer.close();
+            }
+            catch (UnsupportedEncodingException exception) { // cannot happen
+            }
+            catch (IOException exception) { // put here not to bypass UnsupportedEncodingException
+                throw new MResponseWebException("Could not add notification area message.", exception);
+            }
+        }
+        else {
+            this.addPlainTextResponseContent(String.format("m_notificationArea.addMessage(%s, '%s');", error, MWebString.getJavascriptEscapedString(MWebString.getXhtmlEscapedString(message))));
+        }
+    }
+
+    /* Roaming mode */
+
+    public void setRoamingMode(boolean roamingMode) {
+        this.roamingMode = roamingMode;
+    }
+
+    public boolean getRoamingMode() {
+        return this.roamingMode;
+    }
+
+    /* Context full Url */
+
+    public String getContextFullUrl() {
+        HttpServletRequest request = this.getRequestReference();
+        String contextFullUrl = null;
+        try {
+            contextFullUrl = (new URL(request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath())).toString();
+        }
+        catch (MalformedURLException exception) { // cannot happen
+        }
+        return contextFullUrl;
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebApplicationServlet.java b/src/java/com/marcozanon/macaco/web/ui/MWebApplicationServlet.java
new file mode 100644 (file)
index 0000000..9aeef9b
--- /dev/null
@@ -0,0 +1,378 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.MHttpServlet;
+import com.marcozanon.macaco.MInformation;
+import com.marcozanon.macaco.json.MInvalidValueJsonException;
+import com.marcozanon.macaco.json.MJsonNumber;
+import com.marcozanon.macaco.json.MJsonObject;
+import com.marcozanon.macaco.json.MJsonString;
+import com.marcozanon.macaco.logging.MLogFilter;
+import com.marcozanon.macaco.logging.MLoggingException;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+public abstract class MWebApplicationServlet extends MHttpServlet {
+
+    private static final long serialVersionUID = 0L;
+
+    protected static enum ErrorMode {
+        CLEAN,
+        SILENT,
+        DEBUG
+    };
+
+    protected boolean debugMode = false;
+
+    protected MLogFilter logFilter = null;
+
+    /* */
+
+    public void destroy() {
+        try {
+            this.getLogFilterReference().close();
+        }
+        catch (MLoggingException exception) {
+        }
+        catch (MNoLogFilterWebException exception) {
+        }
+    }
+
+    /* Debug mode */
+
+    public void setDebugMode(boolean debugMode) {
+        this.debugMode = debugMode;
+    }
+
+    public boolean getDebugMode() {
+        return this.debugMode;
+    }
+
+    /* Logging */
+
+    public void setLogFilter(MLogFilter logFilter) {
+        this.logFilter = logFilter;
+    }
+
+    public MLogFilter getLogFilterReference() throws MNoLogFilterWebException {
+        if (null == this.logFilter) {
+            throw new MNoLogFilterWebException("Invalid log filter: null.");
+        }
+        //
+        return this.logFilter;
+    }
+
+    public void appendLogMessage(MLogFilter.Threshold level, String message) {
+        try {
+            this.getLogFilterReference().appendMessage(level, message);
+        }
+        catch (MLoggingException exception) {
+            this.log("[FALLBACK] " + message);
+        }
+        catch (MNoLogFilterWebException exception) {
+            this.log("[FALLBACK] " + message);
+        }
+    }
+
+    /* Requests */
+
+    protected void doGet(HttpServletRequest request, HttpServletResponse response) {
+        this.processRequest(request, response);
+    }
+
+    protected void doPost(HttpServletRequest request, HttpServletResponse response) {
+        this.processRequest(request, response);
+    }
+
+    protected void onRequestPreprocessing(HttpServletRequest request, HttpServletResponse response) throws MApplicationServletWebException {
+    }
+
+    protected abstract void processCustomRequest(HttpServletRequest request, HttpServletResponse response, MWebBrowserPage browserPage);
+
+    protected void processRequest(HttpServletRequest request, HttpServletResponse response) {
+        try {
+            request.setCharacterEncoding(MInformation.TEXT_ENCODING);
+            //
+            this.onRequestPreprocessing(request, response);
+            // check session security and refresh session parameters
+            MWebBrowserPage browserPage = this.getSafeBrowserPageReference(request, response);
+            // check for request type
+            String pathInfo = request.getPathInfo();
+            if (null == pathInfo) { // standard request
+                synchronized (browserPage) {
+                    // forward request
+                    browserPage.onRequestPreprocessing();
+                    browserPage.processRequest();
+                    // return standard response
+                    try {
+                        this.returnStandardResponse(response, browserPage.getApplicationContextReference().getResponseContentType(), browserPage.getApplicationContextReference().getResponseContent(), (null != request.getParameter("message") ? true : false));
+                    }
+                    catch (UnsupportedEncodingException exception) { // cannot happen
+                    }
+                }
+            }
+            else if (pathInfo.startsWith("/custom")) { // custom request
+                synchronized (browserPage) {
+                    this.processCustomRequest(request, response, browserPage);
+                    return;
+                }
+            }
+            else if ("/null".equals(pathInfo)) { // null request (used by some widgets)
+                return;
+            }
+            else if ("/ping".equals(pathInfo)) { // ping request (used to prevent session timeout)
+                response.setContentType(MInformation.HttpContentType.PLAIN.toString());
+                return;
+            }
+            else if (pathInfo.startsWith("/coreResources/")) { // resource request
+                String resourceInfo = pathInfo.substring("/coreResources/".length()).replace("\\", "/");
+                if ((resourceInfo.startsWith("/")) || (resourceInfo.startsWith("\\")) || (resourceInfo.contains("..")) || (resourceInfo.contains("~"))) {
+                    throw new MInvalidResourceWebException(String.format("Invalid resource request: %s.", pathInfo));
+                }
+                String httpContentType = null;
+                if (resourceInfo.toLowerCase().endsWith(".css")) { // Css resource
+                    httpContentType = MInformation.HttpContentType.CSS.toString();
+                }
+                else if (resourceInfo.toLowerCase().endsWith(".gif")) { // Gif resource
+                    httpContentType = MInformation.HttpContentType.GIF.toString();
+                }
+                else if (resourceInfo.toLowerCase().endsWith(".htm")) { // TinyMCE (X)html resource
+                    httpContentType = MInformation.HttpContentType.HTML.toString();
+                }
+                else if ((resourceInfo.toLowerCase().endsWith(".jpg")) || (resourceInfo.toLowerCase().endsWith(".jpeg"))) { // Jpeg resource
+                    httpContentType = MInformation.HttpContentType.JPEG.toString();
+                }
+                else if (resourceInfo.toLowerCase().endsWith(".js")) { // Javascript resource
+                    httpContentType = MInformation.HttpContentType.JAVASCRIPT.toString();
+                }
+                else if (resourceInfo.toLowerCase().endsWith(".png")) { // Png resource
+                    httpContentType = MInformation.HttpContentType.PNG.toString();
+                }
+                else if (resourceInfo.toLowerCase().endsWith(".txt")) { // Plain text resource
+                    httpContentType = MInformation.HttpContentType.PLAIN.toString();
+                }
+                else {
+                    throw new MInvalidResourceWebException(String.format("Invalid resource request: %s.", pathInfo));
+                }
+                this.returnRawResponse(response, httpContentType, MInformation.getCoreResource(resourceInfo));
+            }
+            else {
+                throw new MInvalidRequestWebException(String.format("Invalid request: %s.", pathInfo));
+            }
+        }
+        catch (Exception exception) {
+            this.returnErrorResponse(response, exception, (null != request.getParameter("message") ? true : false));
+        }
+    }
+
+    /* Responses */
+
+    protected void returnStandardResponse(HttpServletResponse response, String contentType, byte[] content, boolean ajaxMode) throws IOException {
+        if ((null == contentType) || ("".equals(contentType))) {
+            contentType = MInformation.HttpContentType.PLAIN.toString();
+        }
+        // prepare response content
+        byte[] responseContent = null;
+        if (ajaxMode) {
+            MJsonObject returnValue = null;
+            try {
+                returnValue = new MJsonObject();
+                returnValue.setValue("errorMode", new MJsonNumber(MWebApplicationServlet.ErrorMode.CLEAN.ordinal()));
+                MJsonString jsonParameter = new MJsonString();
+                jsonParameter.setValue(new String(content, MInformation.TEXT_ENCODING));
+                returnValue.setValue("parameter", jsonParameter);
+            }
+            catch (MInvalidValueJsonException exception) { // cannot happen
+            }
+            responseContent = returnValue.getFormattedValue().getBytes(MInformation.TEXT_ENCODING);
+        }
+        else {
+            responseContent = content;
+        }
+        //
+        try {
+            this.returnResponse(response, contentType, responseContent);
+        }
+        catch (UnsupportedEncodingException exception) { // cannot happen
+        }
+    }
+
+    protected void returnErrorResponse(HttpServletResponse response, Exception content, boolean ajaxMode) {
+        // log exception
+        this.appendLogMessage(MLogFilter.Threshold.DEBUG, String.format("Exception: %s.", MInformation.getExceptionAsString(content)));
+        // special check: maybe the client fired two or more consecutive (asynchronous) messages and some of them became unfireable later?
+        if (content instanceof MUnexpectedMessageWebException) {
+            return;
+        }
+        // set error mode
+        MWebApplicationServlet.ErrorMode errorMode = MWebApplicationServlet.ErrorMode.SILENT;
+        if (this.getDebugMode()) {
+            errorMode = MWebApplicationServlet.ErrorMode.DEBUG;
+        }
+        // prepare response content
+        byte[] responseContent = null;
+        try {
+            if (MWebApplicationServlet.ErrorMode.DEBUG == errorMode) {
+                if (ajaxMode) {
+                    MJsonObject returnValue = null;
+                    try {
+                        returnValue = new MJsonObject();
+                        returnValue.setValue("errorMode", new MJsonNumber(errorMode.ordinal()));
+                        MJsonString jsonParameter = new MJsonString();
+                        if (null != content.getMessage()) {
+                            jsonParameter.setValue(content.getClass().getName() + ": " + content.getMessage());
+                        }
+                        else {
+                            jsonParameter.setValue(content.getClass().getName());
+                        }
+                        returnValue.setValue("parameter", jsonParameter);
+                    }
+                    catch (MInvalidValueJsonException exception) { // should not happen
+                    }
+                    responseContent = returnValue.getFormattedValue().getBytes(MInformation.TEXT_ENCODING);
+                }
+                else {
+                    if (null != content.getMessage()) {
+                        responseContent = (content.getClass().getName() + ": " + content.getMessage()).getBytes(MInformation.TEXT_ENCODING);
+                    }
+                    else {
+                        responseContent = (content.getClass().getName()).getBytes(MInformation.TEXT_ENCODING);
+                    }
+                }
+            }
+            else {
+                if (ajaxMode) {
+                    responseContent = "An error occurred while processing the message.".getBytes(MInformation.TEXT_ENCODING);
+                }
+                else {
+                    responseContent = "An error occurred while processing the request.".getBytes(MInformation.TEXT_ENCODING);
+                }
+            }
+        }
+        catch (UnsupportedEncodingException exception) { // cannot happen
+        }
+        //
+        try {
+            this.returnResponse(response, MInformation.HttpContentType.PLAIN.toString(), responseContent);
+        }
+        catch (UnsupportedEncodingException exception) { // cannot happen
+        }
+        catch (IOException exception) { // put here not to bypass UnsupportedEncodingException
+        }
+    }
+
+    protected void returnRawResponse(HttpServletResponse response, String contentType, byte[] content) throws IOException {
+        this.returnResponse(response, contentType, content);
+    }
+
+    protected void returnResponse(HttpServletResponse response, String contentType, byte[] content) throws IOException { // some lines taken from http://onjava.com/pub/a/onjava/excerpt/jebp_3/index2.html
+        if (null == response) {
+            throw new IllegalArgumentException("Invalid 'response': null.");
+        }
+        if ((null == contentType) || ("".equals(contentType))) {
+            throw new IllegalArgumentException("Invalid 'contentType': null or empty.");
+        }
+        if (null == content) {
+            throw new IllegalArgumentException("Invalid 'content': null.");
+        }
+        // disable cache
+        response.setHeader("Expires", "Sun, 01 Nov 1992 02:00:00 GMT"); // already expired
+        response.setHeader("Pragma", "no-cache"); // standard HTTP/1.0 no-cache header
+        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); // standard HTTP/1.1 no-cache header
+        // send response
+        response.setContentType(contentType);
+        response.getOutputStream().write(content);
+    }
+
+    /* Application context */
+
+    protected abstract MWebApplicationContext getInitializedApplicationContext(HttpServletRequest request, HttpServletResponse response) throws MApplicationServletWebException; // abstract => not static => no other static methods in this class
+
+    /* Browser page */
+
+    protected abstract MWebBrowserPage getInitializedBrowserPage(MWebApplicationContext applicationContext) throws MApplicationServletWebException; // abstract => not static => no other static methods in this class
+
+    /* Session */
+
+    protected synchronized MWebBrowserPage getSafeBrowserPageReference(HttpServletRequest request, HttpServletResponse response) throws MApplicationServletWebException, MInvalidRemoteIpAddressWebException {
+        if (null == request) {
+            throw new IllegalArgumentException("Invalid 'request': null.");
+        }
+        //
+        MWebApplicationContext applicationContext = null;
+        MWebBrowserPage browserPage = null;
+        HttpSession session = request.getSession(false);
+        if ((null == session) || (null == (MWebApplicationContext)session.getAttribute("m_applicationContext")) || (null == (MWebBrowserPage)session.getAttribute("m_browserPage"))) { // no previous valid session
+            if (null != session) {
+                // clear complete session (including persistent Serializable objects)
+                session.invalidate();
+            }
+            // setup whole new session
+            session = request.getSession();
+            response.setHeader("Set-Cookie", "JSESSIONID=" + session.getId() + "; HttpOnly");
+            session.setAttribute("m_remoteAddress", request.getRemoteAddr());
+            try {
+                // application context
+                applicationContext = this.getInitializedApplicationContext(request, response);
+                if (null == applicationContext) {
+                    throw new MApplicationServletWebException("Invalid application context: null.");
+                }
+                session.setAttribute("m_applicationContext", applicationContext);
+                // browser page
+                browserPage = this.getInitializedBrowserPage(applicationContext);
+                if (null == browserPage) {
+                    throw new MApplicationServletWebException("Invalid browser page: null.");
+                }
+                session.setAttribute("m_browserPage", browserPage);
+            }
+            catch (MApplicationServletWebException exception) {
+                session.invalidate();
+                throw new MApplicationServletWebException("Session not initialized.", exception);
+            }
+        }
+        else { // valid session
+            // retrieve application context, refresh references and clear response content
+            applicationContext = ((MWebApplicationContext)session.getAttribute("m_applicationContext"));
+            applicationContext.refreshReferences(request, response);
+            applicationContext.clearResponseContent();
+            // retrieve browser page
+            browserPage = ((MWebBrowserPage)session.getAttribute("m_browserPage"));
+            // check whether session and current ip match
+            String sessionRemoteAddress = (String)session.getAttribute("m_remoteAddress");
+            String currentRemoteAddress = request.getRemoteAddr();
+            if ((!applicationContext.getRoamingMode()) && (!sessionRemoteAddress.equals(currentRemoteAddress))) {
+                throw new MInvalidRemoteIpAddressWebException(String.format("Invalid request: no match for session (%s) and current (%s) ip addresses.", sessionRemoteAddress, currentRemoteAddress));
+            }
+        }
+        //
+        return browserPage;
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebBorder.java b/src/java/com/marcozanon/macaco/web/ui/MWebBorder.java
new file mode 100644 (file)
index 0000000..5c49edb
--- /dev/null
@@ -0,0 +1,104 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.MObject;
+
+public class MWebBorder extends MObject {
+
+    public static enum Style {
+        DASHED("dashed"),
+        DOTTED("dotted"),
+        DOUBLE("double"),
+        GROOVE("groove"),
+        INSET("inset"),
+        OUTSET("outset"),
+        RIDGE("ridge"),
+        SOLID("solid");
+        private String name = null;
+        private Style(String name) {
+            this.name = name;
+        }
+        public String toString() {
+            return this.name;
+        }
+    };
+
+    protected MWebMeasure width = null;
+    protected MWebBorder.Style style = null;
+    protected MWebColor color = null;
+
+    /* */
+
+    public MWebBorder(MWebMeasure width, MWebBorder.Style style, MWebColor color) {
+        super();
+        //
+        if (null == width) {
+            throw new IllegalArgumentException("Invalid 'width': null.");
+        }
+        if (null == style) {
+            throw new IllegalArgumentException("Invalid 'style': null.");
+        }
+        if (null == color) {
+            throw new IllegalArgumentException("Invalid 'color': null.");
+        }
+        //
+        this.width = width;
+        this.style = style;
+        this.color = color;
+    }
+
+    public MWebBorder clone() {
+        return new MWebBorder(this.getWidthReference().clone(), this.getStyle(), this.getColorReference().clone());
+    }
+
+    /* Border */
+
+    protected MWebMeasure getWidthReference() {
+        return this.width;
+    }
+
+    protected MWebBorder.Style getStyle() {
+        return this.style;
+    }
+
+    protected MWebColor getColorReference() {
+        return this.color;
+    }
+
+    public Object[] getValue() {
+        Object[] value = new Object[3];
+        value[0] = this.getWidthReference().clone();
+        value[1] = this.getStyle();
+        value[2] = this.getColorReference().clone();
+        return value;
+    }
+
+    public String getFormattedValue() {
+        return this.getWidthReference().getFormattedValue() + " " + this.getStyle().toString() + " " + this.getColorReference().getFormattedValue();
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebBreadcrumbs.java b/src/java/com/marcozanon/macaco/web/ui/MWebBreadcrumbs.java
new file mode 100644 (file)
index 0000000..10c29a6
--- /dev/null
@@ -0,0 +1,151 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+
+public class MWebBreadcrumbs extends MWebDirectWidget {
+
+    protected String prefix = "";
+
+    /* */
+
+    public MWebBreadcrumbs(MWebApplicationContext applicationContext, String prefix) {
+        super(applicationContext);
+        //
+        this.setPrefix(prefix);
+    }
+
+    /* Prefix */
+
+    public void setPrefix(String prefix) {
+        this.setPrefix(prefix, true);
+    }
+
+    protected void setPrefix(String prefix, boolean refreshMode) {
+        if (null == prefix) {
+            throw new IllegalArgumentException("Invalid 'prefix': null.");
+        }
+        //
+        this.prefix = prefix;
+        //
+        if (refreshMode) {
+            try {
+                this.refresh(); // must refresh everything
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+            catch (MUniqueWidgetIdNotAvailableWebException exception) {
+            }
+        }
+    }
+
+    public String getPrefix() {
+        return this.prefix;
+    }
+
+    /* Refresh */
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<div class=\"MWebBreadcrumbs %s\" style=\"display: inline-block;\" id=\"%s\"></div>'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), this.getId()));
+        //
+        super.refresh();
+        //
+        StringBuilder content = new StringBuilder("");
+        content.append(String.format("<span class=\"MWebBreadcrumbPrefix %s\">%s</span>", customClasses, MWebString.getXhtmlEscapedString(this.getPrefix())));
+        LinkedList<String> viewBreadcrumbs = this.getViewReference().getBrowserPageReference().getViewBreadcrumbs();
+        for (int t = 0; t < viewBreadcrumbs.size(); t++) {
+            content.append(" ");
+            if (t > 0) {
+                content.append("» ");
+            }
+            if (t < (viewBreadcrumbs.size() - 1))  {
+                String onItemSelectionFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onItemSelection', {'viewCount': '%s'});", this.getId(), viewBreadcrumbs.size() - 1 - t);
+                content.append(String.format("<span class=\"MWebBreadcrumbItem %s\" onclick=\"%s\">%s</span>", customClasses, onItemSelectionFunction, MWebString.getXhtmlEscapedString(viewBreadcrumbs.get(t))));
+            }
+            else {
+                content.append(String.format("<span class=\"MWebBreadcrumbLastItem %s\">%s</span>", customClasses, MWebString.getXhtmlEscapedString(viewBreadcrumbs.get(t))));
+            }
+        }
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(content.toString())));
+    }
+
+    /* Messages */
+
+    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
+        super.processMessage(event, parameters);
+        //
+        if ("onItemSelection".equals(event)) {
+            if (!this.getVisibleMode()) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
+            }
+            String viewCount = parameters.get("viewCount");
+            if (null == viewCount) {
+                throw new MUnexpectedMessageWebException("Invalid message: view count parameter not available.");
+            }
+            int v = 0;
+            try {
+                v = Integer.parseInt(viewCount);
+            }
+            catch (NumberFormatException exception) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: view count parameter not recognized.", viewCount)); // no need to propagate exception
+            }
+            this.onItemSelection(v);
+        }
+        else if ("onRefresh".equals(event)) {
+            this.onRefresh();
+        }
+        else {
+            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
+        }
+    }
+
+    public void onItemSelection(int viewCount) {
+        try {
+            this.getViewReference().getBrowserPageReference().unloadViewThreads(null, viewCount, null);
+        }
+        catch (MNoBrowserPageWebException exception) {
+        }
+        catch (MNoViewWebException exception) {
+        }
+        catch (MViewNotUnloadableWebException exception) {
+        }
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebBrowserPage.java b/src/java/com/marcozanon/macaco/web/ui/MWebBrowserPage.java
new file mode 100644 (file)
index 0000000..5f3edd5
--- /dev/null
@@ -0,0 +1,440 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.MInformation;
+import com.marcozanon.macaco.MObject;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.Random;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public abstract class MWebBrowserPage extends MObject {
+
+    protected MWebApplicationContext applicationContext = null;
+
+    protected int securityId = -1;
+    protected String author = "";
+    protected String cssSource = null;
+
+    protected String lastViewThreadReturnValue = null;
+    protected Exception lastViewThreadException = null;
+    protected MWebMessage processableMessage = null;
+    protected Object stoppingViewThreadCountMutexObject = new Object();
+    protected int stoppingViewThreadCount = 0;
+    protected boolean forcedLoopMode = false;
+    protected LinkedList<Thread> viewThreads = new LinkedList<Thread>();
+
+    protected LinkedList<String> viewBreadcrumbs = new LinkedList<String>();
+
+    /* */
+
+    public MWebBrowserPage(MWebApplicationContext applicationContext, MWebView defaultView) {
+        super();
+        //
+        if (null == applicationContext) {
+            throw new IllegalArgumentException("Invalid 'applicationContext': null.");
+        }
+        //
+        this.applicationContext = applicationContext;
+        this.loadViewThread(defaultView, false);
+    }
+
+    /* Application context */
+
+    public MWebApplicationContext getApplicationContextReference() {
+        return this.applicationContext;
+    }
+
+    /* Security id */
+
+    protected void resetSecurityId() {
+        this.securityId = (new Random((new Date()).getTime())).nextInt(Integer.MAX_VALUE);
+    }
+
+    protected int getSecurityId() {
+        return this.securityId;
+    }
+
+    /* Author */
+
+    public void setAuthor(String author) {
+        if (null == author) {
+            throw new IllegalArgumentException("Invalid 'author': null.");
+        }
+        //
+        this.author = author;
+        try {
+            this.refreshAuthor();
+        }
+        catch (MResponseWebException exception) {
+        }
+    }
+
+    public String getAuthor() {
+        return this.author;
+    }
+
+    /* Css */
+
+    public void setCssSource(String cssSource) {
+        this.cssSource = cssSource;
+        try {
+            this.refreshCssSource();
+        }
+        catch (MResponseWebException exception) {
+        }
+    }
+
+    public String getCssSource() {
+        return this.cssSource;
+    }
+
+    /* Views threads */
+
+    protected void setLastViewThreadReturnValue(String lastViewThreadReturnValue) {
+        this.lastViewThreadReturnValue = lastViewThreadReturnValue;
+    }
+
+    protected String getLastViewThreadReturnValue() {
+        return this.lastViewThreadReturnValue;
+    }
+
+    protected void setLastViewThreadException(Exception lastViewThreadException) {
+        this.lastViewThreadException = lastViewThreadException;
+    }
+
+    protected Exception getLastViewThreadExceptionReference() {
+        return this.lastViewThreadException;
+    }
+
+    protected void setProcessableMessage(MWebMessage processableMessage) {
+        if (null == processableMessage) {
+            throw new IllegalArgumentException("Invalid 'processableMessage': null.");
+        }
+        //
+        this.processableMessage = processableMessage;
+    }
+
+    protected MWebMessage getProcessableMessageReference() {
+        return this.processableMessage;
+    }
+
+    protected MWebMessage getProcessableMessage() throws MNoProcessableMessageWebException {
+        if (null == this.getProcessableMessageReference()) {
+            throw new MNoProcessableMessageWebException("Invalid processable message: reference null.");
+        }
+        //
+        return this.getProcessableMessageReference().clone();
+    }
+
+    protected void setStoppingViewThreadCount(int stoppingViewThreadCount) {
+        if (stoppingViewThreadCount < 0) {
+            throw new IllegalArgumentException(String.format("Invalid 'stoppingViewThreadCount': %s.", stoppingViewThreadCount));
+        }
+        //
+        synchronized (this.stoppingViewThreadCountMutexObject) {
+            this.stoppingViewThreadCount = stoppingViewThreadCount;
+        }
+    }
+
+    protected void decrementStoppingViewThreadCount() {
+        synchronized (this.stoppingViewThreadCountMutexObject) {
+            this.stoppingViewThreadCount--;
+        }
+    }
+
+    protected int getStoppingViewThreadCount() {
+        synchronized (this.stoppingViewThreadCountMutexObject) {
+            return this.stoppingViewThreadCount;
+        }
+    }
+
+    protected void setForcedLoopMode(boolean forcedLoopMode) {
+        this.forcedLoopMode = forcedLoopMode;
+    }
+
+    protected boolean getForcedLoopMode() {
+        return this.forcedLoopMode;
+    }
+
+    protected LinkedList<Thread> getViewThreadsReference() {
+        return this.viewThreads;
+    }
+
+    protected void loadViewThread(MWebView view) {
+        this.loadViewThread(view, true);
+    }
+
+    protected void loadViewThread(MWebView view, boolean start) {
+        if (null == view) {
+            throw new IllegalArgumentException("Invalid 'view': null.");
+        }
+        //
+        view.setBrowserPage(this);
+        //
+        synchronized (this.getViewThreadsReference()) {
+            this.setLastViewThreadReturnValue(null);
+            this.setLastViewThreadException(null);
+            //
+            this.getViewThreadsReference().add(new Thread(view));
+            this.getViewBreadcrumbsReference().add(view.getBreadcrumb());
+            //
+            if (start) {
+                try {
+                    this.setProcessableMessage(new MWebMessage("{\"widgetId\": \"\", \"event\": \"onRefresh\", \"parameters\": {}}"));
+                }
+                catch (MMessagingWebException exception) { // cannot happen
+                }
+                this.getCurrentViewThreadReference().start();
+            }
+        }
+    }
+
+    protected void unloadViewThreads(String lastViewThreadReturnValue, int viewThreadCount, MWebView replacingView) throws MViewNotUnloadableWebException {
+        if ((null == lastViewThreadReturnValue) && (viewThreadCount < 1) && (null == replacingView)) {
+            throw new IllegalArgumentException("Invalid call mode: (null, < 1, null).");
+        }
+        if (viewThreadCount < 1) {
+            throw new IllegalArgumentException(String.format("Invalid 'viewThreadCount': %s.", viewThreadCount));
+        }
+        else if ((this.getViewThreadCount() <= viewThreadCount) && (null == replacingView)) {
+            throw new MViewNotUnloadableWebException("Invalid 'viewThreadCount': size exceeded.");
+        }
+        //
+        synchronized (this.getViewThreadsReference()) {
+            this.setForcedLoopMode(true);
+            //
+            this.setLastViewThreadReturnValue(lastViewThreadReturnValue);
+            this.setLastViewThreadException(null);
+            //
+            this.setStoppingViewThreadCount(viewThreadCount - 1); // calling view excluded
+            //
+            for (int x = viewThreadCount; x > 0; x--) {
+                Thread t = this.getViewThreadsReference().get(this.getViewThreadCount() - 1);
+                this.getViewThreadsReference().remove(this.getViewThreadCount() - 1);
+                this.getViewBreadcrumbsReference().remove(this.getViewBreadcrumbsReference().size() - 1);
+                synchronized (t) {
+                    t.notify();
+                }
+            }
+            while (this.getStoppingViewThreadCount() > 0) {
+            }
+            //
+            if (null != replacingView) {
+                replacingView.setBrowserPage(this);
+                this.loadViewThread(replacingView, false);
+            }
+            //
+            if (Thread.State.NEW == this.getCurrentViewThreadReference().getState()) {
+                try {
+                    this.setProcessableMessage(new MWebMessage("{\"widgetId\": \"\", \"event\": \"onRefresh\", \"parameters\": {}}"));
+                }
+                catch (MMessagingWebException exception) { // cannot happen
+                }
+                this.getCurrentViewThreadReference().start();
+            }
+            else {
+                synchronized (this.getCurrentViewThreadReference()) {
+                    this.getCurrentViewThreadReference().notify();
+                }
+            }
+            //
+            this.setForcedLoopMode(false);
+        }
+    }
+
+    protected int getViewThreadCount() {
+        synchronized (this.getViewThreadsReference()) {
+            return this.getViewThreadsReference().size();
+        }
+    }
+
+    protected Thread getCurrentViewThreadReference() {
+        synchronized (this.getViewThreadsReference()) {
+            return this.getViewThreadsReference().get(this.getViewThreadCount() - 1);
+        }
+    }
+
+    /* Breadcrumbs */
+
+    protected LinkedList<String> getViewBreadcrumbsReference() {
+        return this.viewBreadcrumbs;
+    }
+
+    public LinkedList<String> getViewBreadcrumbs() {
+        LinkedList<String> viewBreadcrumbs = new LinkedList<String>();
+        for (String viewBreadcrumb: this.getViewBreadcrumbsReference()) {
+            viewBreadcrumbs.add(viewBreadcrumb);
+        }
+        return viewBreadcrumbs;
+    }
+
+    /* Redirection */
+
+    public void redirect(String url) throws MResponseWebException {
+        if ((null == url) || ("".equals(url))) {
+            throw new IllegalArgumentException("Invalid 'url': null or empty.");
+        }
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("window.location = '%s';", MWebString.getJavascriptEscapedString(url)));
+    }
+
+    /* Refresh */
+
+    protected void refresh() throws MResponseWebException {
+        this.resetSecurityId();
+        //
+        String cssSource = MWebString.getXhtmlEscapedString(this.getCssSource());
+        if (null == cssSource) {
+            cssSource = String.format("%s/coreResources/css/default.css", this.getApplicationContextReference().getRequestReference().getRequestURL());
+        }
+        //
+        String NL = System.getProperty("line.separator");
+        StringBuilder content = new StringBuilder("");
+        content.append(String.format("<?xml version=\"1.0\" encoding=\"%s\" ?>", MInformation.TEXT_ENCODING) + NL);
+        content.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" + NL);
+        content.append("<html xmlns=\"http://www.w3.org/1999/xhtml\">" + NL);
+        content.append(NL);
+        content.append("    <head>" + NL);
+        content.append(String.format("        <meta name=\"author\" content=\"%s\" />", MWebString.getXhtmlEscapedString(this.getAuthor())) + NL);
+        content.append(String.format("        <meta name=\"generator\" content=\"%s\" />", MWebString.getXhtmlEscapedString(MInformation.getMacacoFullName())) + NL);
+        content.append(String.format("        <meta http-equiv=\"Content-type\" content=\"%s\" />", MInformation.HttpContentType.XHTML.toString()) + NL);
+        content.append(String.format("        <link rel=\"stylesheet\" type=\"text/css\" href=\"%s\" />", cssSource) + NL);
+        content.append("        <title>Loading...</title>" + NL);
+        content.append(String.format("        <script type=\"text/javascript\" src=\"%s/coreResources/javascript/$.js\" />", this.getApplicationContextReference().getRequestReference().getRequestURL()) + NL);
+        content.append(String.format("        <script type=\"text/javascript\" src=\"%s/coreResources/javascript/MWebCustomJsonHelper.js\" />", this.getApplicationContextReference().getRequestReference().getRequestURL()) + NL);
+        content.append(String.format("        <script type=\"text/javascript\" src=\"%s/coreResources/javascript/MWebMessageInterface.js\" />", this.getApplicationContextReference().getRequestReference().getRequestURL()) + NL);
+        content.append(String.format("        <script type=\"text/javascript\" src=\"%s/coreResources/javascript/MWebNotificationArea.js\" />", this.getApplicationContextReference().getRequestReference().getRequestURL()) + NL);
+        content.append(String.format("        <script type=\"text/javascript\" src=\"%s/coreResources/javascript/TinyMCE/tiny_mce.js\" />", this.getApplicationContextReference().getRequestReference().getRequestURL()) + NL);
+        content.append("        <style type=\"text/css\" id=\"m_styleSheet\">" + NL);
+        content.append("        </style>" + NL);
+        content.append("        <script type=\"text/javascript\">" + NL);
+        content.append("        // <![CDATA[" + NL);
+        content.append("            if ('Gecko' == $getRenderingEngine()) {" + NL);
+        content.append("                $('m_styleSheet').innerHTML = '* { -moz-box-sizing: border-box; }';" + NL);
+        content.append("            }" + NL);
+        content.append("            else if ('Ie' == $getRenderingEngine()) {" + NL);
+        content.append("                $('m_styleSheet').innerHTML = '* { -ms-box-sizing: border-box; }';" + NL);
+        content.append("            }" + NL);
+        content.append("            else if ('Webkit' == $getRenderingEngine()) {" + NL);
+        content.append("                $('m_styleSheet').innerHTML = '* { -webkit-box-sizing: border-box; }';" + NL);
+        content.append("            }" + NL);
+        content.append("            else {" + NL);
+        content.append("                $('m_styleSheet').innerHTML = '* { box-sizing: border-box; }';" + NL);
+        content.append("            }" + NL);
+        content.append("            var m_notificationArea = new MWebNotificationArea();" + NL);
+        content.append("            var m_waitingIcon = new Image();" + NL);
+        content.append(String.format("            m_waitingIcon.src = '%s/coreResources/gif/waitingIcon.gif';", this.getApplicationContextReference().getRequestReference().getRequestURL()) + NL);
+        content.append(String.format("            var m_messageInterface = new MWebMessageInterface('%s', '%s', m_waitingIcon);", this.getApplicationContextReference().getRequestReference().getRequestURL(), this.getSecurityId()) + NL);
+        content.append(String.format("            setInterval('m_messageInterface.sendPingRequest();', %s * 1000);", (int)Math.floor(this.getApplicationContextReference().getRequestReference().getSession(false).getMaxInactiveInterval() / 2)) + NL);
+        content.append("        // ]]>" + NL);
+        content.append("        </script>" + NL);
+        content.append("    </head>" + NL);
+        content.append(NL);
+        content.append("    <body onload=\"javascript: m_messageInterface.fireMessage('', 'onRefresh', {});\" onmousemove=\"javascript: m_notificationArea.hide();\" onkeypress=\"javascript: m_notificationArea.hide();\">" + NL);
+        content.append("        <iframe style=\"display: none;\" id=\"m_downloader\" src=\"\"></iframe>" + NL);
+        content.append("        <iframe style=\"display: none;\" id=\"m_uploader\" src=\"\"></iframe>" + NL);
+        content.append("        <div class=\"MWebView\" id=\"m_view\">Loading...</div>" + NL);
+        content.append("    </body>" + NL);
+        content.append(NL);
+        content.append("</html>" + NL);
+        //
+        this.getApplicationContextReference().setXhtmlResponseContent(content.toString());
+    }
+
+    protected void refreshAuthor() throws MResponseWebException { // inspired by http://www.programminghelp.com/forums/Topic81-20-1.aspx#bm334
+        String commands = "metaTags = $T('meta');"
+                        + "for (m = 0; m < metaTags.length; m++) {"
+                        + "    if ('author' == metaTags[m].getAttribute('name')) {"
+                        + "        metaTags[m].setAttribute('content', '%s');"
+                        + "    }"
+                        + "}";
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format(commands, MWebString.getJavascriptEscapedString(this.getAuthor())));
+    }
+
+    protected void refreshCssSource() throws MResponseWebException { // inspired by http://www.thesitewizard.com/javascripts/change-style-sheets.shtml
+        String cssSource = this.getCssSource();
+        if (null == cssSource) {
+            cssSource = String.format("%s/coreResources/css/default.css", this.getApplicationContextReference().getRequestReference().getRequestURL());
+        }
+        //
+        String commands = "linkTags = $T('link');"
+                        + "for (l = 0; l < linkTags.length; l++) {"
+                        + "    if ('stylesheet' == linkTags[l].rel) {"
+                        + "        linkTags[l].href = '%s';"
+                        + "    }"
+                        + "}";
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format(commands, MWebString.getJavascriptEscapedString(cssSource)));
+    }
+
+    /* Requests */
+
+    protected void onRequestPreprocessing() throws MBrowserPageRequestPreprocessingWebException {
+    }
+
+    protected void processRequest() throws Exception {
+        // check for proper security id, then determine request type
+        String securityId = this.getApplicationContextReference().getRequestReference().getParameter("securityId");
+        if (null == securityId) {
+            this.refresh();
+        }
+        else if (Integer.parseInt(securityId) != this.getSecurityId()) {
+            throw new MInvalidSecurityIdWebException(String.format("Invalid request: no match for security ids (%s vs %s).", securityId, this.getSecurityId()));
+        }
+        else {
+            String message = this.getApplicationContextReference().getRequestReference().getParameter("message");
+            if (null == message) {
+                throw new MUnexpectedMessageWebException("Invalid request: message null.");
+            }
+            //
+            this.setProcessableMessage(new MWebMessage(message));
+            //
+            this.setLastViewThreadReturnValue(null);
+            this.setLastViewThreadException(null);
+            //
+            if (Thread.State.NEW == this.getCurrentViewThreadReference().getState()) {
+                this.getCurrentViewThreadReference().start();
+            }
+            else {
+                synchronized (this.getCurrentViewThreadReference()) {
+                    this.getCurrentViewThreadReference().notify();
+                }
+            }
+            //
+            while (true) {
+                if (null != this.getLastViewThreadExceptionReference()) {
+                    throw this.getLastViewThreadExceptionReference();
+                }
+                if ((Thread.State.WAITING == this.getCurrentViewThreadReference().getState()) && (!this.getForcedLoopMode())) {
+                    break;
+                }
+            }
+        }
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebCellWidget.java b/src/java/com/marcozanon/macaco/web/ui/MWebCellWidget.java
new file mode 100644 (file)
index 0000000..ef1770a
--- /dev/null
@@ -0,0 +1,179 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public abstract class MWebCellWidget extends MWebDisplayWidget {
+
+    public static enum VerticalAlignment {
+        TOP("top"),
+        MIDDLE("middle"),
+        BOTTOM("bottom");
+        private String name = null;
+        private VerticalAlignment(String name) {
+            this.name = name;
+        }
+        public String toString() {
+            return this.name;
+        }
+    };
+
+    public static enum HorizontalAlignment {
+        LEFT("left"),
+        CENTER("center"),
+        RIGHT("right");
+        private String name = null;
+        private HorizontalAlignment(String name) {
+            this.name = name;
+        }
+        public String toString() {
+            return this.name;
+        }
+    };
+
+    protected MWebCellWidget.VerticalAlignment verticalAlignment = null;
+    protected MWebCellWidget.HorizontalAlignment horizontalAlignment = null;
+
+    /* */
+
+    public MWebCellWidget(MWebApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    public void cloneCellWidgetProperties(MWebCellWidget cellWidget) {
+        super.cloneDisplayWidgetProperties(cellWidget);
+        //
+        cellWidget.setVerticalAlignment(this.getVerticalAlignment());
+        cellWidget.setHorizontalAlignment(this.getHorizontalAlignment());
+    }
+
+    /* Vertical alignment */
+
+    public void setVerticalAlignment(MWebCellWidget.VerticalAlignment verticalAlignment) {
+        this.setVerticalAlignment(verticalAlignment, true);
+    }
+
+    protected void setVerticalAlignment(MWebCellWidget.VerticalAlignment verticalAlignment, boolean refreshMode) {
+        this.verticalAlignment = verticalAlignment;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshVerticalAlignment(false);
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public MWebCellWidget.VerticalAlignment getVerticalAlignment() {
+        return this.verticalAlignment;
+    }
+
+    public String getFormattedVerticalAlignment() throws MNullPropertyWebException {
+        if (null == this.getVerticalAlignment()) {
+            throw new MNullPropertyWebException("Invalid vertical alignment: property null.");
+        }
+        return this.getVerticalAlignment().toString();
+    }
+
+    /* Horizontal alignment */
+
+    public void setHorizontalAlignment(MWebCellWidget.HorizontalAlignment horizontalAlignment) {
+        this.setHorizontalAlignment(horizontalAlignment, true);
+    }
+
+    protected void setHorizontalAlignment(MWebCellWidget.HorizontalAlignment horizontalAlignment, boolean refreshMode) {
+        this.horizontalAlignment = horizontalAlignment;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshHorizontalAlignment(false);
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public MWebCellWidget.HorizontalAlignment getHorizontalAlignment() {
+        return this.horizontalAlignment;
+    }
+
+    public String getFormattedHorizontalAlignment() throws MNullPropertyWebException {
+        if (null == this.getHorizontalAlignment()) {
+            throw new MNullPropertyWebException("Invalid horizontal alignment: property null.");
+        }
+        return this.getHorizontalAlignment().toString();
+    }
+
+    /* Refresh */
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        super.refresh();
+        //
+        this.refreshVerticalAlignment(true);
+        this.refreshHorizontalAlignment(true);
+    }
+
+    protected void refreshVerticalAlignment(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        try {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').verticalAlign = '%s'; }", this.getId(), this.getId(), this.getFormattedVerticalAlignment()));
+        }
+        catch (MNullPropertyWebException exception) {
+            if (!directRefreshMode) {
+                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').verticalAlign = null; }", this.getId(), this.getId()));
+            }
+        }
+    }
+
+    protected void refreshHorizontalAlignment(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        try {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textAlign = '%s'; }", this.getId(), this.getId(), this.getFormattedHorizontalAlignment()));
+        }
+        catch (MNullPropertyWebException exception) {
+            if (!directRefreshMode) {
+                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textAlign = null; }", this.getId(), this.getId()));
+            }
+        }
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebCheckBox.java b/src/java/com/marcozanon/macaco/web/ui/MWebCheckBox.java
new file mode 100644 (file)
index 0000000..31ddc34
--- /dev/null
@@ -0,0 +1,186 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import java.util.LinkedHashMap;
+
+public class MWebCheckBox extends MWebDirectWidget {
+
+    protected boolean checkedMode = false;
+
+    protected boolean enabledMode = true;
+
+    /* */
+
+    public MWebCheckBox(MWebApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    public MWebCheckBox(MWebApplicationContext applicationContext, boolean checkedMode) {
+        this(applicationContext);
+        //
+        this.setCheckedMode(checkedMode);
+    }
+
+    /* Focus */
+
+    public void setFocus() {
+        try {
+            this.refreshFocus();
+        }
+        catch (MNoBrowserPageWebException exception) {
+        }
+        catch (MNoViewWebException exception) {
+        }
+        catch (MNoWidgetIdWebException exception) {
+        }
+        catch (MResponseWebException exception) {
+        }
+    }
+
+    /* Checked mode */
+
+    public void setCheckedMode(boolean checkedMode) {
+        this.setCheckedMode(checkedMode, true);
+    }
+
+    protected void setCheckedMode(boolean checkedMode, boolean refreshMode) {
+        this.checkedMode = checkedMode;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshCheckedMode();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public boolean getCheckedMode() {
+        return this.checkedMode;
+    }
+
+    /* Enabled mode */
+
+    public void setEnabledMode(boolean enabledMode) {
+        this.setEnabledMode(enabledMode, true);
+    }
+
+    protected void setEnabledMode(boolean enabledMode, boolean refreshMode) {
+        this.enabledMode = enabledMode;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshEnabledMode();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public boolean getEnabledMode() {
+        return this.enabledMode;
+    }
+
+    /* Refresh */
+
+    protected void refreshFocus() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').focus(); }", this.getId(), this.getId()));
+    }
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        String onChangeFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onChange', {'checkedMode': (this.checked ? '1' : '0')});", this.getId());
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<input type=\"checkbox\" class=\"MWebCheckBox %s\" style=\"display: inline-block;\" onchange=\"%s\" id=\"%s\" />'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onChangeFunction), this.getId()));
+        //
+        super.refresh();
+        //
+        this.refreshCheckedMode();
+        this.refreshEnabledMode();
+    }
+
+    protected void refreshCheckedMode() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').checked = %s; }", this.getId(), this.getId(), this.getCheckedMode()));
+    }
+
+    protected void refreshEnabledMode() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').disabled = %s; }", this.getId(), this.getId(), !this.getEnabledMode()));
+    }
+
+    /* Messages */
+
+    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
+        super.processMessage(event, parameters);
+        //
+        if ("onChange".equals(event)) {
+            if ((!this.getVisibleMode()) || (!this.getEnabledMode())) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden or disabled.", event));
+            }
+            String checkedMode = parameters.get("checkedMode");
+            if (null == checkedMode) {
+                throw new MUnexpectedMessageWebException("Invalid message: checked mode parameter not available.");
+            }
+            else if ((!"0".equals(checkedMode)) && (!"1".equals(checkedMode))) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: checked mode parameter not recognized.", checkedMode));
+            }
+            this.onChange("1".equals(checkedMode));
+        }
+        else if ("onRefresh".equals(event)) {
+            this.onRefresh();
+        }
+        else {
+            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
+        }
+    }
+
+    public void onChange(boolean checkedMode) {
+        this.setCheckedMode(checkedMode, false);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebColor.java b/src/java/com/marcozanon/macaco/web/ui/MWebColor.java
new file mode 100644 (file)
index 0000000..ecc7857
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.MObject;
+
+public class MWebColor extends MObject {
+
+    protected Integer color = null;
+
+    /* */
+
+    public MWebColor(Integer color) {
+        super();
+        //
+        if (null == color) {
+            throw new IllegalArgumentException("Invalid 'color': null.");
+        }
+        else if ((color < 0) || (color > 0xFFFFFF)) {
+            throw new IllegalArgumentException(String.format("Invalid 'color': %s.", color));
+        }
+        //
+        this.color = color;
+    }
+
+    public MWebColor clone() {
+        return new MWebColor(this.getValue());
+    }
+
+    /* Color */
+
+    public Integer getValue() {
+        return this.color;
+    }
+
+    public String getFormattedValue() {
+        return "#" + String.format("%6H", this.getValue()).replace(" ", "0");
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebComboBox.java b/src/java/com/marcozanon/macaco/web/ui/MWebComboBox.java
new file mode 100644 (file)
index 0000000..9c32336
--- /dev/null
@@ -0,0 +1,360 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+
+public class MWebComboBox extends MWebDirectWidget {
+
+    public static enum TextAlignment {
+        LEFT("left"),
+        CENTER("center"),
+        RIGHT("right");
+        private String name = null;
+        private TextAlignment(String name) {
+            this.name = name;
+        }
+        public String toString() {
+            return this.name;
+        }
+    };
+
+    protected LinkedHashMap<String, String> items = new LinkedHashMap<String, String>();
+    protected String selectedItemKey = "";
+    protected MWebComboBox.TextAlignment textAlignment = null;
+
+    protected boolean enabledMode = true;
+
+    /* */
+
+    public MWebComboBox(MWebApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    public MWebComboBox(MWebApplicationContext applicationContext, LinkedHashMap<String, String> items, String selectedItemKey) {
+        this(applicationContext);
+        //
+        this.setItems(items, selectedItemKey);
+    }
+
+    /* Focus */
+
+    public void setFocus() {
+        try {
+            this.refreshFocus();
+        }
+        catch (MNoBrowserPageWebException exception) {
+        }
+        catch (MNoViewWebException exception) {
+        }
+        catch (MNoWidgetIdWebException exception) {
+        }
+        catch (MResponseWebException exception) {
+        }
+    }
+
+    /* Items */
+
+    public void setItems(LinkedHashMap<String, String> items, String selectedItemKey) {
+        this.setItems(items, selectedItemKey, true);
+    }
+
+    protected void setItems(LinkedHashMap<String, String> items, String selectedItemKey, boolean refreshMode) {
+        if (null == items) {
+            throw new IllegalArgumentException("Invalid 'items': null.");
+        }
+        else {
+            for (String k: items.keySet()) {
+                if ((null == k) || ("".equals(k))) {
+                    throw new IllegalArgumentException("Invalid 'items': item key null or empty.");
+                }
+                else if (null == items.get(k)) {
+                    throw new IllegalArgumentException("Invalid 'items': item null.");
+                }
+            }
+        }
+        //
+        this.items = items;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshItems();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+        //
+        this.setSelectedItem(selectedItemKey, refreshMode);
+    }
+
+    protected LinkedHashMap<String, String> getItemsReference() {
+        return this.items;
+    }
+
+    public LinkedHashMap<String, String> getItems() {
+        LinkedHashMap<String, String> tmpItems = new LinkedHashMap<String, String>();
+        for (String itemKey: this.getItemsReference().keySet()) {
+            tmpItems.put(itemKey, this.getItemsReference().get(itemKey));
+        }
+        return tmpItems;
+    }
+
+    public LinkedHashSet<String> getItemKeys() {
+        LinkedHashSet<String> tmpItemKeys = new LinkedHashSet<String>();
+        for (String itemKey: this.getItemsReference().keySet()) {
+            tmpItemKeys.add(itemKey);
+        }
+        return tmpItemKeys;
+    }
+
+    public void setSelectedItem(String selectedItemKey) {
+        this.setSelectedItem(selectedItemKey, true);
+    }
+
+    protected void setSelectedItem(String selectedItemKey, boolean refreshMode) {
+        if (null == selectedItemKey) {
+            throw new IllegalArgumentException("Invalid 'selectedItemKey': null.");
+        }
+        else if ((!"".equals(selectedItemKey)) && (!this.getItemsReference().containsKey(selectedItemKey))) {
+            throw new IllegalArgumentException(String.format("Invalid 'selectedItemKey': %s: not available.", selectedItemKey));
+        }
+        //
+        this.selectedItemKey = selectedItemKey;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshSelectedItem();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public String getSelectedItemKey() {
+        return this.selectedItemKey;
+    }
+
+    public int getSelectedItemIndex() {
+        String selectedItemKey = this.getSelectedItemKey();
+        int selectedItemIndex = 0;
+        if ("".equals(selectedItemKey)) {
+            return selectedItemIndex;
+        }
+        for (String k: this.getItemsReference().keySet()) {
+            selectedItemIndex++;
+            if (k.equals(selectedItemKey)) {
+                break;
+            }
+        }
+        return selectedItemIndex;
+    }
+
+    /* Text alignment */
+
+    public void setTextAlignment(MWebComboBox.TextAlignment textAlignment) {
+        this.setTextAlignment(textAlignment, true);
+    }
+
+    protected void setTextAlignment(MWebComboBox.TextAlignment textAlignment, boolean refreshMode) {
+        this.textAlignment = textAlignment;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshTextAlignment(false);
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public MWebComboBox.TextAlignment getTextAlignment() {
+        return this.textAlignment;
+    }
+
+    public String getFormattedTextAlignment() throws MNullPropertyWebException {
+        if (null == this.getTextAlignment()) {
+            throw new MNullPropertyWebException("Invalid text alignment: property null.");
+        }
+        return this.getTextAlignment().toString();
+    }
+
+    /* Enabled mode */
+
+    public void setEnabledMode(boolean enabledMode) {
+        this.setEnabledMode(enabledMode, true);
+    }
+
+    protected void setEnabledMode(boolean enabledMode, boolean refreshMode) {
+        this.enabledMode = enabledMode;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshEnabledMode();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public boolean getEnabledMode() {
+        return this.enabledMode;
+    }
+
+    /* Refresh */
+
+    protected void refreshFocus() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').focus(); }", this.getId(), this.getId()));
+    }
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        String onBlurFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onBlur', {'selectedItemKey': this.value});", this.getId());
+        String onChangeFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onChange', {'selectedItemKey': this.value});", this.getId());
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<select class=\"MWebComboBox %s\" style=\"display: inline-block;\" onblur=\"%s\" onchange=\"%s\" id=\"%s\"><option value=\"\"></option></select>'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onBlurFunction), MWebString.getJavascriptEscapedString(onChangeFunction), this.getId()));
+        //
+        super.refresh();
+        //
+        this.refreshItems();
+        this.refreshSelectedItem();
+        this.refreshTextAlignment(true);
+        this.refreshEnabledMode();
+    }
+
+    protected void refreshItems() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').options.length = 0; }", this.getId(), this.getId()));
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').options[$('%s').options.length] = new Option('', ''); }", this.getId(), this.getId(), this.getId()));
+        for (String itemKey: this.getItemsReference().keySet()) {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').options[$('%s').options.length] = new Option('%s', '%s'); }", this.getId(), this.getId(), this.getId(), MWebString.getJavascriptEscapedString(this.getItemsReference().get(itemKey)), MWebString.getJavascriptEscapedString(itemKey)));
+        }
+    }
+
+    protected void refreshSelectedItem() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').selectedIndex = %s; }", this.getId(), this.getId(), this.getSelectedItemIndex()));
+    }
+
+    protected void refreshTextAlignment(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        try {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textAlign = '%s'; }", this.getId(), this.getId(), this.getFormattedTextAlignment()));
+        }
+        catch (MNullPropertyWebException exception) {
+            if (!directRefreshMode) {
+                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textAlign = null; }", this.getId(), this.getId()));
+            }
+        }
+    }
+
+    protected void refreshEnabledMode() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').disabled = %s; }", this.getId(), this.getId(), !this.getEnabledMode()));
+    }
+
+    /* Messages */
+
+    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
+        super.processMessage(event, parameters);
+        //
+        if ("onBlur".equals(event)) {
+            if ((!this.getVisibleMode()) || (!this.getEnabledMode())) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden or disabled.", event));
+            }
+            String selectedItemKey = parameters.get("selectedItemKey");
+            if (null == selectedItemKey) {
+                throw new MUnexpectedMessageWebException("Invalid message: selected item key parameter not available.");
+            }
+            else if ((!"".equals(selectedItemKey)) && (!this.getItemsReference().keySet().contains(selectedItemKey))) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: selected item key parameter not recognized.", selectedItemKey));
+            }
+            this.onBlur(selectedItemKey);
+        }
+        else if ("onChange".equals(event)) {
+            if ((!this.getVisibleMode()) || (!this.getEnabledMode())) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden or disabled.", event));
+            }
+            String selectedItemKey = parameters.get("selectedItemKey");
+            if (null == selectedItemKey) {
+                throw new MUnexpectedMessageWebException("Invalid message: selected item key parameter not available.");
+            }
+            else if ((!"".equals(selectedItemKey)) && (!this.getItemsReference().keySet().contains(selectedItemKey))) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: selected item key parameter not recognized.", selectedItemKey));
+            }
+            this.onChange(selectedItemKey);
+        }
+        else if ("onRefresh".equals(event)) {
+            this.onRefresh();
+        }
+        else {
+            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
+        }
+    }
+
+    public void onBlur(String selectedItemKey) {
+        this.setSelectedItem(selectedItemKey, false);
+    }
+
+    public void onChange(String selectedItemKey) {
+        this.setSelectedItem(selectedItemKey, false);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebDateBox.java b/src/java/com/marcozanon/macaco/web/ui/MWebDateBox.java
new file mode 100644 (file)
index 0000000..7635f00
--- /dev/null
@@ -0,0 +1,98 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.filtering.MConstraintFilteringException;
+import com.marcozanon.macaco.filtering.MDateFilter;
+import com.marcozanon.macaco.filtering.MFormatFilteringException;
+
+public class MWebDateBox extends MWebTextBox {
+
+    protected MDateFilter dateFilter = null;
+
+    /* */
+
+    public MWebDateBox(MWebApplicationContext applicationContext, MDateFilter dateFilter) {
+        super(applicationContext);
+        //
+        if (null == dateFilter) {
+            throw new IllegalArgumentException("Invalid 'dateFilter': null.");
+        }
+        //
+        this.dateFilter = dateFilter;
+    }
+
+    public MWebDateBox(MWebApplicationContext applicationContext, MDateFilter dateFilter, String text) {
+        this(applicationContext, dateFilter);
+        //
+        this.setText(text);
+    }
+
+    /* Date filter */
+
+    protected MDateFilter getDateFilterReference() {
+        return this.dateFilter;
+    }
+
+    public MDateFilter getDateFilter() {
+        return this.getDateFilterReference().clone();
+    }
+
+    /* Validation */
+
+    public void validate() throws MValidationWebException {
+        String text = this.getText();
+        try {
+            this.setText(this.getDateFilterReference().getValidatedUserDate(text, null));
+        }
+        catch (MConstraintFilteringException exception) {
+            throw new MValidationWebException(String.format("Invalid date: %s.", text), exception);
+        }
+        catch (MFormatFilteringException exception) {
+            throw new MValidationWebException(String.format("Invalid date: %s.", text), exception);
+        }
+    }
+
+    /* Refresh */
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        String onBlurFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onBlur', {'text': this.value});", this.getId());
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<input type=\"text\" class=\"MWebDateBox %s\" style=\"display: inline-block;\" onblur=\"%s\" id=\"%s\" />'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onBlurFunction), this.getId()));
+        //
+        super.refresh();
+        //
+        this.refreshText();
+        this.refreshTextAlignment(true);
+        this.refreshEnabledMode();
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebDatetimeBox.java b/src/java/com/marcozanon/macaco/web/ui/MWebDatetimeBox.java
new file mode 100644 (file)
index 0000000..a9483dc
--- /dev/null
@@ -0,0 +1,98 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.filtering.MConstraintFilteringException;
+import com.marcozanon.macaco.filtering.MDatetimeFilter;
+import com.marcozanon.macaco.filtering.MFormatFilteringException;
+
+public class MWebDatetimeBox extends MWebTextBox {
+
+    protected MDatetimeFilter datetimeFilter = null;
+
+    /* */
+
+    public MWebDatetimeBox(MWebApplicationContext applicationContext, MDatetimeFilter datetimeFilter) {
+        super(applicationContext);
+        //
+        if (null == datetimeFilter) {
+            throw new IllegalArgumentException("Invalid 'datetimeFilter': null.");
+        }
+        //
+        this.datetimeFilter = datetimeFilter;
+    }
+
+    public MWebDatetimeBox(MWebApplicationContext applicationContext, MDatetimeFilter datetimeFilter, String text) {
+        this(applicationContext, datetimeFilter);
+        //
+        this.setText(text);
+    }
+
+    /* Datetime filter */
+
+    protected MDatetimeFilter getDatetimeFilterReference() {
+        return this.datetimeFilter;
+    }
+
+    public MDatetimeFilter getDatetimeFilter() {
+        return this.getDatetimeFilterReference().clone();
+    }
+
+    /* Validation */
+
+    public void validate() throws MValidationWebException {
+        String text = this.getText();
+        try {
+            this.setText(this.getDatetimeFilterReference().getValidatedUserDatetime(text, null));
+        }
+        catch (MConstraintFilteringException exception) {
+            throw new MValidationWebException(String.format("Invalid datetime: %s.", text), exception);
+        }
+        catch (MFormatFilteringException exception) {
+            throw new MValidationWebException(String.format("Invalid datetime: %s.", text), exception);
+        }
+    }
+
+    /* Refresh */
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        String onBlurFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onBlur', {'text': this.value});", this.getId());
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<input type=\"text\" class=\"MWebDatetimeBox %s\" style=\"display: inline-block;\" onblur=\"%s\" id=\"%s\" />'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onBlurFunction), this.getId()));
+        //
+        super.refresh();
+        //
+        this.refreshText();
+        this.refreshTextAlignment(true);
+        this.refreshEnabledMode();
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebDirectWidget.java b/src/java/com/marcozanon/macaco/web/ui/MWebDirectWidget.java
new file mode 100644 (file)
index 0000000..755bb04
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public abstract class MWebDirectWidget extends MWebDisplayWidget {
+
+    /* */
+
+    public MWebDirectWidget(MWebApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebDisplayWidget.java b/src/java/com/marcozanon/macaco/web/ui/MWebDisplayWidget.java
new file mode 100644 (file)
index 0000000..a5015d8
--- /dev/null
@@ -0,0 +1,946 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public abstract class MWebDisplayWidget extends MWebWidget {
+
+    public static enum Side {
+        TOP("top"),
+        RIGHT("right"),
+        BOTTOM("bottom"),
+        LEFT("left");
+        private String name = null;
+        private Side(String name) {
+            this.name = name;
+        }
+        public String toString() {
+            return this.name;
+        }
+    };
+
+    public static enum TextDirection {
+        LTR("ltr"),
+        RTL("rtl");
+        private String name = null;
+        private TextDirection(String name) {
+            this.name = name;
+        }
+        public String toString() {
+            return this.name;
+        }
+    };
+
+    protected String customClasses = null;
+
+    protected MWebMeasure width = null;
+    protected MWebMeasure height = null;
+    protected MWebColor foregroundColor = null;
+    protected MWebColor backgroundColor = null;
+    protected MWebBorder topBorder = null;
+    protected MWebBorder rightBorder = null;
+    protected MWebBorder bottomBorder = null;
+    protected MWebBorder leftBorder = null;
+    protected MWebFont font = null;
+    protected MWebMeasure topPadding = null;
+    protected MWebMeasure rightPadding = null;
+    protected MWebMeasure bottomPadding = null;
+    protected MWebMeasure leftPadding = null;
+    protected MWebDisplayWidget.TextDirection textDirection = null;
+
+    protected boolean visibleMode = true;
+
+    /* */
+
+    public MWebDisplayWidget(MWebApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    public void cloneDisplayWidgetProperties(MWebDisplayWidget displayWidget) {
+        displayWidget.setWidth(this.getWidth());
+        displayWidget.setHeight(this.getHeight());
+        displayWidget.setForegroundColor(this.getForegroundColor());
+        displayWidget.setBackgroundColor(this.getBackgroundColor());
+        displayWidget.setTopBorder(this.getTopBorder());
+        displayWidget.setRightBorder(this.getRightBorder());
+        displayWidget.setBottomBorder(this.getBottomBorder());
+        displayWidget.setLeftBorder(this.getLeftBorder());
+        displayWidget.setFont(this.getFont());
+        displayWidget.setTopPadding(this.getTopPadding());
+        displayWidget.setRightPadding(this.getRightPadding());
+        displayWidget.setBottomPadding(this.getBottomPadding());
+        displayWidget.setLeftPadding(this.getLeftPadding());
+        displayWidget.setTextDirection(this.getTextDirection());
+        displayWidget.setVisibleMode(this.getVisibleMode());
+    }
+
+    /* Custom classes */
+
+    public void setCustomClasses(String customClasses) {
+        this.setCustomClasses(customClasses, true);
+    }
+
+    protected void setCustomClasses(String customClasses, boolean refreshMode) {
+        if ("".equals(customClasses)) {
+            throw new IllegalArgumentException("Invalid 'customClasses': empty.");
+        }
+        //
+        this.customClasses = customClasses;
+        //
+        if (refreshMode) {
+            try {
+                this.refresh(); // must refresh everything
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+            catch (MUniqueWidgetIdNotAvailableWebException exception) {
+            }
+        }
+    }
+
+    public String getCustomClasses() {
+        return this.customClasses;
+    }
+
+    /* Width */
+
+    public void setWidth(MWebMeasure width) {
+        this.setWidth(width, true);
+    }
+
+    protected void setWidth(MWebMeasure width, boolean refreshMode) {
+        this.width = width;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshWidth(false);
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    protected MWebMeasure getWidthReference() {
+        return this.width;
+    }
+
+    public MWebMeasure getWidth() {
+        if (null == this.getWidthReference()) {
+            return null;
+        }
+        return this.getWidthReference().clone();
+    }
+
+    public String getFormattedWidth() throws MNullPropertyWebException {
+        if (null == this.getWidthReference()) {
+            throw new MNullPropertyWebException("Invalid width: reference null.");
+        }
+        return this.getWidthReference().getFormattedValue();
+    }
+
+    /* Height */
+
+    public void setHeight(MWebMeasure height) {
+        this.setHeight(height, true);
+    }
+
+    protected void setHeight(MWebMeasure height, boolean refreshMode) {
+        this.height = height;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshHeight(false);
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    protected MWebMeasure getHeightReference() {
+        return this.height;
+    }
+
+    public MWebMeasure getHeight() {
+        if (null == this.getHeightReference()) {
+            return null;
+        }
+        return this.getHeightReference().clone();
+    }
+
+    public String getFormattedHeight() throws MNullPropertyWebException {
+        if (null == this.getHeightReference()) {
+            throw new MNullPropertyWebException("Invalid height: reference null.");
+        }
+        return this.getHeightReference().getFormattedValue();
+    }
+
+    /* Foreground color */
+
+    public void setForegroundColor(MWebColor foregroundColor) {
+        this.setForegroundColor(foregroundColor, true);
+    }
+
+    protected void setForegroundColor(MWebColor foregroundColor, boolean refreshMode) {
+        this.foregroundColor = foregroundColor;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshForegroundColor(false);
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    protected MWebColor getForegroundColorReference() {
+        return this.foregroundColor;
+    }
+
+    public MWebColor getForegroundColor() {
+        if (null == this.getForegroundColorReference()) {
+            return null;
+        }
+        return this.getForegroundColorReference().clone();
+    }
+
+    public String getFormattedForegroundColor() throws MNullPropertyWebException {
+        if (null == this.getForegroundColorReference()) {
+            throw new MNullPropertyWebException("Invalid foreground color: reference null.");
+        }
+        return this.getForegroundColorReference().getFormattedValue();
+    }
+
+    /* Background color */
+
+    public void setBackgroundColor(MWebColor backgroundColor) {
+        this.setBackgroundColor(backgroundColor, true);
+    }
+
+    protected void setBackgroundColor(MWebColor backgroundColor, boolean refreshMode) {
+        this.backgroundColor = backgroundColor;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshBackgroundColor(false);
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    protected MWebColor getBackgroundColorReference() {
+        return this.backgroundColor;
+    }
+
+    public MWebColor getBackgroundColor() {
+        if (null == this.getBackgroundColorReference()) {
+            return null;
+        }
+        return this.getBackgroundColorReference().clone();
+    }
+
+    public String getFormattedBackgroundColor() throws MNullPropertyWebException {
+        if (null == this.getBackgroundColorReference()) {
+            throw new MNullPropertyWebException("Invalid background color: reference null.");
+        }
+        return this.getBackgroundColorReference().getFormattedValue();
+    }
+
+    /* Borders */
+
+    public void setTopBorder(MWebBorder border) {
+        this.setTopBorder(border, true);
+    }
+
+    protected void setTopBorder(MWebBorder border, boolean refreshMode) {
+        this.setBorder(border, MWebDisplayWidget.Side.TOP, refreshMode);
+    }
+
+    public void setRightBorder(MWebBorder border) {
+        this.setRightBorder(border, true);
+    }
+
+    protected void setRightBorder(MWebBorder border, boolean refreshMode) {
+        this.setBorder(border, MWebDisplayWidget.Side.RIGHT, refreshMode);
+    }
+
+    public void setBottomBorder(MWebBorder border) {
+        this.setBottomBorder(border, true);
+    }
+
+    protected void setBottomBorder(MWebBorder border, boolean refreshMode) {
+        this.setBorder(border, MWebDisplayWidget.Side.BOTTOM, refreshMode);
+    }
+
+    public void setLeftBorder(MWebBorder border) {
+        this.setLeftBorder(border, true);
+    }
+
+    protected void setLeftBorder(MWebBorder border, boolean refreshMode) {
+        this.setBorder(border, MWebDisplayWidget.Side.LEFT, refreshMode);
+    }
+
+    public void setBorder(MWebBorder border) {
+        this.setBorder(border, null, true);
+    }
+
+    protected void setBorder(MWebBorder border, boolean refreshMode) {
+        this.setBorder(border, null, refreshMode);
+    }
+
+    public void setBorder(MWebBorder border, MWebDisplayWidget.Side borderSide) {
+        this.setBorder(border, borderSide, true);
+    }
+
+    protected void setBorder(MWebBorder border, MWebDisplayWidget.Side borderSide, boolean refreshMode) {
+        if (null == borderSide) {
+            this.topBorder = border;
+            this.rightBorder = border;
+            this.bottomBorder = border;
+            this.leftBorder = border;
+        }
+        else if (MWebDisplayWidget.Side.TOP == borderSide) {
+            this.topBorder = border;
+        }
+        else if (MWebDisplayWidget.Side.RIGHT == borderSide) {
+            this.rightBorder = border;
+        }
+        else if (MWebDisplayWidget.Side.BOTTOM == borderSide) {
+            this.bottomBorder = border;
+        }
+        else if (MWebDisplayWidget.Side.LEFT == borderSide) {
+            this.leftBorder = border;
+        }
+        //
+        if (refreshMode) {
+            try {
+                this.refreshBorder(borderSide, false);
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    protected MWebBorder getTopBorderReference() {
+        return this.topBorder;
+    }
+
+    public MWebBorder getTopBorder() {
+        if (null == this.getTopBorderReference()) {
+            return null;
+        }
+        return this.getTopBorderReference().clone();
+    }
+
+    public String getFormattedTopBorder() throws MNullPropertyWebException {
+        if (null == this.getTopBorderReference()) {
+            throw new MNullPropertyWebException("Invalid top border: reference null.");
+        }
+        return this.getTopBorderReference().getFormattedValue();
+    }
+
+    protected MWebBorder getRightBorderReference() {
+        return this.rightBorder;
+    }
+
+    public MWebBorder getRightBorder() {
+        if (null == this.getRightBorderReference()) {
+            return null;
+        }
+        return this.getRightBorderReference().clone();
+    }
+
+    public String getFormattedRightBorder() throws MNullPropertyWebException {
+        if (null == this.getRightBorderReference()) {
+            throw new MNullPropertyWebException("Invalid right border: reference null.");
+        }
+        return this.getRightBorderReference().getFormattedValue();
+    }
+
+    protected MWebBorder getBottomBorderReference() {
+        return this.bottomBorder;
+    }
+
+    public MWebBorder getBottomBorder() {
+        if (null == this.getBottomBorderReference()) {
+            return null;
+        }
+        return this.getBottomBorderReference().clone();
+    }
+
+    public String getFormattedBottomBorder() throws MNullPropertyWebException {
+        if (null == this.getBottomBorderReference()) {
+            throw new MNullPropertyWebException("Invalid bottom border: reference null.");
+        }
+        return this.getBottomBorderReference().getFormattedValue();
+    }
+
+    protected MWebBorder getLeftBorderReference() {
+        return this.leftBorder;
+    }
+
+    public MWebBorder getLeftBorder() {
+        if (null == this.getLeftBorderReference()) {
+            return null;
+        }
+        return this.getLeftBorderReference().clone();
+    }
+
+    public String getFormattedLeftBorder() throws MNullPropertyWebException {
+        if (null == this.getLeftBorderReference()) {
+            throw new MNullPropertyWebException("Invalid left border: reference null.");
+        }
+        return this.getLeftBorderReference().getFormattedValue();
+    }
+
+    /* Font */
+
+    public void setFont(MWebFont font) {
+        this.setFont(font, true);
+    }
+
+    protected void setFont(MWebFont font, boolean refreshMode) {
+        this.font = font;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshFont(false);
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    protected MWebFont getFontReference() {
+        return this.font;
+    }
+
+    public MWebFont getFont() {
+        if (null == this.getFontReference()) {
+            return null;
+        }
+        return this.getFontReference().clone();
+    }
+
+    public String[] getFormattedFont() throws MNullPropertyWebException {
+        if (null == this.getFontReference()) {
+            throw new MNullPropertyWebException("Invalid font: reference null.");
+        }
+        return this.getFontReference().getFormattedValue();
+    }
+
+    /* Paddings */
+
+    public void setTopPadding(MWebMeasure padding) {
+        this.setTopPadding(padding, true);
+    }
+
+    protected void setTopPadding(MWebMeasure padding, boolean refreshMode) {
+        this.setPadding(padding, MWebDisplayWidget.Side.TOP, refreshMode);
+    }
+
+    public void setRightPadding(MWebMeasure padding) {
+        this.setRightPadding(padding, true);
+    }
+
+    protected void setRightPadding(MWebMeasure padding, boolean refreshMode) {
+        this.setPadding(padding, MWebDisplayWidget.Side.RIGHT, refreshMode);
+    }
+
+    public void setBottomPadding(MWebMeasure padding) {
+        this.setBottomPadding(padding, true);
+    }
+
+    protected void setBottomPadding(MWebMeasure padding, boolean refreshMode) {
+        this.setPadding(padding, MWebDisplayWidget.Side.BOTTOM, refreshMode);
+    }
+
+    public void setLeftPadding(MWebMeasure padding) {
+        this.setLeftPadding(padding, true);
+    }
+
+    protected void setLeftPadding(MWebMeasure padding, boolean refreshMode) {
+        this.setPadding(padding, MWebDisplayWidget.Side.LEFT, refreshMode);
+    }
+
+    public void setPadding(MWebMeasure padding) {
+        this.setPadding(padding, null, true);
+    }
+
+    protected void setPadding(MWebMeasure padding, boolean refreshMode) {
+        this.setPadding(padding, null, refreshMode);
+    }
+
+    public void setPadding(MWebMeasure padding, MWebDisplayWidget.Side paddingSide) {
+        this.setPadding(padding, paddingSide, true);
+    }
+
+    protected void setPadding(MWebMeasure padding, MWebDisplayWidget.Side paddingSide, boolean refreshMode) {
+        if (null == paddingSide) {
+            this.topPadding = padding;
+            this.rightPadding = padding;
+            this.bottomPadding = padding;
+            this.leftPadding = padding;
+        }
+        else if (MWebDisplayWidget.Side.TOP == paddingSide) {
+            this.topPadding = padding;
+        }
+        else if (MWebDisplayWidget.Side.RIGHT == paddingSide) {
+            this.rightPadding = padding;
+        }
+        else if (MWebDisplayWidget.Side.BOTTOM == paddingSide) {
+            this.bottomPadding = padding;
+        }
+        else if (MWebDisplayWidget.Side.LEFT == paddingSide) {
+            this.leftPadding = padding;
+        }
+        //
+        if (refreshMode) {
+            try {
+                this.refreshPadding(paddingSide, false);
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    protected MWebMeasure getTopPaddingReference() {
+        return this.topPadding;
+    }
+
+    public MWebMeasure getTopPadding() {
+        if (null == this.getTopPaddingReference()) {
+            return null;
+        }
+        return this.getTopPaddingReference().clone();
+    }
+
+    public String getFormattedTopPadding() throws MNullPropertyWebException {
+        if (null == this.getTopPaddingReference()) {
+            throw new MNullPropertyWebException("Invalid top padding: reference null.");
+        }
+        return this.getTopPaddingReference().getFormattedValue();
+    }
+
+    protected MWebMeasure getRightPaddingReference() {
+        return this.rightPadding;
+    }
+
+    public MWebMeasure getRightPadding() {
+        if (null == this.getRightPaddingReference()) {
+            return null;
+        }
+        return this.getRightPaddingReference().clone();
+    }
+
+    public String getFormattedRightPadding() throws MNullPropertyWebException {
+        if (null == this.getRightPaddingReference()) {
+            throw new MNullPropertyWebException("Invalid right padding: reference null.");
+        }
+        return this.getRightPaddingReference().getFormattedValue();
+    }
+
+    protected MWebMeasure getBottomPaddingReference() {
+        return this.bottomPadding;
+    }
+
+    public MWebMeasure getBottomPadding() {
+        if (null == this.getBottomPaddingReference()) {
+            return null;
+        }
+        return this.getBottomPaddingReference().clone();
+    }
+
+    public String getFormattedBottomPadding() throws MNullPropertyWebException {
+        if (null == this.getBottomPaddingReference()) {
+            throw new MNullPropertyWebException("Invalid bottom padding: reference null.");
+        }
+        return this.getBottomPaddingReference().getFormattedValue();
+    }
+
+    protected MWebMeasure getLeftPaddingReference() {
+        return this.leftPadding;
+    }
+
+    public MWebMeasure getLeftPadding() {
+        if (null == this.getLeftPaddingReference()) {
+            return null;
+        }
+        return this.getLeftPaddingReference().clone();
+    }
+
+    public String getFormattedLeftPadding() throws MNullPropertyWebException {
+        if (null == this.getLeftPaddingReference()) {
+            throw new MNullPropertyWebException("Invalid left padding: reference null.");
+        }
+        return this.getLeftPaddingReference().getFormattedValue();
+    }
+
+    /* Text direction */
+
+    public void setTextDirection(MWebDisplayWidget.TextDirection textDirection) {
+        this.setTextDirection(textDirection, true);
+    }
+
+    protected void setTextDirection(MWebDisplayWidget.TextDirection textDirection, boolean refreshMode) {
+        this.textDirection = textDirection;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshTextDirection(false);
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public MWebDisplayWidget.TextDirection getTextDirection() {
+        return this.textDirection;
+    }
+
+    public String getFormattedTextDirection() throws MNullPropertyWebException {
+        if (null == this.getTextDirection()) {
+            throw new MNullPropertyWebException("Invalid text direction: property null.");
+        }
+        return this.getTextDirection().toString();
+    }
+
+    /* Visible mode */
+
+    public void setVisibleMode(boolean visibleMode) {
+        this.setVisibleMode(visibleMode, true);
+    }
+
+    protected void setVisibleMode(boolean visibleMode, boolean refreshMode) {
+        this.visibleMode = visibleMode;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshVisibleMode();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public boolean getVisibleMode() {
+        return this.visibleMode;
+    }
+
+    /* Display widgets */
+
+    protected MWebDisplayWidget getDisplayWidgetReferenceById(String id) throws MDisplayWidgetNotFoundWebException {
+        if ((null == id) || ("".equals(id))) {
+            throw new IllegalArgumentException("Invalid 'id': null or empty.");
+        }
+        //
+        String myId = null;
+        try {
+            myId = this.getId();
+        }
+        catch (MNoWidgetIdWebException exception) {
+            throw new MDisplayWidgetNotFoundWebException("Display widget id not available."); // no need to propagate exception
+        }
+        if (myId.equals(id)) {
+            return this;
+        }
+        throw new MDisplayWidgetNotFoundWebException(String.format("Invalid 'id': %s: display widget not available on this path.", id));
+    }
+
+    /* Validation */
+
+    public void validate() throws MValidationWebException {
+    }
+
+    /* Refresh */
+
+    public void checkPresence() throws MNoBrowserPageWebException, MNoViewWebException {
+        this.getViewReference().checkPresence();
+    }
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        this.refreshWidth(true);
+        this.refreshHeight(true);
+        this.refreshForegroundColor(true);
+        this.refreshBackgroundColor(true);
+        this.refreshBorder(null, true);
+        this.refreshFont(true);
+        this.refreshPadding(null, true);
+        this.refreshTextDirection(true);
+        //
+        this.refreshVisibleMode();
+    }
+
+    protected void refreshWidth(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        try {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').width = '%s'; }", this.getId(), this.getId(), this.getFormattedWidth()));
+        }
+        catch (MNullPropertyWebException exception) {
+            if (!directRefreshMode) {
+                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').width = null; }", this.getId(), this.getId()));
+            }
+        }
+    }
+
+    protected void refreshHeight(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        try {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').height = '%s'; }", this.getId(), this.getId(), this.getFormattedHeight()));
+        }
+        catch (MNullPropertyWebException exception) {
+            if (!directRefreshMode) {
+                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').height = null; }", this.getId(), this.getId()));
+            }
+        }
+    }
+
+    protected void refreshForegroundColor(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        try {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').color = '%s'; }", this.getId(), this.getId(), this.getFormattedForegroundColor()));
+        }
+        catch (MNullPropertyWebException exception) {
+            if (!directRefreshMode) {
+                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').color = null; }", this.getId(), this.getId()));
+            }
+        }
+    }
+
+    protected void refreshBackgroundColor(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        try {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').backgroundColor = '%s'; }", this.getId(), this.getId(), this.getFormattedBackgroundColor()));
+        }
+        catch (MNullPropertyWebException exception) {
+            if (!directRefreshMode) {
+                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').backgroundColor = null; }", this.getId(), this.getId()));
+            }
+        }
+    }
+
+    protected void refreshBorder(MWebDisplayWidget.Side borderSide, boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        if (null == borderSide) {
+            this.refreshBorder(MWebDisplayWidget.Side.TOP, directRefreshMode);
+            this.refreshBorder(MWebDisplayWidget.Side.RIGHT, directRefreshMode);
+            this.refreshBorder(MWebDisplayWidget.Side.BOTTOM, directRefreshMode);
+            this.refreshBorder(MWebDisplayWidget.Side.LEFT, directRefreshMode);
+        }
+        else {
+            String temporaryBorderSide = null;
+            try {
+                String formattedBorder = null;
+                if (MWebDisplayWidget.Side.TOP == borderSide) {
+                    temporaryBorderSide = "Top";
+                    formattedBorder = this.getFormattedTopBorder();
+                }
+                else if (MWebDisplayWidget.Side.RIGHT == borderSide) {
+                    temporaryBorderSide = "Right";
+                    formattedBorder = this.getFormattedRightBorder();
+                }
+                else if (MWebDisplayWidget.Side.BOTTOM == borderSide) {
+                    temporaryBorderSide = "Bottom";
+                    formattedBorder = this.getFormattedBottomBorder();
+                }
+                else if (MWebDisplayWidget.Side.LEFT == borderSide) {
+                    temporaryBorderSide = "Left";
+                    formattedBorder = this.getFormattedLeftBorder();
+                }
+                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').border%s = '%s'; }", this.getId(), this.getId(), temporaryBorderSide, formattedBorder));
+            }
+            catch (MNullPropertyWebException exception) {
+                if (!directRefreshMode) {
+                    this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').border%s = null; }", this.getId(), this.getId(), temporaryBorderSide));
+                }
+            }
+        }
+    }
+
+    protected void refreshFont(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        try {
+            String[] formattedFont = this.getFormattedFont();
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').font = '%s'; }", this.getId(), this.getId(), formattedFont[0]));
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textDecoration = '%s'; }", this.getId(), this.getId(), formattedFont[1]));
+        }
+        catch (MNullPropertyWebException exception) {
+            if (!directRefreshMode) {
+                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').font = null; }", this.getId(), this.getId()));
+                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textDecoration = null; }", this.getId(), this.getId()));
+            }
+        }
+    }
+
+    protected void refreshPadding(MWebDisplayWidget.Side paddingSide, boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        if (null == paddingSide) {
+            this.refreshPadding(MWebDisplayWidget.Side.TOP, directRefreshMode);
+            this.refreshPadding(MWebDisplayWidget.Side.RIGHT, directRefreshMode);
+            this.refreshPadding(MWebDisplayWidget.Side.BOTTOM, directRefreshMode);
+            this.refreshPadding(MWebDisplayWidget.Side.LEFT, directRefreshMode);
+        }
+        else {
+            String temporaryPaddingSide = null;
+            try {
+                String formattedPadding = null;
+                if (MWebDisplayWidget.Side.TOP == paddingSide) {
+                    temporaryPaddingSide = "Top";
+                    formattedPadding = this.getFormattedTopPadding();
+                }
+                else if (MWebDisplayWidget.Side.RIGHT == paddingSide) {
+                    temporaryPaddingSide = "Right";
+                    formattedPadding = this.getFormattedRightPadding();
+                }
+                else if (MWebDisplayWidget.Side.BOTTOM == paddingSide) {
+                    temporaryPaddingSide = "Bottom";
+                    formattedPadding = this.getFormattedBottomPadding();
+                }
+                else if (MWebDisplayWidget.Side.LEFT == paddingSide) {
+                    temporaryPaddingSide = "Left";
+                    formattedPadding = this.getFormattedLeftPadding();
+                }
+                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').padding%s = '%s'; }", this.getId(), this.getId(), temporaryPaddingSide, formattedPadding));
+            }
+            catch (MNullPropertyWebException exception) {
+                if (!directRefreshMode) {
+                    this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').padding%s = null; }", this.getId(), this.getId(), temporaryPaddingSide));
+                }
+            }
+        }
+    }
+
+    protected void refreshTextDirection(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        try {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').direction = '%s'; }", this.getId(), this.getId(), this.getFormattedTextDirection()));
+        }
+        catch (MNullPropertyWebException exception) {
+            if (!directRefreshMode) {
+                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').direction = null; }", this.getId(), this.getId()));
+            }
+        }
+    }
+
+    protected void refreshVisibleMode() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        if (this.getVisibleMode()) {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').visibility = 'visible'; }", this.getId(), this.getId()));
+        }
+        else {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').visibility = 'hidden'; }", this.getId(), this.getId()));
+        }
+    }
+
+    /* Messages */
+
+    public void onRefresh() {
+        try {
+            this.refresh();
+        }
+        catch (MNoBrowserPageWebException exception) {
+        }
+        catch (MNoViewWebException exception) {
+        }
+        catch (MNoWidgetIdWebException exception) {
+        }
+        catch (MResponseWebException exception) {
+        }
+        catch (MUniqueWidgetIdNotAvailableWebException exception) {
+        }
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebDownloader.java b/src/java/com/marcozanon/macaco/web/ui/MWebDownloader.java
new file mode 100644 (file)
index 0000000..5e26931
--- /dev/null
@@ -0,0 +1,77 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.json.MInvalidValueJsonException;
+import com.marcozanon.macaco.json.MJsonObject;
+import com.marcozanon.macaco.json.MJsonString;
+import java.util.LinkedHashMap;
+
+public class MWebDownloader extends MWebWidget {
+
+    /* */
+
+    public MWebDownloader(MWebApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    /* Downloads */
+
+    public void forceDownload() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        MJsonObject downloadMessage = null;
+        try {
+            downloadMessage = new MJsonObject();
+            downloadMessage.setValue("widgetId", new MJsonString("\"" + this.getId() + "\""));
+            downloadMessage.setValue("event", new MJsonString("\"" + "onDownload" + "\""));
+            downloadMessage.setValue("parameters", new MJsonObject());
+        }
+        catch (MInvalidValueJsonException exception) { // cannot happen
+        }
+        //
+        MWebBrowserPage browserPage = this.getViewReference().getBrowserPageReference();
+        String destinationUrl = this.getApplicationContextReference().getRequestReference().getRequestURL().toString();
+        String parameters = "securityId=" + browserPage.getSecurityId() + "&message=" + downloadMessage.getFormattedValue();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("$('m_downloader').src = '%s?%s';", destinationUrl, parameters));
+    }
+
+    /* Messages */
+
+    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
+        super.processMessage(event, parameters);
+        //
+        if ("onDownload".equals(event)) {
+            this.onDownload();
+        }
+        else {
+            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
+        }
+    }
+
+    public void onDownload() {
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebException.java b/src/java/com/marcozanon/macaco/web/ui/MWebException.java
new file mode 100644 (file)
index 0000000..5f5bb35
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.MException;
+
+public abstract class MWebException extends MException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MWebException() {
+        super();
+    }
+
+    public MWebException(String message) {
+        super(message);
+    }
+
+    public MWebException(Throwable error) {
+        super(error);
+    }
+
+    public MWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebExtendedTextBox.java b/src/java/com/marcozanon/macaco/web/ui/MWebExtendedTextBox.java
new file mode 100644 (file)
index 0000000..48229ec
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import java.util.LinkedHashMap;
+
+public class MWebExtendedTextBox extends MWebTextBox {
+
+    /* */
+
+    public MWebExtendedTextBox(MWebApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    public MWebExtendedTextBox(MWebApplicationContext applicationContext, String text) {
+        this(applicationContext);
+        //
+        this.setText(text);
+    }
+
+    /* Refresh */
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        String onBlurFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onBlur', {'text': this.value});", this.getId());
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<textarea class=\"MWebExtendedTextBox %s\" style=\"display: inline-block;\" onblur=\"%s\" id=\"%s\" cols=\"1\" rows=\"1\"></textarea>'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onBlurFunction), this.getId()));
+        //
+        super.refresh();
+        //
+        this.refreshText();
+        this.refreshTextAlignment(true);
+        this.refreshEnabledMode();
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebFont.java b/src/java/com/marcozanon/macaco/web/ui/MWebFont.java
new file mode 100644 (file)
index 0000000..df63a9b
--- /dev/null
@@ -0,0 +1,177 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.MObject;
+
+public class MWebFont extends MObject {
+
+    public static enum Style {
+        ITALIC("italic"),
+        NORMAL("normal"),
+        OBLIQUE("oblique");
+        private String name = null;
+        private Style(String name) {
+            this.name = name;
+        }
+        public String toString() {
+            return this.name;
+        }
+    };
+
+    public static enum Variant {
+        NORMAL("normal"),
+        SMALL_CAPS("small-caps");
+        private String name = null;
+        private Variant(String name) {
+            this.name = name;
+        }
+        public String toString() {
+            return this.name;
+        }
+    };
+
+    public static enum Weight {
+        BOLD("bold"),
+        BOLDER("bolder"),
+        LIGHTER("lighter"),
+        NORMAL("normal");
+        private String name = null;
+        private Weight(String name) {
+            this.name = name;
+        }
+        public String toString() {
+            return this.name;
+        }
+    };
+
+    public static final String MONOSPACE_FAMILY = "monospace";
+    public static final String SANS_SERIF_FAMILY = "sans-serif";
+    public static final String SERIF_FAMILY = "serif";
+
+    public static enum Decoration {
+        BLINK("blink"),
+        LINE_THROUGH("line-through"),
+        NONE("none"),
+        OVERLINE("overline"),
+        UNDERLINE("underline");
+        private String name = null;
+        private Decoration(String name) {
+            this.name = name;
+        }
+        public String toString() {
+            return this.name;
+        }
+    };
+
+    protected MWebFont.Style style = null;
+    protected MWebFont.Variant variant = null;
+    protected MWebFont.Weight weight = null;
+    protected MWebMeasure size = null;
+    protected String family = null;
+    protected MWebFont.Decoration decoration = null;
+
+    /* */
+
+    public MWebFont(MWebFont.Style style, MWebFont.Variant variant, MWebFont.Weight weight, MWebMeasure size, String family, MWebFont.Decoration decoration) {
+        super();
+        //
+        if (null == style) {
+            throw new IllegalArgumentException("Invalid 'style': null.");
+        }
+        if (null == variant) {
+            throw new IllegalArgumentException("Invalid 'variant': null.");
+        }
+        if (null == weight) {
+            throw new IllegalArgumentException("Invalid 'weight': null.");
+        }
+        if (null == size) {
+            throw new IllegalArgumentException("Invalid 'size': null.");
+        }
+        if ((null == family) || ("".equals(family))) {
+            throw new IllegalArgumentException("Invalid 'family': null or empty.");
+        }
+        if (null == decoration) {
+            throw new IllegalArgumentException("Invalid 'decoration': null.");
+        }
+        //
+        this.style = style;
+        this.variant = variant;
+        this.weight = weight;
+        this.size = size;
+        this.family = family;
+        this.decoration = decoration;
+    }
+
+    public MWebFont clone() {
+        return new MWebFont(this.getStyle(), this.getVariant(), this.getWeight(), this.getSizeReference().clone(), this.getFamily(), this.getDecoration());
+    }
+
+    /* Font */
+
+    protected MWebFont.Style getStyle() {
+        return this.style;
+    }
+
+    protected MWebFont.Variant getVariant() {
+        return this.variant;
+    }
+
+    protected MWebFont.Weight getWeight() {
+        return this.weight;
+    }
+
+    protected MWebMeasure getSizeReference() {
+        return this.size;
+    }
+
+    protected String getFamily() {
+        return this.family;
+    }
+
+    protected MWebFont.Decoration getDecoration() {
+        return this.decoration;
+    }
+
+    public Object[] getValue() {
+        Object[] value = new Object[6];
+        value[0] = this.getStyle();
+        value[1] = this.getVariant();
+        value[2] = this.getWeight();
+        value[3] = this.getSizeReference().clone();
+        value[4] = this.getFamily();
+        value[5] = this.getDecoration();
+        return value;
+    }
+
+    public String[] getFormattedValue() {
+        String[] formattedValue = new String[2];
+        formattedValue[0] = this.getStyle().toString() + " " + this.getVariant().toString() + " " + this.getWeight().toString() + " " + this.getSizeReference().getFormattedValue() + " " + this.getFamily();
+        formattedValue[1] = this.getDecoration().toString();
+        return formattedValue;
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebGridLayout.java b/src/java/com/marcozanon/macaco/web/ui/MWebGridLayout.java
new file mode 100644 (file)
index 0000000..5308e50
--- /dev/null
@@ -0,0 +1,203 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import java.util.LinkedHashMap;
+
+public class MWebGridLayout extends MWebDirectWidget {
+
+    protected MWebGridLayoutCell[][] cells = null;
+
+    /* */
+
+    public MWebGridLayout(MWebApplicationContext applicationContext, int rowCount, int columnCount) {
+        super(applicationContext);
+        //
+        this.setWidth(new MWebMeasure(100, MWebMeasure.Unit.PERCENT)); // manual override
+        //
+        if (rowCount < 1) {
+            throw new IllegalArgumentException(String.format("Invalid 'rowCount': %s.", rowCount));
+        }
+        if (columnCount < 1) {
+            throw new IllegalArgumentException(String.format("Invalid 'columnCount': %s.", columnCount));
+        }
+        //
+        this.cells = new MWebGridLayoutCell[rowCount][columnCount];
+        for (int r = 0; r < rowCount; r++) {
+            for (int c = 0; c < columnCount; c++) {
+                this.cells[r][c] = new MWebGridLayoutCell(this.getApplicationContextReference(), this);
+            }
+        }
+    }
+
+    /* Cells */
+
+    public int getRowCount() {
+        if (null == this.getCellsReference()) {
+            return 0;
+        }
+        return this.getCellsReference().length;
+    }
+
+    public int getColumnCount() {
+        if (null == this.getCellsReference()) {
+            return 0;
+        }
+        return this.getCellsReference()[0].length;
+    }
+
+    protected MWebGridLayoutCell[][] getCellsReference() {
+        return this.cells;
+    }
+
+    public MWebGridLayoutCell getCellReference(int rowIndex, int columnIndex) {
+        if ((rowIndex < 0) || (rowIndex > (this.getCellsReference().length - 1))) {
+            throw new IllegalArgumentException(String.format("Invalid 'rowIndex': %s.", rowIndex));
+        }
+        if ((columnIndex < 0) || (columnIndex > (this.getCellsReference()[0].length - 1))) {
+            throw new IllegalArgumentException(String.format("Invalid 'columnIndex': %s.", columnIndex));
+        }
+        //
+        return this.getCellsReference()[rowIndex][columnIndex];
+    }
+
+    /* View */
+
+    protected void setView(MWebView view) throws MUniqueWidgetIdNotAvailableWebException {
+        super.setView(view);
+        //
+        for (int r = 0; r < this.getRowCount(); r++) {
+            for (int c = 0; c < this.getColumnCount(); c++) {
+                this.getCellReference(r, c).setView(view);
+            }
+        }
+    }
+
+    /* Display widgets */
+
+    protected MWebDisplayWidget getDisplayWidgetReferenceById(String id) throws MDisplayWidgetNotFoundWebException {
+        try {
+            return super.getDisplayWidgetReferenceById(id);
+        }
+        catch (MDisplayWidgetNotFoundWebException exception) {
+            for (int r = 0; r < this.getRowCount(); r++) {
+                for (int c = 0; c < this.getColumnCount(); c++) {
+                    try {
+                        return this.getCellReference(r, c).getDisplayWidgetReferenceById(id);
+                    }
+                    catch (MDisplayWidgetNotFoundWebException exception2) {
+                    }
+                }
+            }
+            throw new MDisplayWidgetNotFoundWebException(String.format("Invalid 'id': %s: display widget not available on this path.", id)); // no need to propagate exception
+        }
+    }
+
+    /* Refresh */
+
+    protected boolean isCellRefreshable(int rowIndex, int columnIndex) {
+        if ((rowIndex < 0) || (rowIndex > (this.getCellsReference().length - 1))) {
+            throw new IllegalArgumentException(String.format("Invalid 'rowIndex': %s.", rowIndex));
+        }
+        if ((columnIndex < 0) || (columnIndex > (this.getCellsReference()[0].length - 1))) {
+            throw new IllegalArgumentException(String.format("Invalid 'columnIndex': %s.", columnIndex));
+        }
+        //
+        int[][] cellsRefreshableMode = new int[rowIndex + 1][columnIndex + 1]; // to avoid recursion
+        for (int r = 0; r <= rowIndex; r++) {
+            for (int c = 0; c <= columnIndex; c++) {
+                if (0 > cellsRefreshableMode[r][c]) {
+                    continue;
+                }
+                cellsRefreshableMode[r][c] = 1;
+                int rs = this.getCellReference(r, c).getRowSpan();
+                int cs = this.getCellReference(r, c).getColumnSpan();
+                if ((rs > 1) || (cs > 1)) {
+                    for (int rsi = r + 1; rsi <= Math.min(rowIndex, r + rs - 1); rsi++) {
+                        for (int csi = c + 1; csi <= Math.min(columnIndex, c + cs - 1); csi++) {
+                            cellsRefreshableMode[rsi][csi] = -1;
+                        }
+                    }
+                }
+                if ((r == rowIndex) && (c == columnIndex)) {
+                    return true;
+                }
+                if ((0 < cellsRefreshableMode[r][c]) && ((r + this.getCellReference(r, c).getRowSpan() - 1) >= rowIndex) && ((c + this.getCellReference(r, c).getColumnSpan() - 1) >= columnIndex)) {
+                    return false;
+                }
+            }
+        }
+        //
+        return true; // necessary to avoid Java compilation errors
+    }
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        StringBuilder content = new StringBuilder("");
+        content.append(String.format("<table class=\"MWebGridLayoutTable %s\" style=\"display: inline-table;\" id=\"%s\">", customClasses, this.getId()));
+        for (int r = 0; r < this.getRowCount(); r++) {
+            content.append(String.format("<tr class=\"MWebGridLayoutRow %s\">", customClasses));
+            for (int c = 0; c < this.getColumnCount(); c++) {
+                String displayedMode = "";
+                if (!this.isCellRefreshable(r, c)) {
+                    displayedMode = "display: none;";
+                    this.getCellReference(r, c).setVisibleMode(false, false); 
+                }
+                content.append(String.format("<td class=\"MWebGridLayoutCell %s\" style=\"%s\" id=\"%s\" rowspan=\"%s\" colspan=\"%s\"></td>", customClasses, displayedMode, this.getCellReference(r, c).getId(), Math.min(this.getCellReference(r, c).getRowSpan(), this.getRowCount() - r), Math.min(this.getCellReference(r, c).getColumnSpan(), this.getColumnCount() - c)));
+            }
+            content.append("</tr>");
+        }
+        content.append("</table>");
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(content.toString())));
+        //
+        for (int r = 0; r < this.getRowCount(); r++) {
+            for (int c = 0; c < this.getColumnCount(); c++) {
+                this.getCellReference(r, c).onRefresh();
+            }
+        }
+        //
+        super.refresh();
+    }
+
+    /* Messages */
+
+    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
+        super.processMessage(event, parameters);
+        //
+        if ("onRefresh".equals(event)) {
+            this.onRefresh();
+        }
+        else {
+            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
+        }
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebGridLayoutCell.java b/src/java/com/marcozanon/macaco/web/ui/MWebGridLayoutCell.java
new file mode 100644 (file)
index 0000000..0bce4d0
--- /dev/null
@@ -0,0 +1,230 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import java.util.LinkedHashMap;
+
+public class MWebGridLayoutCell extends MWebCellWidget {
+
+    protected MWebDirectWidget content = null;
+
+    protected MWebGridLayout container = null;
+
+    protected int rowSpan = 1;
+    protected int columnSpan = 1;
+
+    /* */
+
+    public MWebGridLayoutCell(MWebApplicationContext applicationContext, MWebGridLayout container) {
+        super(applicationContext);
+        //
+        if (null == container) {
+            throw new IllegalArgumentException("Invalid 'container': null.");
+        }
+        //
+        this.container = container;
+    }
+
+    /* Content */
+
+    public void setContent(MWebDirectWidget directWidget) throws MUniqueWidgetIdNotAvailableWebException {
+        this.setContent(directWidget, true);
+    }
+
+    protected void setContent(MWebDirectWidget directWidget, boolean refreshMode) throws MUniqueWidgetIdNotAvailableWebException {
+        try {
+            this.getContentReference().setView(null);
+        }
+        catch (MNoCellContentWebException exception) {
+        }
+        catch (MUniqueWidgetIdNotAvailableWebException exception) { // cannot happen
+        }
+        //
+        this.content = directWidget;
+        //
+        MWebDirectWidget content = null;
+        try {
+            content = this.getContentReference();
+            content.setView(this.getViewReference());
+        }
+        catch (MNoCellContentWebException exception) {
+        }
+        catch (MNoViewWebException exception) {
+            content.setView(null);
+        }
+        //
+        if (refreshMode) {
+            try {
+                this.refreshContent();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public MWebDirectWidget getContentReference() throws MNoCellContentWebException {
+        if (null == this.content) {
+            throw new MNoCellContentWebException("Invalid content: null.");
+        }
+        //
+        return this.content;
+    }
+
+    /* View */
+
+    protected void setView(MWebView view) throws MUniqueWidgetIdNotAvailableWebException {
+        super.setView(view);
+        //
+        try {
+            this.getContentReference().setView(view);
+        }
+        catch (MNoCellContentWebException exception) {
+        }
+    }
+
+    /* Container */
+
+    public MWebGridLayout getContainerReference() {
+        return this.container;
+    }
+
+    /* Span */
+
+    public void setRowSpan(int rowSpan) {
+        if (rowSpan < 1) {
+            throw new IllegalArgumentException("Invalid 'rowSpan': must be > 1.");
+        }
+        //
+        this.rowSpan = rowSpan;
+        //
+        try {
+            this.getContainerReference().refresh();
+        }
+        catch (MNoBrowserPageWebException exception) {
+        }
+        catch (MNoViewWebException exception) {
+        }
+        catch (MNoWidgetIdWebException exception) {
+        }
+        catch (MResponseWebException exception) {
+        }
+        catch (MUniqueWidgetIdNotAvailableWebException exception) {
+        }
+    }
+
+    public int getRowSpan() {
+        return this.rowSpan;
+    }
+
+    public void setColumnSpan(int columnSpan) {
+        if (columnSpan < 1) {
+            throw new IllegalArgumentException("Invalid 'columnSpan': must be > 1.");
+        }
+        //
+        this.columnSpan = columnSpan;
+        //
+        try {
+            this.getContainerReference().refresh();
+        }
+        catch (MNoBrowserPageWebException exception) {
+        }
+        catch (MNoViewWebException exception) {
+        }
+        catch (MNoWidgetIdWebException exception) {
+        }
+        catch (MResponseWebException exception) {
+        }
+        catch (MUniqueWidgetIdNotAvailableWebException exception) {
+        }
+    }
+
+    public int getColumnSpan() {
+        return this.columnSpan;
+    }
+
+    /* Display widgets */
+
+    protected MWebDisplayWidget getDisplayWidgetReferenceById(String id) throws MDisplayWidgetNotFoundWebException {
+        try {
+            return super.getDisplayWidgetReferenceById(id);
+        }
+        catch (MDisplayWidgetNotFoundWebException exception) {
+            try {
+                return this.getContentReference().getDisplayWidgetReferenceById(id);
+            }
+            catch (MDisplayWidgetNotFoundWebException exception2) {
+                throw new MDisplayWidgetNotFoundWebException(String.format("Invalid 'id': %s: display widget not available on this path.", id)); // no need to propagate exception
+            }
+            catch (MNoCellContentWebException exception2) {
+                throw new MDisplayWidgetNotFoundWebException(String.format("Invalid 'id': %s: no cell content.", id)); // no need to propagate exception
+            }
+        }
+    }
+
+    /* Refresh */
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        this.refreshContent();
+        //
+        super.refresh();
+    }
+
+    protected void refreshContent() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        MWebDirectWidget content = null;
+        try {
+            content = this.getContentReference();
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '<div id=\"%s\"></div>'; }", this.getId(), this.getId(), content.getId()));
+            content.onRefresh();
+        }
+        catch (MNoCellContentWebException exception) {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = ''; }", this.getId(), this.getId()));
+        }
+    }
+
+    /* Messages */
+
+    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
+        super.processMessage(event, parameters);
+        //
+        if ("onRefresh".equals(event)) {
+            this.onRefresh();
+        }
+        else {
+            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
+        }
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebImage.java b/src/java/com/marcozanon/macaco/web/ui/MWebImage.java
new file mode 100644 (file)
index 0000000..5b9e1b1
--- /dev/null
@@ -0,0 +1,175 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import java.util.LinkedHashMap;
+
+public class MWebImage extends MWebDirectWidget {
+
+    protected String imageSource = null;
+    protected String alternativeText = "";
+
+    /* */
+
+    public MWebImage(MWebApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    public MWebImage(MWebApplicationContext applicationContext, String imageSource, String alternativeText) {
+        this(applicationContext);
+        //
+        this.setImageSource(imageSource);
+        this.setAlternativeText(alternativeText);
+    }
+
+    /* Image source */
+
+    public void setImageSource(String imageSource) {
+        this.setImageSource(imageSource, true);
+    }
+
+    protected void setImageSource(String imageSource, boolean refreshMode) {
+        this.imageSource = imageSource;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshImageSource();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public String getImageSource() {
+        return this.imageSource;
+    }
+
+    /* Alternative text */
+
+    public void setAlternativeText(String alternativeText) {
+        this.setAlternativeText(alternativeText, true);
+    }
+
+    protected void setAlternativeText(String alternativeText, boolean refreshMode) {
+        if (null == alternativeText) {
+            throw new IllegalArgumentException("Invalid 'alternativeText': null.");
+        }
+        //
+        this.alternativeText = alternativeText;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshAlternativeText();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public String getAlternativeText() {
+        return this.alternativeText;
+    }
+
+    /* Refresh */
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        String onClickFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onClick', {});", this.getId());
+        String onDoubleClickFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onDoubleClick', {});", this.getId());
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<img class=\"MWebImage %s\" style=\"display: inline-block;\" onclick=\"%s\" ondblclick=\"%s\" id=\"%s\" src=\"%s/null\" alt=\"\" />'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onClickFunction), MWebString.getJavascriptEscapedString(onDoubleClickFunction), this.getId(), this.getApplicationContextReference().getRequestReference().getRequestURL()));
+        //
+        super.refresh();
+        //
+        this.refreshImageSource();
+        this.refreshAlternativeText();
+    }
+
+    protected void refreshImageSource() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        if (null == this.getImageSource()) {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').src = '%s/null'; }", this.getId(), this.getId(), this.getApplicationContextReference().getRequestReference().getRequestURL()));
+        }
+        else {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').src = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(this.getImageSource())));
+        }
+    }
+
+    protected void refreshAlternativeText() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').alt = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(this.getAlternativeText())));
+    }
+
+    /* Messages */
+
+    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
+        super.processMessage(event, parameters);
+        //
+        if ("onClick".equals(event)) {
+            if (!this.getVisibleMode()) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
+            }
+            this.onClick();
+        }
+        else if ("onDoubleClick".equals(event)) {
+            if (!this.getVisibleMode()) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
+            }
+            this.onDoubleClick();
+        }
+        else if ("onRefresh".equals(event)) {
+            this.onRefresh();
+        }
+        else {
+            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
+        }
+    }
+
+    public void onClick() {
+    }
+
+    public void onDoubleClick() {
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebImageButton.java b/src/java/com/marcozanon/macaco/web/ui/MWebImageButton.java
new file mode 100644 (file)
index 0000000..f82fca9
--- /dev/null
@@ -0,0 +1,326 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import java.util.LinkedHashMap;
+
+public class MWebImageButton extends MWebDirectWidget {
+
+    public static enum ImageAlignment {
+        TOP("top"),
+        RIGHT("right"),
+        BOTTOM("bottom"),
+        LEFT("left");
+        private String name = null;
+        private ImageAlignment(String name) {
+            this.name = name;
+        }
+        public String toString() {
+            return this.name;
+        }
+    };
+
+    protected String text = "";
+    protected String imageSource = null;
+    protected MWebImageButton.ImageAlignment imageAlignment = null;
+
+    protected boolean enabledMode = true;
+
+    /* */
+
+    public MWebImageButton(MWebApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    public MWebImageButton(MWebApplicationContext applicationContext, String text) {
+        this(applicationContext);
+        //
+        this.setText(text);
+    }
+
+    public MWebImageButton(MWebApplicationContext applicationContext, String text, String imageSource, MWebImageButton.ImageAlignment imageAlignment) {
+        this(applicationContext, text);
+        //
+        this.setImageSource(imageSource);
+        this.setImageAlignment(imageAlignment);
+    }
+
+    /* Focus */
+
+    public void setFocus() {
+        try {
+            this.refreshFocus();
+        }
+        catch (MNoBrowserPageWebException exception) {
+        }
+        catch (MNoViewWebException exception) {
+        }
+        catch (MNoWidgetIdWebException exception) {
+        }
+        catch (MResponseWebException exception) {
+        }
+    }
+
+    /* Text */
+
+    public void setText(String text) {
+        this.setText(text, true);
+    }
+
+    protected void setText(String text, boolean refreshMode) {
+        if (null == text) {
+            throw new IllegalArgumentException("Invalid 'text': null.");
+        }
+        //
+        this.text = text;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshText();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public String getText() {
+        return this.text;
+    }
+
+    /* Image source */
+
+    public void setImageSource(String imageSource) {
+        this.setImageSource(imageSource, true);
+    }
+
+    protected void setImageSource(String imageSource, boolean refreshMode) {
+        this.imageSource = imageSource;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshImageSource();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public String getImageSource() {
+        return this.imageSource;
+    }
+
+    /* Image alignment */
+
+    public void setImageAlignment(MWebImageButton.ImageAlignment imageAlignment) {
+        this.setImageAlignment(imageAlignment, true);
+    }
+
+    protected void setImageAlignment(MWebImageButton.ImageAlignment imageAlignment, boolean refreshMode) {
+        this.imageAlignment = imageAlignment;
+        //
+        if (refreshMode) {
+            try {
+                this.refresh(); // must refresh everything
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+            catch (MUniqueWidgetIdNotAvailableWebException exception) {
+            }
+        }
+    }
+
+    public MWebImageButton.ImageAlignment getImageAlignment() {
+        return this.imageAlignment;
+    }
+
+    public String getFormattedImageAlignment() throws MNullPropertyWebException {
+        if (null == this.getImageAlignment()) {
+            throw new MNullPropertyWebException("Invalid image alignment: property null.");
+        }
+        return this.getImageAlignment().toString();
+    }
+
+    /* Enabled mode */
+
+    public void setEnabledMode(boolean enabledMode) {
+        this.setEnabledMode(enabledMode, true);
+    }
+
+    protected void setEnabledMode(boolean enabledMode, boolean refreshMode) {
+        this.enabledMode = enabledMode;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshEnabledMode();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public boolean getEnabledMode() {
+        return this.enabledMode;
+    }
+
+    /* Refresh */
+
+    protected void refreshFocus() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').focus(); }", this.getId(), this.getId()));
+    }
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        StringBuilder imageContent = new StringBuilder(String.format("<td class=\"MWebImageButtonImageCell %s\"><img class=\"MWebImageButtonImage %s\" id=\"%s_image\" src=\"%s/null\" alt=\"\" /></td>", customClasses, customClasses, this.getId(), this.getApplicationContextReference().getRequestReference().getRequestURL()));
+        StringBuilder textContent = new StringBuilder(String.format("<td class=\"MWebImageButtonTextCell %s\" id=\"%s_textCell\"></td>", customClasses, this.getId()));
+        StringBuilder content = new StringBuilder("");
+        content.append(String.format("<table class=\"MWebImageButtonTable %s\">", customClasses));
+        MWebImageButton.ImageAlignment imageAlignment = this.getImageAlignment();
+        if (null == imageAlignment) {
+            content.append(String.format("<tr class=\"MWebImageButtonRow %s\">", customClasses));
+            content.append(textContent);
+            content.append("</tr>");
+        }
+        else if (MWebImageButton.ImageAlignment.TOP == imageAlignment) {
+            content.append(String.format("<tr class=\"MWebImageButtonRow %s\">", customClasses));
+            content.append(imageContent);
+            content.append("</tr>");
+            content.append(String.format("<tr class=\"MWebImageButtonRow %s\">", customClasses));
+            content.append(textContent);
+            content.append("</tr>");
+        }
+        else if (MWebImageButton.ImageAlignment.RIGHT == imageAlignment) {
+            content.append(String.format("<tr class=\"MWebImageButtonRow %s\">", customClasses));
+            content.append(textContent);
+            content.append(imageContent);
+            content.append("</tr>");
+        }
+        else if (MWebImageButton.ImageAlignment.BOTTOM == imageAlignment) {
+            content.append(String.format("<tr class=\"MWebImageButtonRow %s\">", customClasses));
+            content.append(textContent);
+            content.append("</tr>");
+            content.append(String.format("<tr class=\"MWebImageButtonRow %s\">", customClasses));
+            content.append(imageContent);
+            content.append("</tr>");
+        }
+        else if (MWebImageButton.ImageAlignment.LEFT == imageAlignment) {
+            content.append(String.format("<tr class=\"MWebImageButtonRow %s\">", customClasses));
+            content.append(imageContent);
+            content.append(textContent);
+            content.append("</tr>");
+        }
+        content.append("</table>");
+        String onClickFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onClick', {});", this.getId());
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<button class=\"MWebImageButton %s\" style=\"display: inline-block;\" onclick=\"%s\" id=\"%s\">%s</button>'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onClickFunction), this.getId(), MWebString.getJavascriptEscapedString(content.toString())));
+        //
+        super.refresh();
+        //
+        this.refreshText();
+        this.refreshImageSource();
+        this.refreshEnabledMode();
+    }
+
+    protected void refreshText() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s_textCell').innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(this.getText())));
+    }
+
+    protected void refreshImageSource() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        try {
+            this.getFormattedImageAlignment();
+            if (null == this.getImageSource()) {
+                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s_image').src = '%s/null'; }", this.getId(), this.getId(), this.getApplicationContextReference().getRequestReference().getRequestURL()));
+            }
+            else {
+                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s_image').src = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(this.getImageSource())));
+            }
+        }
+        catch (MNullPropertyWebException exception) {
+        }
+    }
+
+    protected void refreshEnabledMode() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').disabled = %s; }", this.getId(), this.getId(), !this.getEnabledMode()));
+    }
+
+    /* Messages */
+
+    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
+        super.processMessage(event, parameters);
+        //
+        if ("onClick".equals(event)) {
+            if ((!this.getVisibleMode()) || (!this.getEnabledMode())) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden or disabled.", event));
+            }
+            this.onClick();
+        }
+        else if ("onRefresh".equals(event)) {
+            this.onRefresh();
+        }
+        else {
+            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
+        }
+    }
+
+    public void onClick() {
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebLabel.java b/src/java/com/marcozanon/macaco/web/ui/MWebLabel.java
new file mode 100644 (file)
index 0000000..1fb4dec
--- /dev/null
@@ -0,0 +1,197 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import java.util.LinkedHashMap;
+
+public class MWebLabel extends MWebDirectWidget {
+
+    public static enum TextAlignment {
+        LEFT("left"),
+        CENTER("center"),
+        RIGHT("right"),
+        JUSTIFIED("justify");
+        private String name = null;
+        private TextAlignment(String name) {
+            this.name = name;
+        }
+        public String toString() {
+            return this.name;
+        }
+    };
+
+    protected String text = "";
+    protected MWebLabel.TextAlignment textAlignment = null;
+
+    /* */
+
+    public MWebLabel(MWebApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    public MWebLabel(MWebApplicationContext applicationContext, String text) {
+        this(applicationContext);
+        //
+        this.setText(text);
+    }
+
+    /* Text */
+
+    public void setText(String text) {
+        this.setText(text, true);
+    }
+
+    protected void setText(String text, boolean refreshMode) {
+        if (null == text) {
+            throw new IllegalArgumentException("Invalid 'text': null.");
+        }
+        //
+        this.text = text;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshText();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public String getText() {
+        return this.text;
+    }
+
+    /* Text alignment */
+
+    public void setTextAlignment(MWebLabel.TextAlignment textAlignment) {
+        this.setTextAlignment(textAlignment, true);
+    }
+
+    protected void setTextAlignment(MWebLabel.TextAlignment textAlignment, boolean refreshMode) {
+        this.textAlignment = textAlignment;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshTextAlignment(false);
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public MWebLabel.TextAlignment getTextAlignment() {
+        return this.textAlignment;
+    }
+
+    public String getFormattedTextAlignment() throws MNullPropertyWebException {
+        if (null == this.getTextAlignment()) {
+            throw new MNullPropertyWebException("Invalid text alignment: property null.");
+        }
+        return this.getTextAlignment().toString();
+    }
+
+    /* Refresh */
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        String onClickFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onClick', {});", this.getId());
+        String onDoubleClickFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onDoubleClick', {});", this.getId());
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<div class=\"MWebLabel %s\" style=\"display: inline-block;\" onclick=\"%s\" ondblclick=\"%s\" id=\"%s\"></div>'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onClickFunction), MWebString.getJavascriptEscapedString(onDoubleClickFunction), this.getId()));
+        //
+        super.refresh();
+        //
+        this.refreshText();
+        this.refreshTextAlignment(true);
+    }
+
+    protected void refreshText() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(MWebString.getXhtmlEscapedString(this.getText()))));
+    }
+
+    protected void refreshTextAlignment(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        try {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textAlign = '%s'; }", this.getId(), this.getId(), this.getFormattedTextAlignment()));
+        }
+        catch (MNullPropertyWebException exception) {
+            if (!directRefreshMode) {
+                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textAlign = null; }", this.getId(), this.getId()));
+            }
+        }
+    }
+
+    /* Messages */
+
+    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
+        super.processMessage(event, parameters);
+        //
+        if ("onClick".equals(event)) {
+            if (!this.getVisibleMode()) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
+            }
+            this.onClick();
+        }
+        else if ("onDoubleClick".equals(event)) {
+            if (!this.getVisibleMode()) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
+            }
+            this.onDoubleClick();
+        }
+        else if ("onRefresh".equals(event)) {
+            this.onRefresh();
+        }
+        else {
+            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
+        }
+    }
+
+    public void onClick() {
+    }
+
+    public void onDoubleClick() {
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebMeasure.java b/src/java/com/marcozanon/macaco/web/ui/MWebMeasure.java
new file mode 100644 (file)
index 0000000..f2a461f
--- /dev/null
@@ -0,0 +1,95 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.MObject;
+
+public class MWebMeasure extends MObject {
+
+    public static enum Unit {
+        CM("cm"),
+        EM("em"),
+        EX("ex"),
+        IN("in"),
+        MM("mm"),
+        PC("pc"),
+        PERCENT("%"),
+        PT("pt"),
+        PX("px");
+        private String name = null;
+        private Unit(String name) {
+            this.name = name;
+        }
+        public String toString() {
+            return this.name;
+        }
+    };
+
+    protected Number number = null;
+    protected MWebMeasure.Unit unit = null;
+
+    /* */
+
+    public MWebMeasure(Number number, MWebMeasure.Unit unit) {
+        super();
+        //
+        if (null == number) {
+            throw new IllegalArgumentException("Invalid 'number': null.");
+        }
+        if (null == unit) {
+            throw new IllegalArgumentException("Invalid 'unit': null.");
+        }
+        //
+        this.number = number;
+        this.unit = unit;
+    }
+
+    public MWebMeasure clone() {
+        return new MWebMeasure(this.getNumber(), this.getUnit());
+    }
+
+    /* Measure */
+
+    protected Number getNumber() {
+        return this.number;
+    }
+
+    protected MWebMeasure.Unit getUnit() {
+        return this.unit;
+    }
+
+    public Object[] getValue() {
+        Object[] value = new Object[2];
+        value[0] = this.getNumber();
+        value[1] = this.getUnit();
+        return value;
+    }
+
+    public String getFormattedValue() {
+        return this.getNumber() + this.getUnit().toString();
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebMessage.java b/src/java/com/marcozanon/macaco/web/ui/MWebMessage.java
new file mode 100644 (file)
index 0000000..03f2ced
--- /dev/null
@@ -0,0 +1,150 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.MObject;
+import com.marcozanon.macaco.json.MInvalidValueJsonException;
+import com.marcozanon.macaco.json.MJsonObject;
+import com.marcozanon.macaco.json.MJsonString;
+import com.marcozanon.macaco.json.MValueNotFoundJsonException;
+import java.util.LinkedHashMap;
+
+public class MWebMessage extends MObject {
+
+    protected String widgetId = null;
+    protected String event = null;
+    protected LinkedHashMap<String, String> parameters = null;
+
+    /* */
+
+    public MWebMessage(String message) throws MMessagingWebException {
+        super();
+        //
+        if ((null == message) || "".equals(message)) {
+            throw new IllegalArgumentException("Invalid 'message': null or empty.");
+        }
+        //
+        MJsonObject jsonMessage = null;
+        try {
+            jsonMessage = new MJsonObject(message);
+        }
+        catch (MInvalidValueJsonException exception) {
+            throw new MMessagingWebException("Invalid 'message': not a Json object."); // no need to propagate exception
+        }
+        // parse widget id component
+        try {
+            this.widgetId = ((MJsonString)jsonMessage.getValue("widgetId")).getValue();
+        }
+        catch (ClassCastException exception) {
+            throw new MMessagingWebException("Invalid 'message': invalid widget id."); // no need to propagate exception
+        }
+        catch (MValueNotFoundJsonException exception) {
+            throw new MMessagingWebException("Invalid 'message': no widget id key."); // no need to propagate exception
+        }
+        // parse event component
+        try {
+            String temporaryEvent = ((MJsonString)jsonMessage.getValue("event")).getValue();
+            if ("".equals(temporaryEvent)) {
+                throw new MMessagingWebException("Invalid 'message': event empty.");
+            }
+            this.event = temporaryEvent;
+        }
+        catch (ClassCastException exception) {
+            throw new MMessagingWebException("Invalid 'message': invalid event."); // no need to propagate exception
+        }
+        catch (MValueNotFoundJsonException exception) {
+            throw new MMessagingWebException("Invalid 'message': no event key."); // no need to propagate exception
+        }
+        // parse parameters component
+        this.parameters = new LinkedHashMap<String, String>();
+        try {
+            MJsonObject temporaryParameters = (MJsonObject)jsonMessage.getValue("parameters");
+            for (String key: temporaryParameters.getKeys()) {
+                this.parameters.put(key, ((MJsonString)temporaryParameters.getValue(key)).getValue());
+            }
+        }
+        catch (ClassCastException exception) {
+            throw new MMessagingWebException("Invalid 'message': invalid parameters."); // no need to propagate exception
+        }
+        catch (MValueNotFoundJsonException exception) {
+            throw new MMessagingWebException("Invalid 'message': no parameters key."); // no need to propagate exception
+        }
+    }
+
+    public MWebMessage clone() {
+        try {
+            MJsonString tmpString = null;
+            MJsonObject tmpMessage = new MJsonObject("{}");
+            //
+            tmpString = new MJsonString("\"\"");
+            tmpString.setValue(this.getWidgetId());
+            tmpMessage.setValue("widgetId", tmpString);
+            //
+            tmpString = new MJsonString("\"\"");
+            tmpString.setValue(this.getEvent());
+            tmpMessage.setValue("event", tmpString);
+            //
+            MJsonObject tmpMessageParameters = new MJsonObject("{}");
+            for (String parameterKey: this.getParametersReference().keySet()) {
+                tmpString = new MJsonString("\"\"");
+                tmpString.setValue(this.getParameters().get(parameterKey));
+                tmpMessageParameters.setValue(parameterKey, tmpString);
+            }
+            tmpMessage.setValue("parameters", tmpMessageParameters);
+            //
+            return new MWebMessage(tmpMessage.getFormattedValue());
+        }
+        catch (MInvalidValueJsonException exception) { // cannot happen
+            return null; // necessary to avoid Java compilation errors
+        }
+        catch (MMessagingWebException exception) { // cannot happen
+            return null; // necessary to avoid Java compilation errors
+        }
+    }
+
+    /* Components */
+
+    public String getWidgetId() {
+        return this.widgetId;
+    }
+
+    public String getEvent() {
+        return this.event;
+    }
+
+    protected LinkedHashMap<String, String> getParametersReference() {
+        return this.parameters;
+    }
+
+    public LinkedHashMap<String, String> getParameters() {
+        LinkedHashMap<String, String> tmpParameters = new LinkedHashMap<String, String>();
+        for (String key: this.getParametersReference().keySet()) {
+            tmpParameters.put(key, this.getParametersReference().get(key));
+        }
+        return tmpParameters;
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebNumberBox.java b/src/java/com/marcozanon/macaco/web/ui/MWebNumberBox.java
new file mode 100644 (file)
index 0000000..373fdc0
--- /dev/null
@@ -0,0 +1,98 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.filtering.MConstraintFilteringException;
+import com.marcozanon.macaco.filtering.MFormatFilteringException;
+import com.marcozanon.macaco.filtering.MNumberFilter;
+
+public class MWebNumberBox extends MWebTextBox {
+
+    protected MNumberFilter numberFilter = null;
+
+    /* */
+
+    public MWebNumberBox(MWebApplicationContext applicationContext, MNumberFilter numberFilter) {
+        super(applicationContext);
+        //
+        if (null == numberFilter) {
+            throw new IllegalArgumentException("Invalid 'numberFilter': null.");
+        }
+        //
+        this.numberFilter = numberFilter;
+    }
+
+    public MWebNumberBox(MWebApplicationContext applicationContext, MNumberFilter numberFilter, String text) {
+        this(applicationContext, numberFilter);
+        //
+        this.setText(text);
+    }
+
+    /* Number filter */
+
+    protected MNumberFilter getNumberFilterReference() {
+        return this.numberFilter;
+    }
+
+    public MNumberFilter getNumberFilter() {
+        return this.getNumberFilterReference().clone();
+    }
+
+    /* Validation */
+
+    public void validate() throws MValidationWebException {
+        String text = this.getText();
+        try {
+            this.setText(this.getNumberFilterReference().getValidatedUserNumber(text, null));
+        }
+        catch (MConstraintFilteringException exception) {
+            throw new MValidationWebException(String.format("Invalid number: %s.", text), exception);
+        }
+        catch (MFormatFilteringException exception) {
+            throw new MValidationWebException(String.format("Invalid number: %s.", text), exception);
+        }
+    }
+
+    /* Refresh */
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        String onBlurFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onBlur', {'text': this.value});", this.getId());
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<input type=\"text\" class=\"MWebNumberBox %s\" style=\"display: inline-block;\" onblur=\"%s\" id=\"%s\" />'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onBlurFunction), this.getId()));
+        //
+        super.refresh();
+        //
+        this.refreshText();
+        this.refreshTextAlignment(true);
+        this.refreshEnabledMode();
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebPasswordBox.java b/src/java/com/marcozanon/macaco/web/ui/MWebPasswordBox.java
new file mode 100644 (file)
index 0000000..e7c2a66
--- /dev/null
@@ -0,0 +1,61 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MWebPasswordBox extends MWebTextBox {
+
+    /* */
+
+    public MWebPasswordBox(MWebApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    public MWebPasswordBox(MWebApplicationContext applicationContext, String text) {
+        this(applicationContext);
+        //
+        this.setText(text);
+    }
+
+    /* Refresh */
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        String onBlurFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onBlur', {'text': this.value});", this.getId());
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<input type=\"password\" class=\"MWebPasswordBox %s\" style=\"display: inline-block;\" onblur=\"%s\" id=\"%s\" />'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onBlurFunction), this.getId()));
+        //
+        super.refresh();
+        //
+        this.refreshText();
+        this.refreshTextAlignment(true);
+        this.refreshEnabledMode();
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebRuntimeException.java b/src/java/com/marcozanon/macaco/web/ui/MWebRuntimeException.java
new file mode 100644 (file)
index 0000000..faddbd8
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.MRuntimeException;
+
+public abstract class MWebRuntimeException extends MRuntimeException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MWebRuntimeException() {
+        super();
+    }
+
+    public MWebRuntimeException(String message) {
+        super(message);
+    }
+
+    public MWebRuntimeException(Throwable error) {
+        super(error);
+    }
+
+    public MWebRuntimeException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebSimpleTextBox.java b/src/java/com/marcozanon/macaco/web/ui/MWebSimpleTextBox.java
new file mode 100644 (file)
index 0000000..0912a89
--- /dev/null
@@ -0,0 +1,61 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MWebSimpleTextBox extends MWebTextBox {
+
+    /* */
+
+    public MWebSimpleTextBox(MWebApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    public MWebSimpleTextBox(MWebApplicationContext applicationContext, String text) {
+        this(applicationContext);
+        //
+        this.setText(text);
+    }
+
+    /* Refresh */
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        String onBlurFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onBlur', {'text': this.value});", this.getId());
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<input type=\"text\" class=\"MWebSimpleTextBox %s\" style=\"display: inline-block;\" onblur=\"%s\" id=\"%s\" />'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onBlurFunction), this.getId()));
+        //
+        super.refresh();
+        //
+        this.refreshText();
+        this.refreshTextAlignment(true);
+        this.refreshEnabledMode();
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebString.java b/src/java/com/marcozanon/macaco/web/ui/MWebString.java
new file mode 100644 (file)
index 0000000..f351e32
--- /dev/null
@@ -0,0 +1,421 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.MInformation;
+import com.marcozanon.macaco.MObject;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class MWebString extends MObject {
+
+    /* */
+
+    public MWebString() {
+        super();
+    }
+
+    /* Javascript escape */
+
+    public static String getJavascriptEscapedString(String x) {
+        if (null == x) {
+            return null;
+        }
+        //
+        String text = x;
+        //
+        text = text.replace("\\", "\\\\");
+        text = text.replace("'", "\\\'");
+        //
+        return text;
+    }
+
+    /* Xhtml escape and safety */
+
+    public static String getXhtmlEscapedString(String x) { // similar to PHP's htmlspecialchars()
+        if (null == x) {
+            return null;
+        }
+        //
+        String text = x;
+        //
+        text = text.replace("&", "&amp;");
+        text = text.replace("\"", "&quot;");
+        text = text.replace("'", "&apos;");
+        text = text.replace("<", "&lt;");
+        text = text.replace(">", "&gt;");
+        //
+        text = text.replace("\n", "<br />");
+        //
+        return text;
+    }
+
+    public static String getXhtmlNumericEntitiesString(String x) { // for compatibility with innerHTML
+        if (null == x) {
+            return null;
+        }
+        //
+        String text = x;
+        //
+        text = text.replace("&nbsp;", "&#160;");
+        text = text.replace("&iexcl;", "&#161;");
+        text = text.replace("&cent;", "&#162;");
+        text = text.replace("&pound;", "&#163;");
+        text = text.replace("&curren;", "&#164;");
+        text = text.replace("&yen;", "&#165;");
+        text = text.replace("&brvbar;", "&#166;");
+        text = text.replace("&sect;", "&#167;");
+        text = text.replace("&uml;", "&#168;");
+        text = text.replace("&copy;", "&#169;");
+        text = text.replace("&ordf;", "&#170;");
+        text = text.replace("&laquo;", "&#171;");
+        text = text.replace("&not;", "&#172;");
+        text = text.replace("&shy;", "&#173;");
+        text = text.replace("&reg;", "&#174;");
+        text = text.replace("&macr;", "&#175;");
+        text = text.replace("&deg;", "&#176;");
+        text = text.replace("&plusmn;", "&#177;");
+        text = text.replace("&sup2;", "&#178;");
+        text = text.replace("&sup3;", "&#179;");
+        text = text.replace("&acute;", "&#180;");
+        text = text.replace("&micro;", "&#181;");
+        text = text.replace("&para;", "&#182;");
+        text = text.replace("&middot;", "&#183;");
+        text = text.replace("&cedil;", "&#184;");
+        text = text.replace("&sup1;", "&#185;");
+        text = text.replace("&ordm;", "&#186;");
+        text = text.replace("&raquo;", "&#187;");
+        text = text.replace("&frac14;", "&#188;");
+        text = text.replace("&frac12;", "&#189;");
+        text = text.replace("&frac34;", "&#190;");
+        text = text.replace("&iquest;", "&#191;");
+        text = text.replace("&Agrave;", "&#192;");
+        text = text.replace("&Aacute;", "&#193;");
+        text = text.replace("&Acirc;", "&#194;");
+        text = text.replace("&Atilde;", "&#195;");
+        text = text.replace("&Auml;", "&#196;");
+        text = text.replace("&Aring;", "&#197;");
+        text = text.replace("&AElig;", "&#198;");
+        text = text.replace("&Ccedil;", "&#199;");
+        text = text.replace("&Egrave;", "&#200;");
+        text = text.replace("&Eacute;", "&#201;");
+        text = text.replace("&Ecirc;", "&#202;");
+        text = text.replace("&Euml;", "&#203;");
+        text = text.replace("&Igrave;", "&#204;");
+        text = text.replace("&Iacute;", "&#205;");
+        text = text.replace("&Icirc;", "&#206;");
+        text = text.replace("&Iuml;", "&#207;");
+        text = text.replace("&ETH;", "&#208;");
+        text = text.replace("&Ntilde;", "&#209;");
+        text = text.replace("&Ograve;", "&#210;");
+        text = text.replace("&Oacute;", "&#211;");
+        text = text.replace("&Ocirc;", "&#212;");
+        text = text.replace("&Otilde;", "&#213;");
+        text = text.replace("&Ouml;", "&#214;");
+        text = text.replace("&times;", "&#215;");
+        text = text.replace("&Oslash;", "&#216;");
+        text = text.replace("&Ugrave;", "&#217;");
+        text = text.replace("&Uacute;", "&#218;");
+        text = text.replace("&Ucirc;", "&#219;");
+        text = text.replace("&Uuml;", "&#220;");
+        text = text.replace("&Yacute;", "&#221;");
+        text = text.replace("&THORN;", "&#222;");
+        text = text.replace("&szlig;", "&#223;");
+        text = text.replace("&agrave;", "&#224;");
+        text = text.replace("&aacute;", "&#225;");
+        text = text.replace("&acirc;", "&#226;");
+        text = text.replace("&atilde;", "&#227;");
+        text = text.replace("&auml;", "&#228;");
+        text = text.replace("&aring;", "&#229;");
+        text = text.replace("&aelig;", "&#230;");
+        text = text.replace("&ccedil;", "&#231;");
+        text = text.replace("&egrave;", "&#232;");
+        text = text.replace("&eacute;", "&#233;");
+        text = text.replace("&ecirc;", "&#234;");
+        text = text.replace("&euml;", "&#235;");
+        text = text.replace("&igrave;", "&#236;");
+        text = text.replace("&iacute;", "&#237;");
+        text = text.replace("&icirc;", "&#238;");
+        text = text.replace("&iuml;", "&#239;");
+        text = text.replace("&eth;", "&#240;");
+        text = text.replace("&ntilde;", "&#241;");
+        text = text.replace("&ograve;", "&#242;");
+        text = text.replace("&oacute;", "&#243;");
+        text = text.replace("&ocirc;", "&#244;");
+        text = text.replace("&otilde;", "&#245;");
+        text = text.replace("&ouml;", "&#246;");
+        text = text.replace("&divide;", "&#247;");
+        text = text.replace("&oslash;", "&#248;");
+        text = text.replace("&ugrave;", "&#249;");
+        text = text.replace("&uacute;", "&#250;");
+        text = text.replace("&ucirc;", "&#251;");
+        text = text.replace("&uuml;", "&#252;");
+        text = text.replace("&yacute;", "&#253;");
+        text = text.replace("&thorn;", "&#254;");
+        text = text.replace("&yuml;", "&#255;");
+        text = text.replace("&OElig;", "&#338;");
+        text = text.replace("&oelig;", "&#339;");
+        text = text.replace("&Scaron;", "&#352;");
+        text = text.replace("&scaron;", "&#353;");
+        text = text.replace("&Yuml;", "&#376;");
+        text = text.replace("&fnof;", "&#402;");
+        text = text.replace("&circ;", "&#710;");
+        text = text.replace("&tilde;", "&#732;");
+        text = text.replace("&Alpha;", "&#913;");
+        text = text.replace("&Beta;", "&#914;");
+        text = text.replace("&Gamma;", "&#915;");
+        text = text.replace("&Delta;", "&#916;");
+        text = text.replace("&Epsilon;", "&#917;");
+        text = text.replace("&Zeta;", "&#918;");
+        text = text.replace("&Eta;", "&#919;");
+        text = text.replace("&Theta;", "&#920;");
+        text = text.replace("&Iota;", "&#921;");
+        text = text.replace("&Kappa;", "&#922;");
+        text = text.replace("&Lambda;", "&#923;");
+        text = text.replace("&Mu;", "&#924;");
+        text = text.replace("&Nu;", "&#925;");
+        text = text.replace("&Xi;", "&#926;");
+        text = text.replace("&Omicron;", "&#927;");
+        text = text.replace("&Pi;", "&#928;");
+        text = text.replace("&Rho;", "&#929;");
+        text = text.replace("&Sigma;", "&#931;");
+        text = text.replace("&Tau;", "&#932;");
+        text = text.replace("&Upsilon;", "&#933;");
+        text = text.replace("&Phi;", "&#934;");
+        text = text.replace("&Chi;", "&#935;");
+        text = text.replace("&Psi;", "&#936;");
+        text = text.replace("&Omega;", "&#937;");
+        text = text.replace("&alpha;", "&#945;");
+        text = text.replace("&beta;", "&#946;");
+        text = text.replace("&gamma;", "&#947;");
+        text = text.replace("&delta;", "&#948;");
+        text = text.replace("&epsilon;", "&#949;");
+        text = text.replace("&zeta;", "&#950;");
+        text = text.replace("&eta;", "&#951;");
+        text = text.replace("&theta;", "&#952;");
+        text = text.replace("&iota;", "&#953;");
+        text = text.replace("&kappa;", "&#954;");
+        text = text.replace("&lambda;", "&#955;");
+        text = text.replace("&mu;", "&#956;");
+        text = text.replace("&nu;", "&#957;");
+        text = text.replace("&xi;", "&#958;");
+        text = text.replace("&omicron;", "&#959;");
+        text = text.replace("&pi;", "&#960;");
+        text = text.replace("&rho;", "&#961;");
+        text = text.replace("&sigmaf;", "&#962;");
+        text = text.replace("&sigma;", "&#963;");
+        text = text.replace("&tau;", "&#964;");
+        text = text.replace("&upsilon;", "&#965;");
+        text = text.replace("&phi;", "&#966;");
+        text = text.replace("&chi;", "&#967;");
+        text = text.replace("&psi;", "&#968;");
+        text = text.replace("&omega;", "&#969;");
+        text = text.replace("&thetasym;", "&#977;");
+        text = text.replace("&upsih;", "&#978;");
+        text = text.replace("&piv;", "&#982;");
+        text = text.replace("&ensp;", "&#8194;");
+        text = text.replace("&emsp;", "&#8195;");
+        text = text.replace("&thinsp;", "&#8201;");
+        text = text.replace("&zwnj;", "&#8204;");
+        text = text.replace("&zwj;", "&#8205;");
+        text = text.replace("&lrm;", "&#8206;");
+        text = text.replace("&rlm;", "&#8207;");
+        text = text.replace("&ndash;", "&#8211;");
+        text = text.replace("&mdash;", "&#8212;");
+        text = text.replace("&lsquo;", "&#8216;");
+        text = text.replace("&rsquo;", "&#8217;");
+        text = text.replace("&sbquo;", "&#8218;");
+        text = text.replace("&ldquo;", "&#8220;");
+        text = text.replace("&rdquo;", "&#8221;");
+        text = text.replace("&bdquo;", "&#8222;");
+        text = text.replace("&dagger;", "&#8224;");
+        text = text.replace("&Dagger;", "&#8225;");
+        text = text.replace("&bull;", "&#8226;");
+        text = text.replace("&hellip;", "&#8230;");
+        text = text.replace("&permil;", "&#8240;");
+        text = text.replace("&prime;", "&#8242;");
+        text = text.replace("&Prime;", "&#8243;");
+        text = text.replace("&lsaquo;", "&#8249;");
+        text = text.replace("&rsaquo;", "&#8250;");
+        text = text.replace("&oline;", "&#8254;");
+        text = text.replace("&frasl;", "&#8260;");
+        text = text.replace("&euro;", "&#8364;");
+        text = text.replace("&image;", "&#8465;");
+        text = text.replace("&weierp;", "&#8472;");
+        text = text.replace("&real;", "&#8476;");
+        text = text.replace("&trade;", "&#8482;");
+        text = text.replace("&alefsym;", "&#8501;");
+        text = text.replace("&larr;", "&#8592;");
+        text = text.replace("&uarr;", "&#8593;");
+        text = text.replace("&rarr;", "&#8594;");
+        text = text.replace("&darr;", "&#8595;");
+        text = text.replace("&harr;", "&#8596;");
+        text = text.replace("&crarr;", "&#8629;");
+        text = text.replace("&lArr;", "&#8656;");
+        text = text.replace("&uArr;", "&#8657;");
+        text = text.replace("&rArr;", "&#8658;");
+        text = text.replace("&dArr;", "&#8659;");
+        text = text.replace("&hArr;", "&#8660;");
+        text = text.replace("&forall;", "&#8704;");
+        text = text.replace("&part;", "&#8706;");
+        text = text.replace("&exist;", "&#8707;");
+        text = text.replace("&empty;", "&#8709;");
+        text = text.replace("&nabla;", "&#8711;");
+        text = text.replace("&isin;", "&#8712;");
+        text = text.replace("&notin;", "&#8713;");
+        text = text.replace("&ni;", "&#8715;");
+        text = text.replace("&prod;", "&#8719;");
+        text = text.replace("&sum;", "&#8721;");
+        text = text.replace("&minus;", "&#8722;");
+        text = text.replace("&lowast;", "&#8727;");
+        text = text.replace("&radic;", "&#8730;");
+        text = text.replace("&prop;", "&#8733;");
+        text = text.replace("&infin;", "&#8734;");
+        text = text.replace("&ang;", "&#8736;");
+        text = text.replace("&and;", "&#8743;");
+        text = text.replace("&or;", "&#8744;");
+        text = text.replace("&cap;", "&#8745;");
+        text = text.replace("&cup;", "&#8746;");
+        text = text.replace("&int;", "&#8747;");
+        text = text.replace("&there4;", "&#8756;");
+        text = text.replace("&sim;", "&#8764;");
+        text = text.replace("&cong;", "&#8773;");
+        text = text.replace("&asymp;", "&#8776;");
+        text = text.replace("&ne;", "&#8800;");
+        text = text.replace("&equiv;", "&#8801;");
+        text = text.replace("&le;", "&#8804;");
+        text = text.replace("&ge;", "&#8805;");
+        text = text.replace("&sub;", "&#8834;");
+        text = text.replace("&sup;", "&#8835;");
+        text = text.replace("&nsub;", "&#8836;");
+        text = text.replace("&sube;", "&#8838;");
+        text = text.replace("&supe;", "&#8839;");
+        text = text.replace("&oplus;", "&#8853;");
+        text = text.replace("&otimes;", "&#8855;");
+        text = text.replace("&perp;", "&#8869;");
+        text = text.replace("&sdot;", "&#8901;");
+        text = text.replace("&lceil;", "&#8968;");
+        text = text.replace("&rceil;", "&#8969;");
+        text = text.replace("&lfloor;", "&#8970;");
+        text = text.replace("&rfloor;", "&#8971;");
+        text = text.replace("&lang;", "&#9001;");
+        text = text.replace("&rang;", "&#9002;");
+        text = text.replace("&loz;", "&#9674;");
+        text = text.replace("&spades;", "&#9824;");
+        text = text.replace("&clubs;", "&#9827;");
+        text = text.replace("&hearts;", "&#9829;");
+        text = text.replace("&diams;", "&#9830;");
+        //
+        return text;
+    }
+
+    public static String getXhtmlSafeString(String x) throws MXhtmlUnsafeStringWebException {
+        if (null == x) {
+            return null;
+        }
+        //
+        String text = x;
+        //
+        StringBuilder fakeXhtmlPageContent = new StringBuilder("");
+        fakeXhtmlPageContent.append(String.format("<?xml version=\"1.0\" encoding=\"%s\" ?>", MInformation.TEXT_ENCODING));
+        fakeXhtmlPageContent.append("<!DOCTYPE html SYSTEM \"fake-dtd\" >");
+        fakeXhtmlPageContent.append("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
+        fakeXhtmlPageContent.append("<head><title /></head>");
+        fakeXhtmlPageContent.append(String.format("<body>%s</body>", text));
+        fakeXhtmlPageContent.append("</html>");
+        // validate Xhtml (without dangerous tags and event attributes)
+        try {
+            SAXParserFactory factory = SAXParserFactory.newInstance();
+            factory.setValidating(true);
+            factory.setNamespaceAware(true);
+            SAXParser parser = factory.newSAXParser();
+            XMLReader reader = parser.getXMLReader();
+            reader.setEntityResolver(new EntityResolver() {
+
+                public InputSource resolveEntity(String publicId, String systemId) {
+                    return new InputSource(new BufferedInputStream(this.getClass().getClassLoader().getResourceAsStream("dtd/xhtml1-transitional-macaco-edit.dtd")));
+                }
+
+            });
+            reader.setContentHandler(new DefaultHandler() {
+
+                public void startElement(String namespaceUri, String strippedName, String tagName, Attributes attributes) throws SAXException {
+                    if ("script".equalsIgnoreCase(tagName)) {
+                        throw new SAXException(String.format("Tag not allowed: %s.", tagName));
+                    }
+                    for (int a = 0; a < attributes.getLength(); a++) {
+                        if (attributes.getLocalName(a).toLowerCase().startsWith("on")) {
+                            throw new SAXException(String.format("Attribute not allowed: %s.", attributes.getLocalName(a)));
+                        }
+                    }
+                }
+
+            });
+            reader.setErrorHandler(new ErrorHandler() {
+
+                public void error(SAXParseException exception) throws SAXException {
+                    throw new SAXException(exception);
+                }
+
+                public void fatalError(SAXParseException exception) throws SAXException {
+                    throw new SAXException(exception);
+                }
+
+                public void warning(SAXParseException exception) throws SAXException {
+                    throw new SAXException(exception);
+                }
+
+            });
+            //
+            reader.parse(new InputSource(new ByteArrayInputStream(fakeXhtmlPageContent.toString().getBytes(MInformation.TEXT_ENCODING))));
+        }
+        catch (ParserConfigurationException exception) { // cannot happen
+        }
+        catch (SAXException exception) {
+            throw new MXhtmlUnsafeStringWebException("Invalid 'x': unsafe tags or attributes inside.", exception);
+        }
+        catch (UnsupportedEncodingException exception) { // cannot happen
+        }
+        catch (IOException exception) { // cannot happen, put here not to bypass UnsupportedEncodingException
+        }
+        // also convert named entities to numeric entities
+        return MWebString.getXhtmlNumericEntitiesString(text);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebTable.java b/src/java/com/marcozanon/macaco/web/ui/MWebTable.java
new file mode 100644 (file)
index 0000000..9494f6e
--- /dev/null
@@ -0,0 +1,755 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+
+public abstract class MWebTable extends MWebDirectWidget {
+
+    protected LinkedHashMap<String, MWebTableCell> columnHeaders = null;
+
+    protected String primaryKey = null;
+
+    protected String sortKey = null;
+    protected boolean ascendingSortMode = true;
+
+    protected int rowsPerPage = 10;
+    protected Integer selectedPage = null;
+
+    protected int rowCount = 0;
+    protected LinkedHashMap<String, LinkedHashMap<String, MWebTableCell>> rowSubset = new LinkedHashMap<String, LinkedHashMap<String, MWebTableCell>>();
+
+    protected boolean selectableRowMode = false;
+    protected LinkedHashSet<String> selectedRowKeys = new LinkedHashSet<String>();
+
+    /* */
+
+    public MWebTable(MWebApplicationContext applicationContext, LinkedHashMap<String, MWebTableCell> columnHeaders, String primaryKey) {
+        super(applicationContext);
+        //
+        if (null == columnHeaders) {
+            throw new IllegalArgumentException("Invalid 'columnHeaders': null.");
+        }
+        else {
+            for (String columnKey: columnHeaders.keySet()) {
+                if ((null == columnKey) || ("".equals(columnKey))) {
+                    throw new IllegalArgumentException("Invalid 'columnHeaders': column key null or empty.");
+                }
+                else if (null == columnHeaders.get(columnKey)) {
+                    throw new IllegalArgumentException("Invalid 'columnHeaders': table cell null.");
+                }
+            }
+        }
+        if ((null == primaryKey) || ("".equals(primaryKey))) {
+            throw new IllegalArgumentException("Invalid 'primaryKey': null or empty.");
+        }
+        //
+        this.columnHeaders = columnHeaders;
+        this.primaryKey = primaryKey;
+    }
+
+    /* Column headers */
+
+    protected LinkedHashMap<String, MWebTableCell> getColumnHeadersReference() {
+        return this.columnHeaders;
+    }
+
+    public LinkedHashMap<String, MWebTableCell> getColumnHeaders() {
+        LinkedHashMap<String, MWebTableCell> tmpColumnHeaders = new LinkedHashMap<String, MWebTableCell>();
+        for (String key: this.getColumnHeadersReference().keySet()) {
+            tmpColumnHeaders.put(key, this.getColumnHeadersReference().get(key).clone());
+        }
+        return tmpColumnHeaders;
+    }
+
+    public LinkedHashSet<String> getColumnHeaderKeys() {
+        LinkedHashSet<String> tmpColumnHeaderKeys = new LinkedHashSet<String>();
+        Iterator i = this.getColumnHeadersReference().keySet().iterator();
+        while (i.hasNext()) {
+            tmpColumnHeaderKeys.add((String)i.next());
+        }
+        return tmpColumnHeaderKeys;
+    }
+
+    /* Primary key */
+
+    public String getPrimaryKey() {
+        return this.primaryKey;
+    }
+
+    /* Sorting */
+
+    public void setSortKey(String sortKey, boolean ascendingSortMode) {
+        this.setSortKey(sortKey, ascendingSortMode, true);
+    }
+
+    protected void setSortKey(String sortKey, boolean ascendingSortMode, boolean refreshMode) {
+        if ("".equals(sortKey)) {
+            throw new IllegalArgumentException("Invalid 'sortKey': empty.");
+        }
+        //
+        if (null == sortKey) {
+            this.sortKey = null;
+            this.ascendingSortMode = true;
+        }
+        else {
+            this.sortKey = sortKey;
+            this.ascendingSortMode = ascendingSortMode;
+        }
+        //
+        if (refreshMode) {
+            try {
+                this.refresh(); // must refresh everything
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+            catch (MUniqueWidgetIdNotAvailableWebException exception) {
+            }
+        }
+    }
+
+    public String getSortKey() {
+        return this.sortKey;
+    }
+
+    public boolean getAscendingSortMode() {
+        return this.ascendingSortMode;
+    }
+
+    /* Page selection */
+
+    public void setRowsPerPage(int rowsPerPage) {
+        this.setRowsPerPage(rowsPerPage, true);
+    }
+
+    protected void setRowsPerPage(int rowsPerPage, boolean refreshMode) {
+        if (rowsPerPage < 1) {
+            throw new IllegalArgumentException(String.format("Invalid 'rowsPerPage': %s: must be positive.", rowsPerPage));
+        }
+        //
+        this.rowsPerPage = rowsPerPage;
+        //
+        if (refreshMode) {
+            try {
+                this.refresh(); // must refresh everything
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+            catch (MUniqueWidgetIdNotAvailableWebException exception) {
+            }
+        }
+    }
+
+    public int getRowsPerPage() {
+        return this.rowsPerPage;
+    }
+
+    public void setSelectedPage(Integer selectedPage) {
+        this.setSelectedPage(selectedPage, true);
+    }
+
+    protected void setSelectedPage(Integer selectedPage, boolean refreshMode) {
+        if ((0 == this.getRowCount()) && (null != selectedPage)) {
+            this.selectedPage = 1;
+            return;
+        }
+        else if ((null != selectedPage) && ((selectedPage < 1) || (selectedPage > (int)Math.ceil((float)this.getRowCount() / (float)this.getRowsPerPage())))) {
+            throw new IllegalArgumentException(String.format("Invalid 'selectedPage': %s: out of range.", selectedPage));
+        }
+        //
+        this.clearSelectedRowKeys();
+        //
+        this.selectedPage = selectedPage;
+        //
+        if (refreshMode) {
+            try {
+                this.refresh(); // must refresh everything
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+            catch (MUniqueWidgetIdNotAvailableWebException exception) {
+            }
+        }
+    }
+
+    public Integer getSelectedPage() {
+        return this.selectedPage;
+    }
+
+    protected void resetSelectedPage() {
+        Integer selectedPage = this.getSelectedPage();
+        if (null == selectedPage) {
+            return;
+        }
+        else if (0 == this.getRowCount()) {
+            this.setSelectedPage(null);
+        }
+        else if (selectedPage < 1) {
+            this.setSelectedPage(1);
+        }
+        else if (selectedPage > (int)Math.ceil((float)this.getRowCount() / (float)this.getRowsPerPage())) {
+            this.setSelectedPage((int)Math.ceil((float)this.getRowCount() / (float)this.getRowsPerPage()));
+        }
+    }
+
+    /* Rows */
+
+    public void loadRows(LinkedList<LinkedHashMap<String, String>> rows) throws MUniqueWidgetIdNotAvailableWebException {
+        this.loadRows(rows, true);
+    }
+
+    protected void loadRows(LinkedList<LinkedHashMap<String, String>> rows, boolean refreshMode) throws MUniqueWidgetIdNotAvailableWebException {
+        if (null == rows) {
+            throw new IllegalArgumentException("Invalid 'rows': null.");
+        }
+        else {
+            for (LinkedHashMap<String, String> row: rows) {
+                if (null == row) {
+                    throw new IllegalArgumentException("Invalid 'rows': row null.");
+                }
+                for (String columnKey: row.keySet()) {
+                    if ((null == columnKey) || ("".equals(columnKey))) {
+                        throw new IllegalArgumentException("Invalid 'rows': column key null or empty.");
+                    }
+                }
+            }
+        }
+        //
+        this.rowCount = rows.size();
+        this.resetSelectedPage();
+        //
+        int firstRow = 0;
+        int lastRow = this.getRowCount() - 1;
+        Integer selectedPage = this.getSelectedPage();
+        if (null != selectedPage) {
+            firstRow = (selectedPage - 1) * this.getRowsPerPage();
+            lastRow = Math.min((selectedPage * this.getRowsPerPage()) - 1, lastRow);
+        }
+        LinkedList<LinkedHashMap<String, String>> tmpRowSubset = new LinkedList<LinkedHashMap<String, String>>();
+        for (int r = firstRow; r < (lastRow + 1); r++) {
+            tmpRowSubset.add(rows.get(r));
+        }
+        LinkedHashMap<String, MWebTableCell> columnHeaders = this.getColumnHeadersReference();
+        LinkedHashMap<String, LinkedHashMap<String, MWebTableCell>> rowSubset = new LinkedHashMap<String, LinkedHashMap<String, MWebTableCell>>();
+        for (LinkedHashMap<String, String> tmpRow: tmpRowSubset) {
+            String primaryKeyValue = tmpRow.get(this.getPrimaryKey());
+            if (null == primaryKeyValue) {
+                throw new IllegalArgumentException("Invalid row: primary key value null.");
+            }
+            LinkedHashMap<String, MWebTableCell> row = new LinkedHashMap<String, MWebTableCell>();
+            for (String columnKey: columnHeaders.keySet()) {
+                String text = null;
+                if (null == tmpRow.get(columnKey)) {
+                    text = "";
+                }
+                else {
+                    text = tmpRow.get(columnKey);
+                }
+                row.put(columnKey, new MWebTableCell(this.getApplicationContextReference(), text, null, null));
+            }
+            rowSubset.put(primaryKeyValue, row);
+        }
+        //
+        for (LinkedHashMap<String, MWebTableCell> row: this.getRowSubsetReference().values()) {
+            for (MWebTableCell rowCell: row.values()) {
+                try {
+                    rowCell.setView(null);
+                }
+                catch (MUniqueWidgetIdNotAvailableWebException exception) { // cannot happen
+                }
+            }
+        }
+        //
+        this.rowSubset = rowSubset;
+        //
+        for (LinkedHashMap<String, MWebTableCell> row: this.getRowSubsetReference().values()) {
+            for (MWebTableCell rowCell: row.values()) {
+                try {
+                    rowCell.setView(this.getViewReference());
+                }
+                catch (MNoViewWebException exception) {
+                }
+            }
+        }
+        //
+        if (refreshMode) {
+            try {
+                this.refresh(); // must refresh everything
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public int getRowCount() {
+        return this.rowCount;
+    }
+
+    protected LinkedHashMap<String, LinkedHashMap<String, MWebTableCell>> getRowSubsetReference() {
+        return this.rowSubset;
+    }
+
+    public LinkedHashMap<String, LinkedHashMap<String, MWebTableCell>> getRowSubset() {
+        LinkedHashMap<String, LinkedHashMap<String, MWebTableCell>> tmpRowSubset = new LinkedHashMap<String, LinkedHashMap<String, MWebTableCell>>();
+        for (String rowKey: this.getRowSubsetReference().keySet()) {
+            LinkedHashMap<String, MWebTableCell> tmpRow = new LinkedHashMap<String, MWebTableCell>();
+            for (String columnKey: this.getRowSubsetReference().get(rowKey).keySet()) {
+                tmpRow.put(columnKey, this.getRowSubsetReference().get(rowKey).get(columnKey).clone());
+            }
+            tmpRowSubset.put(rowKey, tmpRow);
+        }
+        return tmpRowSubset;
+    }
+
+    public LinkedHashSet<String> getRowSubsetKeys() {
+        LinkedHashSet<String> tmpRowSubsetKeys = new LinkedHashSet<String>();
+        Iterator i = this.getRowSubsetReference().keySet().iterator();
+        while (i.hasNext()) {
+            tmpRowSubsetKeys.add((String)i.next());
+        }
+        return tmpRowSubsetKeys;
+    }
+
+    /* Row selection */
+
+    public void setSelectableRowMode(boolean selectableRowMode) {
+        this.setSelectableRowMode(selectableRowMode, true);
+    }
+
+    protected void setSelectableRowMode(boolean selectableRowMode, boolean refreshMode) {
+        if (!selectableRowMode) {
+            this.clearSelectedRowKeys();
+        }
+        this.selectableRowMode = selectableRowMode;
+        //
+        if (refreshMode) {
+            try {
+                this.refresh(); // must refresh everything
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+            catch (MUniqueWidgetIdNotAvailableWebException exception) {
+            }
+        }
+    }
+
+    public boolean getSelectableRowMode() {
+        return this.selectableRowMode;
+    }
+
+    protected LinkedHashSet<String> getSelectedRowKeysReference() {
+        return this.selectedRowKeys;
+    }
+
+    public LinkedHashSet<String> getSelectedRowKeys() {
+        LinkedHashSet<String> tmpSelectedRowKeys = new LinkedHashSet<String>();
+        Iterator i = this.getSelectedRowKeysReference().iterator();
+        while (i.hasNext()) {
+            tmpSelectedRowKeys.add((String)i.next());
+        }
+        return tmpSelectedRowKeys;
+    }
+
+    protected void clearSelectedRowKeys() {
+        this.getSelectedRowKeysReference().clear();
+    }
+
+    public void setRowSelectedMode(String primaryKeyValue, boolean selectedMode) {
+        this.setRowSelectedMode(primaryKeyValue, selectedMode, true);
+    }
+
+    protected void setRowSelectedMode(String primaryKeyValue, boolean selectedMode, boolean refreshMode) {
+        if ((null == primaryKeyValue) || ("".equals(primaryKeyValue))) {
+            throw new IllegalArgumentException("Invalid 'primaryKeyValue': null or empty.");
+        }
+        //
+        if (selectedMode) {
+            this.getSelectedRowKeysReference().add(primaryKeyValue);
+        }
+        else {
+            this.getSelectedRowKeysReference().remove(primaryKeyValue);
+        }
+        //
+        if (refreshMode) {
+            try {
+                this.refresh(); // must refresh everything
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+            catch (MUniqueWidgetIdNotAvailableWebException exception) {
+            }
+        }
+    }
+
+    public boolean getRowSelectedMode(String primaryKeyValue) {
+        if ((null == primaryKeyValue) || ("".equals(primaryKeyValue))) {
+            throw new IllegalArgumentException("Invalid 'primaryKeyValue': null or empty.");
+        }
+        //
+        return this.getSelectedRowKeys().contains(primaryKeyValue);
+    }
+
+    public boolean getRowSubsetSelectedMode() {
+        return this.getSelectedRowKeysReference().size() == this.getRowSubsetReference().size();
+    }
+
+    public void toggleRowSubsetSelectedMode() {
+        this.toggleRowSubsetSelectedMode(true);
+    }
+
+    protected void toggleRowSubsetSelectedMode(boolean refreshMode) {
+        if (this.getRowSubsetSelectedMode()) {
+            this.clearSelectedRowKeys();
+        }
+        else {
+            this.clearSelectedRowKeys();
+            for (String primaryKeyValue: this.getRowSubsetReference().keySet()) {
+                this.setRowSelectedMode(primaryKeyValue, true, false);
+            }
+        }
+        //
+        if (refreshMode) {
+            try {
+                this.refresh(); // must refresh everything
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+            catch (MUniqueWidgetIdNotAvailableWebException exception) {
+            }
+        }
+    }
+
+    /* View */
+
+    protected void setView(MWebView view) throws MUniqueWidgetIdNotAvailableWebException {
+        super.setView(view);
+        //
+        for (MWebTableCell cell: this.getColumnHeadersReference().values()) {
+            cell.setView(view);
+        }
+        //
+        for (LinkedHashMap<String, MWebTableCell> row: this.getRowSubsetReference().values()) {
+            for (MWebTableCell rowCell: row.values()) {
+                rowCell.setView(view);
+            }
+        }
+    }
+
+    /* Display widgets */
+
+    protected MWebDisplayWidget getDisplayWidgetReferenceById(String id) throws MDisplayWidgetNotFoundWebException {
+        try {
+            return super.getDisplayWidgetReferenceById(id);
+        }
+        catch (MDisplayWidgetNotFoundWebException exception) {
+            for (MWebTableCell columnHeadersCell: this.getColumnHeadersReference().values()) {
+                try {
+                    return columnHeadersCell.getDisplayWidgetReferenceById(id);
+                }
+                catch (MDisplayWidgetNotFoundWebException exception2) {
+                }
+            }
+            for (LinkedHashMap<String, MWebTableCell> row: this.getRowSubsetReference().values()) {
+                for (MWebTableCell rowCell: row.values()) {
+                    try {
+                        return rowCell.getDisplayWidgetReferenceById(id);
+                    }
+                    catch (MDisplayWidgetNotFoundWebException exception2) {
+                    }
+                }
+            }
+            throw new MDisplayWidgetNotFoundWebException(String.format("Invalid 'id': %s: display widget not available on this path.", id)); // no need to propagate exception
+        }
+    }
+
+    /* Refresh */
+
+    protected void customizeRowSubset() {
+    }
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        StringBuilder content = new StringBuilder("");
+        LinkedHashMap<String, MWebTableCell> columnHeaders = this.getColumnHeadersReference();
+        Integer selectedPage = this.getSelectedPage();
+        LinkedHashMap<String, LinkedHashMap<String, MWebTableCell>> rowSubset = this.getRowSubsetReference();
+        content.append(String.format("<table class=\"MWebTable %s\" style=\"display: inline-table;\" id=\"%s\">", customClasses, this.getId()));
+        //
+        content.append(String.format("<tr class=\"MWebTableColumnHeaderRow %s\">", customClasses));
+        if (this.getSelectableRowMode()) {
+            String onRowSubsetSelectedModeToggleFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onRowSubsetSelectedModeToggle', {});", this.getId());
+            content.append(String.format("<th class=\"MWebTableColumnHeaderRowSelectionCell %s\"><input type=\"checkbox\" class=\"MWebTableColumnHeaderRowSelector %s\" onclick=\"%s\" /></th>", customClasses, customClasses, onRowSubsetSelectedModeToggleFunction));
+        }
+        for (String columnKey: columnHeaders.keySet()) {
+            String onSortFunction = "";
+            if (!"".equals(columnHeaders.get(columnKey).getText())) {
+                onSortFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onSort', {'sortKey': '%s'});", this.getId(), MWebString.getJavascriptEscapedString(columnKey));
+            }
+            content.append(String.format("<th class=\"MWebTableColumnHeaderCell %s\" onclick=\"%s\" id=\"%s\"></th>", customClasses, MWebString.getXhtmlEscapedString(onSortFunction), columnHeaders.get(columnKey).getId()));
+        }
+        content.append("</tr>");
+        //
+        for (String primaryKeyValue: rowSubset.keySet()) {
+            content.append(String.format("<tr class=\"MWebTableRow %s\">", customClasses));
+            if (this.getSelectableRowMode()) {
+                String onRowSelectedModeToggleFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onRowSelectedModeToggle', {'primaryKeyValue': '%s'});", this.getId(), MWebString.getJavascriptEscapedString(primaryKeyValue));
+                String checkedMode = "";
+                if (this.getRowSelectedMode(primaryKeyValue)) {
+                    checkedMode = "checked=\"checked\"";
+                }
+                content.append(String.format("<th class=\"MWebTableRowSelectionCell %s\"><input type=\"checkbox\" class=\"MWebTableRowSelector %s\" onclick=\"%s\" %s /></th>", customClasses, customClasses, MWebString.getXhtmlEscapedString(onRowSelectedModeToggleFunction), checkedMode));
+            }
+            for (String columnKey: rowSubset.get(primaryKeyValue).keySet()) {
+                String onCellClickFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onCellClick', {'primaryKeyValue': '%s', 'columnKey': '%s'});", this.getId(), MWebString.getJavascriptEscapedString(primaryKeyValue), MWebString.getJavascriptEscapedString(columnKey));
+                content.append(String.format("<td class=\"MWebTableCell %s\" onclick=\"%s\" id=\"%s\"></td>", customClasses, MWebString.getXhtmlEscapedString(onCellClickFunction), rowSubset.get(primaryKeyValue).get(columnKey).getId()));
+            }
+            content.append("</tr>");
+        }
+        //
+        content.append(String.format("<tr class=\"MWebTablePageChangerRow %s\">", customClasses));
+        int columnSpan = columnHeaders.size();
+        if (this.getSelectableRowMode()) {
+            columnSpan++;
+        }
+        String onPageSelectionFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onPageSelection', {'selectedPage': this.value});", this.getId());
+        content.append(String.format("<td class=\"MWebTablePageChangerCell %s\" colspan=\"%s\"><select class=\"MWebTablePageChanger %s\" onchange=\"%s\">", customClasses, columnSpan, customClasses, onPageSelectionFunction));
+        String selectedMode = "";
+        if (null == selectedPage) {
+            selectedMode = "selected=\"selected\"";
+        }
+        content.append(String.format("<option value=\"\" %s>*</option>", selectedMode));
+        int rowCount = this.getRowCount();
+        int rowsPerPage = this.getRowsPerPage();
+        if (rowCount > 0) {
+            int p = 0;
+            int firstRow = 0;
+            int lastRow = 0;
+            for (p = 1; p <= (int)Math.ceil((float)rowCount / (float)rowsPerPage); p++) {
+                firstRow = (p - 1) * rowsPerPage;
+                lastRow = Math.min((p * rowsPerPage) - 1, rowCount - 1);
+                if ((null != selectedPage) && (selectedPage.intValue() == p)) {
+                    selectedMode = "selected=\"selected\"";
+                }
+                else {
+                    selectedMode = "";
+                }
+                content.append(String.format("<option value=\"%s\" %s>%s (%s - %s)</option>", p, selectedMode, p, (firstRow + 1), (lastRow + 1)));
+            }
+        }
+        content.append("</select></td>");
+        content.append("</tr>");
+        //
+        content.append("</table>");
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(content.toString())));
+        //
+        String sortKey = this.getSortKey();
+        for (String columnKey: columnHeaders.keySet()) {
+            MWebTableCell columnHeaderCell = columnHeaders.get(columnKey);
+            columnHeaderCell.onRefresh();
+            String sortIndicator = "";
+            if (columnKey.equals(sortKey)) {
+                if (true == this.getAscendingSortMode()) {
+                    sortIndicator = "+";
+                }
+                else {
+                    sortIndicator = "-";
+                }
+            }
+            else {
+                sortIndicator = "";
+            }
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '%s<br />' + $('%s').innerHTML; }", this.getId(), columnHeaderCell.getId(), sortIndicator, columnHeaderCell.getId()));
+        }
+        //
+        this.customizeRowSubset();
+        //
+        for (LinkedHashMap<String, MWebTableCell> row: rowSubset.values()) {
+            for (MWebTableCell rowCell: row.values()) {
+                rowCell.onRefresh();
+            }
+        }
+        //
+        super.refresh();
+    }
+
+    /* Messages */
+
+    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
+        super.processMessage(event, parameters);
+        //
+        if ("onCellClick".equals(event)) {
+            if (!this.getVisibleMode()) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
+            }
+            String primaryKeyValue = parameters.get("primaryKeyValue");
+            String columnKey = parameters.get("columnKey");
+            if (null == primaryKeyValue) {
+                throw new MUnexpectedMessageWebException("Invalid message: primary key value parameter not available.");
+            }
+            else if (!this.getRowSubsetKeys().contains(primaryKeyValue)) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: primary key value parameter not recognized.", primaryKeyValue));
+            }
+            if (null == columnKey) {
+                throw new MUnexpectedMessageWebException("Invalid message: column key parameter not available.");
+            }
+            else if (!this.getColumnHeaderKeys().contains(columnKey)) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: column key parameter not recognized.", columnKey));
+            }
+            this.onCellClick(primaryKeyValue, columnKey);
+        }
+        else if ("onPageSelection".equals(event)) {
+            if (!this.getVisibleMode()) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
+            }
+            String selectedPage = parameters.get("selectedPage");
+            if (null == selectedPage) {
+                throw new MUnexpectedMessageWebException("Invalid message: selected page parameter not available.");
+            }
+            else if ((!"".equals(selectedPage)) && ((Integer.parseInt(selectedPage) < 1) || (Integer.parseInt(selectedPage) > (int)Math.ceil((float)this.getRowCount() / (float)this.getRowsPerPage())))) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: selected page parameter out of range.", selectedPage));
+            }
+            this.onPageSelection(selectedPage);
+        }
+        else if ("onRefresh".equals(event)) {
+            this.onRefresh();
+        }
+        else if ("onRowSelectedModeToggle".equals(event)) {
+            if (!this.getVisibleMode()) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
+            }
+            String primaryKeyValue = parameters.get("primaryKeyValue");
+            if (null == primaryKeyValue) {
+                throw new MUnexpectedMessageWebException("Invalid message: primary key value parameter not available.");
+            }
+            else if (!this.getRowSubsetKeys().contains(primaryKeyValue)) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: primary key value parameter not recognized.", primaryKeyValue));
+            }
+            this.onRowSelectedModeToggle(primaryKeyValue);
+        }
+        else if ("onRowSubsetSelectedModeToggle".equals(event)) {
+            if (!this.getVisibleMode()) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
+            }
+            this.onRowSubsetSelectedModeToggle();
+        }
+        else if ("onSort".equals(event)) {
+            if (!this.getVisibleMode()) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
+            }
+            String sortKey = parameters.get("sortKey");
+            if (null == sortKey) {
+                throw new MUnexpectedMessageWebException("Invalid message: sort key parameter not available.");
+            }
+            else if (!this.getColumnHeaderKeys().contains(sortKey)) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: sort key parameter not recognized.", sortKey));
+            }
+            this.onSort(sortKey);
+        }
+        else {
+            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
+        }
+    }
+
+    public void onCellClick(String primaryKeyValue, String columnKey) {
+    }
+
+    public void onPageSelection(String selectedPage) {
+        if ("".equals(selectedPage)) {
+            this.setSelectedPage(null);
+        }
+        else {
+            this.setSelectedPage(new Integer(selectedPage));
+        }
+    }
+
+    public void onRowSelectedModeToggle(String primaryKeyValue) {
+        this.setRowSelectedMode(primaryKeyValue, !this.getRowSelectedMode(primaryKeyValue));
+    }
+
+    public void onRowSubsetSelectedModeToggle() {
+        this.toggleRowSubsetSelectedMode();
+    }
+
+    public void onSort(String sortKey) {
+        if (sortKey.equals(this.getSortKey())) {
+            this.setSortKey(sortKey, !this.getAscendingSortMode());
+        }
+        else {
+            this.setSortKey(sortKey, true);
+        }
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebTableCell.java b/src/java/com/marcozanon/macaco/web/ui/MWebTableCell.java
new file mode 100644 (file)
index 0000000..f74487f
--- /dev/null
@@ -0,0 +1,190 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import java.util.LinkedHashMap;
+
+public class MWebTableCell extends MWebCellWidget {
+
+    protected String text = "";
+    protected String imageSource = null;
+    protected String externalLinkPrefix = null;
+
+    /* */
+
+    public MWebTableCell(MWebApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    public MWebTableCell(MWebApplicationContext applicationContext, String text, String imageSource, String externalLinkPrefix) {
+        this(applicationContext);
+        //
+        this.setText(text);
+        this.setImageSource(imageSource);
+        this.setExternalLinkPrefix(externalLinkPrefix);
+    }
+
+    public MWebTableCell clone() {
+        MWebTableCell tableCell = new MWebTableCell(this.getApplicationContextReference(), this.getText(), this.getImageSource(), this.getExternalLinkPrefix());
+        this.cloneCellWidgetProperties(tableCell);
+        return tableCell;
+    }
+
+    /* Text */
+
+    public void setText(String text) {
+        this.setText(text, true);
+    }
+
+    protected void setText(String text, boolean refreshMode) {
+        if (null == text) {
+            throw new IllegalArgumentException("Invalid 'text': null.");
+        }
+        //
+        this.text = text;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshContent();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public String getText() {
+        return this.text;
+    }
+
+    /* Image source */
+
+    public void setImageSource(String imageSource) {
+        this.setImageSource(imageSource, true);
+    }
+
+    protected void setImageSource(String imageSource, boolean refreshMode) {
+        this.imageSource = imageSource;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshContent();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public String getImageSource() {
+        return this.imageSource;
+    }
+
+    /* External link prefix */
+
+    public void setExternalLinkPrefix(String externalLinkPrefix) {
+        this.setExternalLinkPrefix(externalLinkPrefix, true);
+    }
+
+    protected void setExternalLinkPrefix(String externalLinkPrefix, boolean refreshMode) {
+        if ("".equals(externalLinkPrefix)) {
+            throw new IllegalArgumentException("Invalid 'externalLinkPrefix': empty.");
+        }
+        //
+        this.externalLinkPrefix = externalLinkPrefix;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshContent();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public String getExternalLinkPrefix() {
+        return this.externalLinkPrefix;
+    }
+
+    /* Refresh */
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        this.refreshContent();
+        //
+        super.refresh();
+    }
+
+    protected void refreshContent() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        String content = null;
+        String text = this.getText();
+        String imageSource = this.getImageSource();
+        String externalLinkPrefix = this.getExternalLinkPrefix();
+        if (null == imageSource) {
+            content = MWebString.getXhtmlEscapedString(text);
+        }
+        else {
+            content = String.format("<img src=\"%s\" alt=\"%s\" />", MWebString.getXhtmlEscapedString(imageSource), MWebString.getXhtmlEscapedString(text));
+        }
+        if (null != externalLinkPrefix) {
+            content = String.format("<a href=\"%s\">%s</a>", MWebString.getXhtmlEscapedString(externalLinkPrefix + text), content);
+        }
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(content)));
+    }
+
+    /* Messages */
+
+    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
+        super.processMessage(event, parameters);
+        //
+        if ("onRefresh".equals(event)) {
+            this.onRefresh();
+        }
+        else {
+            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
+        }
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebTextBox.java b/src/java/com/marcozanon/macaco/web/ui/MWebTextBox.java
new file mode 100644 (file)
index 0000000..64e1473
--- /dev/null
@@ -0,0 +1,227 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import java.util.LinkedHashMap;
+
+public abstract class MWebTextBox extends MWebDirectWidget {
+
+    public static enum TextAlignment {
+        LEFT("left"),
+        CENTER("center"),
+        RIGHT("right");
+        private String name = null;
+        private TextAlignment(String name) {
+            this.name = name;
+        }
+        public String toString() {
+            return this.name;
+        }
+    };
+
+    protected String text = "";
+    protected MWebTextBox.TextAlignment textAlignment = null;
+
+    protected boolean enabledMode = true;
+
+    /* */
+
+    public MWebTextBox(MWebApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    /* Focus */
+
+    public void setFocus() {
+        try {
+            this.refreshFocus();
+        }
+        catch (MNoBrowserPageWebException exception) {
+        }
+        catch (MNoViewWebException exception) {
+        }
+        catch (MNoWidgetIdWebException exception) {
+        }
+        catch (MResponseWebException exception) {
+        }
+    }
+
+    /* Text */
+
+    public void setText(String text) {
+        this.setText(text, true);
+    }
+
+    protected void setText(String text, boolean refreshMode) {
+        if (null == text) {
+            throw new IllegalArgumentException("Invalid 'text': null.");
+        }
+        //
+        this.text = text;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshText();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public String getText() {
+        return this.text;
+    }
+
+    /* Text alignment */
+
+    public void setTextAlignment(MWebTextBox.TextAlignment textAlignment) {
+        this.setTextAlignment(textAlignment, true);
+    }
+
+    protected void setTextAlignment(MWebTextBox.TextAlignment textAlignment, boolean refreshMode) {
+        this.textAlignment = textAlignment;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshTextAlignment(false);
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public MWebTextBox.TextAlignment getTextAlignment() {
+        return this.textAlignment;
+    }
+
+    public String getFormattedTextAlignment() throws MNullPropertyWebException {
+        if (null == this.getTextAlignment()) {
+            throw new MNullPropertyWebException("Invalid text alignment: property null.");
+        }
+        return this.getTextAlignment().toString();
+    }
+
+    /* Enabled mode */
+
+    public void setEnabledMode(boolean enabledMode) {
+        this.setEnabledMode(enabledMode, true);
+    }
+
+    protected void setEnabledMode(boolean enabledMode, boolean refreshMode) {
+        this.enabledMode = enabledMode;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshEnabledMode();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public boolean getEnabledMode() {
+        return this.enabledMode;
+    }
+
+    /* Refresh */
+
+    protected void refreshFocus() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').focus(); }", this.getId(), this.getId()));
+    }
+
+    protected void refreshText() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').value = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(this.getText())));
+    }
+
+    protected void refreshTextAlignment(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        try {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textAlign = '%s'; }", this.getId(), this.getId(), this.getFormattedTextAlignment()));
+        }
+        catch (MNullPropertyWebException exception) {
+            if (!directRefreshMode) {
+                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textAlign = null; }", this.getId(), this.getId()));
+            }
+        }
+    }
+
+    protected void refreshEnabledMode() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').disabled = %s; }", this.getId(), this.getId(), !this.getEnabledMode()));
+    }
+
+    /* Messages */
+
+    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
+        super.processMessage(event, parameters);
+        //
+        if ("onBlur".equals(event)) {
+            if ((!this.getVisibleMode()) || (!this.getEnabledMode())) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden or disabled.", event));
+            }
+            String text = parameters.get("text");
+            if (null == text) {
+                throw new MUnexpectedMessageWebException("Invalid message: text parameter not available.");
+            }
+            this.onBlur(text);
+        }
+        else if ("onRefresh".equals(event)) {
+            this.onRefresh();
+        }
+        else {
+            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
+        }
+    }
+
+    public void onBlur(String text) {
+        this.setText(text, false);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebTimeBox.java b/src/java/com/marcozanon/macaco/web/ui/MWebTimeBox.java
new file mode 100644 (file)
index 0000000..6da48bf
--- /dev/null
@@ -0,0 +1,98 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.filtering.MConstraintFilteringException;
+import com.marcozanon.macaco.filtering.MFormatFilteringException;
+import com.marcozanon.macaco.filtering.MTimeFilter;
+
+public class MWebTimeBox extends MWebTextBox {
+
+    protected MTimeFilter timeFilter = null;
+
+    /* */
+
+    public MWebTimeBox(MWebApplicationContext applicationContext, MTimeFilter timeFilter) {
+        super(applicationContext);
+        //
+        if (null == timeFilter) {
+            throw new IllegalArgumentException("Invalid 'timeFilter': null.");
+        }
+        //
+        this.timeFilter = timeFilter;
+    }
+
+    public MWebTimeBox(MWebApplicationContext applicationContext, MTimeFilter timeFilter, String text) {
+        this(applicationContext, timeFilter);
+        //
+        this.setText(text);
+    }
+
+    /* Time filter */
+
+    protected MTimeFilter getTimeFilterReference() {
+        return this.timeFilter;
+    }
+
+    public MTimeFilter getTimeFilter() {
+        return this.getTimeFilterReference().clone();
+    }
+
+    /* Validation */
+
+    public void validate() throws MValidationWebException {
+        String text = this.getText();
+        try {
+            this.setText(this.getTimeFilterReference().getValidatedUserTime(text, null));
+        }
+        catch (MConstraintFilteringException exception) {
+            throw new MValidationWebException(String.format("Invalid time: %s.", text), exception);
+        }
+        catch (MFormatFilteringException exception) {
+            throw new MValidationWebException(String.format("Invalid time: %s.", text), exception);
+        }
+    }
+
+    /* Refresh */
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        String onBlurFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onBlur', {'text': this.value});", this.getId());
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<input type=\"text\" class=\"MWebTimeBox %s\" style=\"display: inline-block;\" onblur=\"%s\" id=\"%s\" />'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onBlurFunction), this.getId()));
+        //
+        super.refresh();
+        //
+        this.refreshText();
+        this.refreshTextAlignment(true);
+        this.refreshEnabledMode();
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebUploader.java b/src/java/com/marcozanon/macaco/web/ui/MWebUploader.java
new file mode 100644 (file)
index 0000000..fc6125b
--- /dev/null
@@ -0,0 +1,172 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.Part;
+
+public class MWebUploader extends MWebDirectWidget {
+
+    protected boolean enabledMode = true;
+
+    /* */
+
+    public MWebUploader(MWebApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    /* Focus */
+
+    public void setFocus() {
+        try {
+            this.refreshFocus();
+        }
+        catch (MNoBrowserPageWebException exception) {
+        }
+        catch (MNoViewWebException exception) {
+        }
+        catch (MNoWidgetIdWebException exception) {
+        }
+        catch (MResponseWebException exception) {
+        }
+    }
+
+    /* Enabled mode */
+
+    public void setEnabledMode(boolean enabledMode) {
+        this.setEnabledMode(enabledMode, true);
+    }
+
+    protected void setEnabledMode(boolean enabledMode, boolean refreshMode) {
+        this.enabledMode = enabledMode;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshEnabledMode();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public boolean getEnabledMode() {
+        return this.enabledMode;
+    }
+
+    /* Content disposition */
+
+    protected String getFileName(Part part) { // taken and adapted from http://java-x.blogspot.com/2010/08/file-upload-with-servlet-30.html
+        if (null == part) {
+            throw new IllegalArgumentException("Invalid 'part': null.");
+        }
+        //
+        for (String cd: part.getHeader("content-disposition").split(";")) {
+            if (cd.trim().startsWith("filename")) {
+                return cd.substring(cd.indexOf("=") + 1).trim().replace("\"", "");
+            }
+        }
+        return null;
+    }
+
+    /* Refresh */
+
+    protected void refreshFocus() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s_file').focus(); }", this.getId(), this.getId()));
+    }
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        String onUploadFunction = String.format("javascript: m_messageInterface.fireUploadFakeMessage('%s');", this.getId());
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<form class=\"MWebUploader %s\" id=\"%s\" action=\"#\" enctype=\"multipart/form-data\" method=\"post\" target=\"m_uploader\"><input type=\"file\" class=\"MWebUploaderFile %s\" style=\"display: inline-block;\" onchange=\"%s\" id=\"%s_file\" name=\"%s_file\" /></form>'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onUploadFunction), this.getId(), this.getId()));
+        //
+        super.refresh();
+        //
+        this.refreshEnabledMode();
+    }
+
+    protected void refreshEnabledMode() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s_file').disabled = %s; }", this.getId(), this.getId(), !this.getEnabledMode()));
+    }
+
+    /* Messages */
+
+    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
+        super.processMessage(event, parameters);
+        //
+        if ("onRefresh".equals(event)) {
+            this.onRefresh();
+        }
+        else if ("onUpload".equals(event)) {
+            if ((!this.getVisibleMode()) || (!this.getEnabledMode())) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden or disabled.", event));
+            }
+            HttpServletRequest request = this.getApplicationContextReference().getRequestReference();
+            Collection<Part> parts = null;
+            try {
+                parts = request.getParts();
+            }
+            catch (IllegalStateException exception) {
+                throw new MUnexpectedMessageWebException("Invalid message: size exceeded."); // no need to propagate exception
+               }
+            catch (IOException exception) {
+                throw new MUnexpectedMessageWebException("Invalid message: I/O error."); // no need to propagate exception
+               }
+            catch (ServletException exception) {
+                throw new MUnexpectedMessageWebException("Invalid message: not a multipart/form-data request."); // no need to propagate exception
+               }
+            if (1 != parts.size()) {
+                throw new MUnexpectedMessageWebException("Invalid message: there must be exactly one part.");
+            }
+            this.onUpload(parts.iterator().next());
+        }
+        else {
+            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
+        }
+    }
+
+    public void onUpload(Part part) {
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebVerticalMenu.java b/src/java/com/marcozanon/macaco/web/ui/MWebVerticalMenu.java
new file mode 100644 (file)
index 0000000..60c5019
--- /dev/null
@@ -0,0 +1,307 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+
+public class MWebVerticalMenu extends MWebDirectWidget {
+
+    protected String title = null;
+
+    protected boolean accordionMode = true;
+
+    protected LinkedHashMap<String, MWebVerticalMenuItem> items = new LinkedHashMap<String, MWebVerticalMenuItem>();
+    protected String selectedItemKey = null;
+
+    /* */
+
+    public MWebVerticalMenu(MWebApplicationContext applicationContext, String title) {
+        super(applicationContext);
+        //
+        this.title = title;
+    }
+
+    public MWebVerticalMenu(MWebApplicationContext applicationContext, String title, LinkedHashMap<String, MWebVerticalMenuItem> items, String selectedItemKey) {
+        this(applicationContext, title);
+        //
+        this.setItems(items, selectedItemKey);
+    }
+
+    /* Title */
+
+    public String getTitle() {
+        return this.title;
+    }
+
+    /* Accordion mode */
+
+    public void setAccordionMode(boolean accordionMode) {
+        this.setAccordionMode(accordionMode, true);
+    }
+
+    protected void setAccordionMode(boolean accordionMode, boolean refreshMode) {
+        this.accordionMode = accordionMode;
+        //
+        if (refreshMode) {
+            try {
+                this.refresh(); // must refresh everything
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+            catch (MUniqueWidgetIdNotAvailableWebException exception) {
+            }
+        }
+    }
+
+    public boolean getAccordionMode() {
+        return this.accordionMode;
+    }
+
+    /* Items */
+
+    public void setItems(LinkedHashMap<String, MWebVerticalMenuItem> items, String selectedItemKey) {
+        this.setItems(items, selectedItemKey, true);
+    }
+
+    protected void setItems(LinkedHashMap<String, MWebVerticalMenuItem> items, String selectedItemKey, boolean refreshMode) {
+        if (null == items) {
+            throw new IllegalArgumentException("Invalid 'items': null.");
+        }
+        else {
+            for (String k: items.keySet()) {
+                if ((null == k) || ("".equals(k))) {
+                    throw new IllegalArgumentException("Invalid 'items': item key null or empty.");
+                }
+                else if (null == items.get(k)) {
+                    throw new IllegalArgumentException("Invalid 'items': item null.");
+                }
+            }
+        }
+        //
+        this.items = items;
+        //
+        if (refreshMode) {
+            try {
+                this.refresh(); // must refresh everything
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+            catch (MUniqueWidgetIdNotAvailableWebException exception) {
+            }
+        }
+        //
+        this.setSelectedItem(selectedItemKey, refreshMode);
+    }
+
+    protected LinkedHashMap<String, MWebVerticalMenuItem> getItemsReference() {
+        return this.items;
+    }
+
+    public LinkedHashMap<String, MWebVerticalMenuItem> getItems() {
+        LinkedHashMap<String, MWebVerticalMenuItem> tmpItems = new LinkedHashMap<String, MWebVerticalMenuItem>();
+        for (String key: this.getItemsReference().keySet()) {
+            tmpItems.put(key, this.getItemsReference().get(key).clone());
+        }
+        return tmpItems;
+    }
+
+    public LinkedHashSet<String> getItemKeys() {
+        LinkedHashSet<String> tmpItemKeys = new LinkedHashSet<String>();
+        for (String itemKey: this.getItemsReference().keySet()) {
+            tmpItemKeys.add(itemKey);
+        }
+        return tmpItemKeys;
+    }
+
+    public void setSelectedItem(String selectedItemKey) {
+        this.setSelectedItem(selectedItemKey, true);
+    }
+
+    protected void setSelectedItem(String selectedItemKey, boolean refreshMode) {
+        if ("".equals(selectedItemKey)) {
+            throw new IllegalArgumentException("Invalid 'selectedItemKey': empty.");
+        }
+        else if ((null != selectedItemKey) && (!this.getItemsReference().containsKey(selectedItemKey))) {
+            throw new IllegalArgumentException(String.format("Invalid 'selectedItemKey': %s: not available.", selectedItemKey));
+        }
+        //
+        this.selectedItemKey = selectedItemKey;
+        //
+        if (refreshMode) {
+            try {
+                this.refresh(); // must refresh everything
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+            catch (MUniqueWidgetIdNotAvailableWebException exception) {
+            }
+        }
+    }
+
+    public String getSelectedItemKey() {
+        return this.selectedItemKey;
+    }
+
+    /* Refresh */
+
+    protected String getItemContent(String parentItemKey) throws MNoWidgetIdWebException { // code partly taken from http://www.codecodex.com/wiki/Count_the_number_of_occurrences_of_a_specific_character_in_a_string
+        if ("".equals(parentItemKey)) {
+            throw new IllegalArgumentException("Invalid 'parentItemKey': empty.");
+        }
+        //
+        if (null == parentItemKey) {
+            parentItemKey = ""; // rewritten for better readability
+        }
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        int parentItemLevel = parentItemKey.replaceAll("[^.]", "").length();
+        StringBuilder itemContent = new StringBuilder("");
+        if ((0 == parentItemLevel) && (null != this.getTitle())) {
+            itemContent.append(String.format("<tr class=\"MWebVerticalMenuTitleRow %s\">", customClasses));
+            itemContent.append(String.format("<td class=\"MWebVerticalMenuTitleCell %s\" colspan=\"2\">%s</td>", customClasses, MWebString.getXhtmlEscapedString(this.getTitle())));
+            itemContent.append("</tr>");
+        }
+        String lastItemKey = "";
+        for (String itemKey: this.getItemsReference().keySet()) {
+            lastItemKey = itemKey;
+            if (!itemKey.startsWith(parentItemKey)) {
+                continue;
+            }
+            if (itemKey.replaceAll("[^.]", "").length() != (parentItemLevel + 1)) {
+                continue;
+            }
+            itemContent.append(String.format("<tr class=\"MWebVerticalMenuRow %s\">", customClasses));
+            String text = this.getItemsReference().get(itemKey).getText();
+            if (!"".equals(text)) {
+                String imageSource = this.getItemsReference().get(itemKey).getImageSource();
+                if (null == imageSource) {
+                    imageSource = String.format("%s/null", this.getApplicationContextReference().getRequestReference().getRequestURL());
+                }
+                String imageClass = "MWebVerticalMenuImageCell";
+                String textClass = "MWebVerticalMenuTextCell";
+                if (itemKey.equals(this.getSelectedItemKey())) {
+                    imageClass = "MWebVerticalMenuSelectedImageCell";
+                    textClass = "MWebVerticalMenuSelectedTextCell";
+                }
+                String onItemSelectionFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onItemSelection', {'selectedItemKey': '%s'});", this.getId(), MWebString.getJavascriptEscapedString(itemKey));
+                itemContent.append(String.format("<td class=\"%s %s\" onclick=\"%s\" id=\"%s\"><img class=\"MWebVerticalMenuImage %s\" src=\"%s\" alt=\"\" /></td>", imageClass, customClasses, MWebString.getXhtmlEscapedString(onItemSelectionFunction), this.getId() + MWebString.getXhtmlEscapedString(itemKey) + "-imageCell", customClasses, MWebString.getXhtmlEscapedString(imageSource)));
+                itemContent.append(String.format("<td class=\"%s %s\" onclick=\"%s\" id=\"%s\">%s</td>", textClass, customClasses, MWebString.getXhtmlEscapedString(onItemSelectionFunction), this.getId() + MWebString.getXhtmlEscapedString(itemKey) + "-textCell", MWebString.getXhtmlEscapedString(text)));
+            }
+            else {
+                itemContent.append(String.format("<td class=\"MWebVerticalMenuSeparatorCell %s\" id=\"%s\" colspan=\"2\"></td>", customClasses, this.getId() + MWebString.getXhtmlEscapedString(itemKey) + "-separatorCell"));
+            }
+            itemContent.append("</tr>");
+            //
+            if ((!this.getAccordionMode()) || (this.getAccordionMode() && (null != this.getSelectedItemKey()) && (this.getSelectedItemKey().startsWith(itemKey)))) {
+                String childItemContent = this.getItemContent(itemKey);
+                if (!"".equals(childItemContent.toString())) {
+                    itemContent.append(String.format("<tr class=\"MWebVerticalMenuRow %s\">", customClasses));
+                    itemContent.append(String.format("<td class=\"MWebVerticalMenuImageCell\" />", customClasses));
+                    itemContent.append(String.format("<td class=\"MWebVerticalMenuChildTableCell %s\" id=\"%s\">%s</td>", customClasses, this.getId() + MWebString.getXhtmlEscapedString(itemKey) + "-childCell", childItemContent));
+                    itemContent.append("</tr>");
+                }
+            }
+        }
+        //
+        StringBuilder content = new StringBuilder("");
+        if (!"".equals(itemContent.toString())) {
+            if ("".equals(parentItemKey)) {
+                content.append(String.format("<table class=\"MWebVerticalMenuTable %s\" style=\"display: inline-table;\" id=\"%s\">", customClasses, this.getId()));
+            }
+            else {
+                content.append(String.format("<table class=\"MWebVerticalMenuChildTable %s\" style=\"display: inline-table; width: 100%%;\" id=\"%s\">", customClasses, this.getId() + MWebString.getXhtmlEscapedString(lastItemKey) + "-childTable"));
+            }
+            content.append(itemContent);
+            content.append("</table>");
+        }
+        return content.toString();
+    }
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        String content = this.getItemContent(null);
+        if ("".equals(content)) {
+            content = String.format("<div id=\"%s\"></div>", this.getId());
+        }
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(content)));
+        //
+        super.refresh();
+    }
+
+    /* Messages */
+
+    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
+        super.processMessage(event, parameters);
+        //
+        if ("onItemSelection".equals(event)) {
+            if (!this.getVisibleMode()) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
+            }
+            String selectedItemKey = parameters.get("selectedItemKey");
+            if (null == selectedItemKey) {
+                throw new MUnexpectedMessageWebException("Invalid message: selected item key parameter not available.");
+            }
+            else if (!this.getItemsReference().keySet().contains(selectedItemKey)) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: selected item key parameter not recognized.", selectedItemKey));
+            }
+            this.onItemSelection(selectedItemKey);
+        }
+        else if ("onRefresh".equals(event)) {
+            this.onRefresh();
+        }
+        else {
+            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
+        }
+    }
+
+    public void onItemSelection(String selectedItemKey) {
+        this.setSelectedItem(selectedItemKey);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebVerticalMenuItem.java b/src/java/com/marcozanon/macaco/web/ui/MWebVerticalMenuItem.java
new file mode 100644 (file)
index 0000000..ee2d3b4
--- /dev/null
@@ -0,0 +1,82 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.MObject;
+
+public class MWebVerticalMenuItem extends MObject {
+
+    protected MWebApplicationContext applicationContext = null;
+
+    protected String text = "";
+    protected String imageSource = null;
+
+    /* */
+
+    public MWebVerticalMenuItem(MWebApplicationContext applicationContext) {
+        super();
+        //
+        if (null == applicationContext) {
+            throw new IllegalArgumentException("Invalid 'applicationContext': null.");
+        }
+        //
+        this.applicationContext = applicationContext;
+    }
+
+    public MWebVerticalMenuItem(MWebApplicationContext applicationContext, String text, String imageSource) {
+        this(applicationContext);
+        //
+        if (null == text) {
+            throw new IllegalArgumentException("Invalid 'text': null.");
+        }
+        //
+        this.text = text;
+        this.imageSource = imageSource;
+    }
+
+    public MWebVerticalMenuItem clone() {
+        return new MWebVerticalMenuItem(this.getApplicationContextReference(), this.getText(), this.getImageSource());
+    }
+
+    /* Application context */
+
+    public MWebApplicationContext getApplicationContextReference() {
+        return this.applicationContext;
+    }
+
+    /* Text */
+
+    public String getText() {
+        return this.text;
+    }
+
+    /* Image source */
+
+    public String getImageSource() {
+        return this.imageSource;
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebView.java b/src/java/com/marcozanon/macaco/web/ui/MWebView.java
new file mode 100644 (file)
index 0000000..5bb555e
--- /dev/null
@@ -0,0 +1,443 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.MObject;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+
+public class MWebView extends MObject implements Runnable {
+
+    protected MWebApplicationContext applicationContext = null;
+
+    protected MWebBrowserPage browserPage = null;
+
+    protected String breadcrumb = null;
+    protected String title = "";
+
+    protected LinkedList<MWebDownloader> downloaders = new LinkedList<MWebDownloader>();
+    protected MWebDirectWidget content = null;
+
+    protected LinkedHashSet<Long> uniqueWidgetIds = new LinkedHashSet<Long>();
+    protected long uniqueWidgetIdsPointer = 0;
+
+    /* */
+
+    public MWebView(MWebApplicationContext applicationContext, String breadcrumb) {
+        super();
+        //
+        if (null == applicationContext) {
+            throw new IllegalArgumentException("Invalid 'applicationContext': null.");
+        }
+        if ((null == breadcrumb) || ("".equals(breadcrumb))) {
+            throw new IllegalArgumentException("Invalid 'breadcrumb': null or empty.");
+        }
+        //
+        this.applicationContext = applicationContext;
+        this.breadcrumb = breadcrumb;
+    }
+
+    public void run() {
+        while (true) {
+            try {
+                this.processMessage(this.getBrowserPageReference().getProcessableMessage());
+            }
+            catch (MViewThreadStoppingWebRuntimeException exception) {
+                break;
+            }
+            catch (Exception exception) { // any other exception, put here not to bypass MViewThreadStoppingWebRuntimeException
+                try {
+                    this.getBrowserPageReference().setLastViewThreadException(exception);
+                }
+                catch (MNoBrowserPageWebException exception2) {
+                }
+            }
+            //
+            try {
+                synchronized (Thread.currentThread()) {
+                    Thread.currentThread().wait();
+                }
+            }
+            catch (InterruptedException exception) {
+            }
+        }
+    }
+
+    public String openView(MWebView view) throws MNoBrowserPageWebException {
+        this.getBrowserPageReference().loadViewThread(view);
+        try {
+            synchronized (Thread.currentThread()) {
+                Thread.currentThread().wait();
+            }
+        }
+        catch (InterruptedException exception) {
+        }
+        //
+        if (this.getBrowserPageReference().getStoppingViewThreadCount() > 0) {
+            this.getBrowserPageReference().decrementStoppingViewThreadCount();
+            throw new MViewThreadStoppingWebRuntimeException("View thread stopping...");
+        }
+        //
+        try {
+            this.refresh();
+        }
+        catch (MNoBrowserPageWebException exception) {
+        }
+        catch (MNoWidgetIdWebException exception) {
+        }
+        catch (MResponseWebException exception) {
+        }
+        //
+        return this.getBrowserPageReference().getLastViewThreadReturnValue();
+    }
+
+    public void close(String returnValue) throws MNoBrowserPageWebException, MViewNotUnloadableWebException {
+        this.getBrowserPageReference().unloadViewThreads(returnValue, 1, null);
+        throw new MViewThreadStoppingWebRuntimeException("View thread stopping...");
+    }
+
+    public void close(int n) throws MNoBrowserPageWebException, MViewNotUnloadableWebException {
+        this.getBrowserPageReference().unloadViewThreads(null, n, null);
+        throw new MViewThreadStoppingWebRuntimeException("View thread stopping...");
+    }
+
+    public void closeAll(MWebView replacingView) throws MNoBrowserPageWebException, MViewNotUnloadableWebException {
+        this.getBrowserPageReference().unloadViewThreads(null, this.getBrowserPageReference().getViewThreadCount(), replacingView);
+        throw new MViewThreadStoppingWebRuntimeException("View thread stopping...");
+    }
+
+    /* Application context */
+
+    public MWebApplicationContext getApplicationContextReference() {
+        return this.applicationContext;
+    }
+
+    /* Browser page */
+
+    protected void setBrowserPage(MWebBrowserPage browserPage) {
+        this.browserPage = browserPage;
+    }
+
+    public MWebBrowserPage getBrowserPageReference() throws MNoBrowserPageWebException {
+        if (null == this.browserPage) {
+            throw new MNoBrowserPageWebException("Invalid browser page: reference null.");
+        }
+        //
+        return this.browserPage;
+    }
+
+    /* Breadcrumb */
+
+    public String getBreadcrumb() {
+        return this.breadcrumb;
+    }
+
+    /* Title */
+
+    public void setTitle(String title) {
+        this.setTitle(title, true);
+    }
+
+    protected void setTitle(String title, boolean refreshMode) {
+        if (null == title) {
+            throw new IllegalArgumentException("Invalid 'title': null.");
+        }
+        //
+        this.title = title;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshTitle();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public String getTitle() {
+        return this.title;
+    }
+
+    /* Downloaders */
+
+    public void addDownloader(MWebDownloader downloader) throws MUniqueWidgetIdNotAvailableWebException {
+        if (null == downloader) {
+            throw new IllegalArgumentException("Invalid 'downloader': null.");
+        }
+        //
+        downloader.setView(this);
+        this.getDownloadersReference().add(downloader);
+    }
+
+    public void setDownloader(int index, MWebDownloader downloader) throws MUniqueWidgetIdNotAvailableWebException {
+        if ((index < 0) || (index > (this.getDownloadersReference().size() - 1))) {
+            throw new IllegalArgumentException(String.format("Invalid 'index': %s: out of range.", index));
+        }
+        if (null == downloader) {
+            throw new IllegalArgumentException("Invalid 'downloader': null.");
+        }
+        //
+        downloader.setView(this);
+        this.getDownloadersReference().set(index, downloader);
+    }
+
+    protected LinkedList<MWebDownloader> getDownloadersReference() {
+        return this.downloaders;
+    }
+
+    public MWebDownloader getDownloaderReference(int index) {
+        if ((index < 0) || (index > (this.getDownloadersReference().size() - 1))) {
+            throw new IllegalArgumentException(String.format("Invalid 'index': %s: out of range.", index));
+        }
+        //
+        return this.getDownloadersReference().get(index);
+    }
+
+    public MWebDownloader getDownloaderReferenceById(String id) throws MDownloaderNotFoundWebException {
+        if ((null == id) || ("".equals(id))) {
+            throw new IllegalArgumentException("Invalid 'id': null or empty.");
+        }
+        //
+        for (MWebDownloader downloader: this.getDownloadersReference()) {
+            try {
+                if (downloader.getId().equals(id)) {
+                    return downloader;
+                }
+            }
+            catch (MNoWidgetIdWebException exception) { // cannot happen
+            }
+        }
+        throw new MDownloaderNotFoundWebException(String.format("Invalid 'id': %s.", id));
+    }
+
+    public int countDownloaders() {
+        return this.getDownloadersReference().size();
+    }
+
+    public void removeDownloader(int index) {
+        if ((index < 0) || (index > (this.getDownloadersReference().size() - 1))) {
+            throw new IllegalArgumentException(String.format("Invalid 'index': %s: out of range.", index));
+        }
+        //
+        try {
+            this.getDownloaderReference(index).setView(null);
+        }
+        catch (MUniqueWidgetIdNotAvailableWebException exception) { // cannot happen
+        }
+        this.getDownloadersReference().remove(index);
+    }
+
+    public void clearDownloaders() {
+        this.getDownloadersReference().clear();
+    }
+
+    /* Content */
+
+    public void setContent(MWebDirectWidget directWidget) throws MUniqueWidgetIdNotAvailableWebException {
+        this.setContent(directWidget, true);
+    }
+
+    protected void setContent(MWebDirectWidget directWidget, boolean refreshMode) throws MUniqueWidgetIdNotAvailableWebException {
+        try {
+            this.getContentReference().setView(null);
+        }
+        catch (MNoViewContentWebException exception) {
+        }
+        catch (MUniqueWidgetIdNotAvailableWebException exception) { // cannot happen
+        }
+        //
+        this.content = directWidget;
+        //
+        try {
+            this.getContentReference().setView(this);
+        }
+        catch (MNoViewContentWebException exception) {
+        }
+        //
+        if (refreshMode) {
+            try {
+                this.refreshContent();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public MWebDirectWidget getContentReference() throws MNoViewContentWebException {
+        if (null == this.content) {
+            throw new MNoViewContentWebException("Invalid content: reference null.");
+        }
+        //
+        return this.content;
+    }
+
+    /* Display widgets */
+
+    protected MWebDisplayWidget getDisplayWidgetReferenceById(String id) throws MDisplayWidgetNotFoundWebException {
+        try {
+            return this.getContentReference().getDisplayWidgetReferenceById(id);
+        }
+        catch (MDisplayWidgetNotFoundWebException exception) {
+            throw new MDisplayWidgetNotFoundWebException(String.format("Invalid 'id': %s: display widget not available on this path.", id)); // no need to propagate exception
+        }
+        catch (MNoViewContentWebException exception) {
+            throw new MDisplayWidgetNotFoundWebException(String.format("Invalid 'id': %s: no view content.", id)); // no need to propagate exception
+        }
+    }
+
+    /* Unique widget ids */
+
+    protected LinkedHashSet<Long> getUniqueWidgetIdsReference() {
+        return this.uniqueWidgetIds;
+    }
+
+    public long getUniqueWidgetId() throws MUniqueWidgetIdNotAvailableWebException {
+        long p = this.uniqueWidgetIdsPointer;
+        //
+        while (true) {
+            if (Long.MAX_VALUE == this.uniqueWidgetIdsPointer) {
+                this.uniqueWidgetIdsPointer = 0;
+            }
+            else {
+                this.uniqueWidgetIdsPointer++;
+            }
+            if (p == this.uniqueWidgetIdsPointer) {
+                throw new MUniqueWidgetIdNotAvailableWebException("Unique widget id not available: too many widgets registered.");
+            }
+            else if (!this.getUniqueWidgetIdsReference().contains(new Long(this.uniqueWidgetIdsPointer))) {
+                this.getUniqueWidgetIdsReference().add(new Long(this.uniqueWidgetIdsPointer));
+                return this.uniqueWidgetIdsPointer;
+            }
+        }
+    }
+
+    public void freeUniqueWidgetId(long uniqueWidgetId) {
+        if (uniqueWidgetId <= 0) {
+            throw new IllegalArgumentException("Invalid 'uniqueWidgetId': must be positive.");
+        }
+        //
+        this.getUniqueWidgetIdsReference().remove(new Long(uniqueWidgetId));
+    }
+
+    /* Refresh */
+
+    public void checkPresence() throws MNoBrowserPageWebException {
+        this.getBrowserPageReference();
+    }
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent("$disableWysiwygBoxEditors();");
+        //
+        this.refreshContent();
+        //
+        this.refreshTitle();
+    }
+
+    protected void refreshContent() throws MNoBrowserPageWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        try {
+            MWebDisplayWidget content = this.getContentReference();
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("$('m_view').innerHTML = '<div id=\"%s\"></div>';", content.getId()));
+            content.onRefresh();
+        }
+        catch (MNoViewContentWebException exception) {
+            this.getApplicationContextReference().addPlainTextResponseContent("$('m_view').innerHTML = '';");
+        }
+    }
+
+    protected void refreshTitle() throws MNoBrowserPageWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("document.title = '%s';", MWebString.getJavascriptEscapedString(this.getTitle())));
+    }
+
+    /* Messages */
+
+    protected void onMessagePreprocessing() {
+    }
+
+    protected void processMessage(MWebMessage message) throws MUnexpectedMessageWebException {
+        if (null == message) {
+            throw new IllegalArgumentException("Invalid 'message': null.");
+        }
+        //
+        this.onMessagePreprocessing();
+        // parse message and forward it to view or to appropriate widgets
+        String widgetId = message.getWidgetId();
+        String event = message.getEvent();
+        LinkedHashMap<String, String> parameters = message.getParameters();
+        if ("".equals(widgetId)) { // no widget id = view
+            if ("onRefresh".equals(event)) {
+                this.onRefresh();
+            }
+            else {
+                throw new MUnexpectedMessageWebException(String.format("Invalid 'message': %s: event not recognized.", event));
+            }
+        }
+        else {
+            try { // first search through downloaders...
+                this.getDownloaderReferenceById(widgetId).processMessage(event, parameters);
+            }
+            catch (MDownloaderNotFoundWebException exception) {
+                try { // ...then through display widgets
+                    this.getDisplayWidgetReferenceById(widgetId).processMessage(event, parameters);
+                }
+                catch (MDisplayWidgetNotFoundWebException exception2) {
+                    throw new MUnexpectedMessageWebException(String.format("Invalid 'message': %s: widget not found.", widgetId)); // no need to propagate exception
+                }
+                catch (MUnexpectedMessageWebException exception2) {
+                    throw new MUnexpectedMessageWebException("Invalid 'message': not suitable.", exception2);
+                }
+            }
+            catch (MUnexpectedMessageWebException exception) {
+                throw new MUnexpectedMessageWebException("Invalid 'message': not suitable.", exception);
+            }
+        }
+    }
+
+    public void onRefresh() {
+        try {
+            this.refresh();
+        }
+        catch (MNoBrowserPageWebException exception) {
+        }
+        catch (MNoWidgetIdWebException exception) {
+        }
+        catch (MResponseWebException exception) {
+        }
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebWidget.java b/src/java/com/marcozanon/macaco/web/ui/MWebWidget.java
new file mode 100644 (file)
index 0000000..f9ffebc
--- /dev/null
@@ -0,0 +1,107 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import com.marcozanon.macaco.MObject;
+import java.util.LinkedHashMap;
+
+public abstract class MWebWidget extends MObject {
+
+    protected MWebApplicationContext applicationContext = null;
+
+    protected MWebView view = null;
+
+    protected String id = null;
+
+    /* */
+
+    public MWebWidget(MWebApplicationContext applicationContext) {
+        super();
+        //
+        if (null == applicationContext) {
+            throw new IllegalArgumentException("Invalid 'applicationContext': null.");
+        }
+        //
+        this.applicationContext = applicationContext;
+    }
+
+    /* Application context */
+
+    public MWebApplicationContext getApplicationContextReference() {
+        return this.applicationContext;
+    }
+
+    /* View */
+
+    protected void setView(MWebView view) throws MUniqueWidgetIdNotAvailableWebException {
+        try {
+            this.getViewReference().freeUniqueWidgetId((new Long(this.getId().substring("m_widget".length()))).longValue());
+        }
+        catch (MNoViewWebException exception) {
+        }
+        catch (MNoWidgetIdWebException exception) {
+        }
+        //
+        this.view = view;
+        //
+        if (null == view) {
+            this.id = null;
+        }
+        else {
+            this.id = (new Long(view.getUniqueWidgetId())).toString();
+        }
+    }
+
+    public MWebView getViewReference() throws MNoViewWebException {
+        if (null == this.view) {
+            throw new MNoViewWebException("Invalid view: reference null.");
+        }
+        //
+        return this.view;
+    }
+
+    /* Id */
+
+    public String getId() throws MNoWidgetIdWebException {
+        if (null == this.id) {
+            throw new MNoWidgetIdWebException("Invalid id: reference null.");
+        }
+        //
+        return "m_widget" + this.id;
+    }
+
+    /* Messages */
+
+    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
+        if ((null == event) || ("".equals(event))) {
+            throw new IllegalArgumentException("Invalid 'event': null or empty.");
+        }
+        if (null == parameters) {
+            throw new IllegalArgumentException("Invalid 'parameters': null.");
+        }
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebWysiwygBox.java b/src/java/com/marcozanon/macaco/web/ui/MWebWysiwygBox.java
new file mode 100644 (file)
index 0000000..9f1086b
--- /dev/null
@@ -0,0 +1,217 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+import java.util.LinkedHashMap;
+
+public class MWebWysiwygBox extends MWebDirectWidget {
+
+    protected String text = "";
+
+    protected boolean enabledMode = true;
+    protected boolean displayedMode = false; // for internal use only
+
+    /* */
+
+    public MWebWysiwygBox(MWebApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    public MWebWysiwygBox(MWebApplicationContext applicationContext, String text) {
+        this(applicationContext);
+        //
+        this.setText(text);
+    }
+
+    /* Focus */
+
+    public void setFocus() {
+        try {
+            this.refreshFocus();
+        }
+        catch (MNoBrowserPageWebException exception) {
+        }
+        catch (MNoViewWebException exception) {
+        }
+        catch (MNoWidgetIdWebException exception) {
+        }
+        catch (MResponseWebException exception) {
+        }
+    }
+
+    /* Text */
+
+    public void setText(String text) {
+        this.setText(text, true);
+    }
+
+    protected void setText(String text, boolean refreshMode) {
+        if (null == text) {
+            throw new IllegalArgumentException("Invalid 'text': null.");
+        }
+        //
+        try {
+            this.text = MWebString.getXhtmlSafeString(text);
+        }
+        catch (MXhtmlUnsafeStringWebException exception) {
+            throw new IllegalArgumentException(String.format("Invalid 'text': %s: unsafe Xhtml tags or attributes inside.", text)); // no need to propagate exception
+        }
+        //
+        if (refreshMode) {
+            try {
+                this.refreshText();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public String getText() {
+        return this.text;
+    }
+
+    /* Enabled mode */
+
+    public void setEnabledMode(boolean enabledMode) {
+        this.setEnabledMode(enabledMode, true);
+    }
+
+    protected void setEnabledMode(boolean enabledMode, boolean refreshMode) {
+        this.enabledMode = enabledMode;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshEnabledMode();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public boolean getEnabledMode() {
+        return this.enabledMode;
+    }
+
+    /* Refresh */
+
+    protected void refreshFocus() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        if (this.getEnabledMode()) {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $focusWysiwygBoxEditor('%s'); }", this.getId(), this.getId()));
+        }
+    }
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        this.displayedMode = false;
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        customClasses = customClasses + " " + this.getId();
+        StringBuilder content = new StringBuilder("");
+        content.append(String.format("<div class=\"MWebWysiwygBox %s\" style=\"display: inline-block;\" id=\"%s\" cols=\"1\" rows=\"1\"></div>", customClasses, this.getId()));
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(content.toString())));
+        //
+        super.refresh();
+        //
+        this.refreshEnabledMode();
+        this.refreshText();
+    }
+
+    protected void refreshEnabledMode() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        if (this.getEnabledMode()) {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $enableWysiwygBoxEditor('%s', '%s'); }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(this.getText())));
+            this.displayedMode = true;
+        }
+        else {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $disableWysiwygBoxEditor('%s'); }", this.getId(), this.getId()));
+            this.displayedMode = false;
+        }
+    }
+
+    protected void refreshText() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        if (this.getEnabledMode() && this.displayedMode) {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $fillWysiwygBoxEditor('%s', '%s'); }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(this.getText())));
+        }
+        else {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(this.getText())));
+        }
+    }
+
+    /* Messages */
+
+    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
+        super.processMessage(event, parameters);
+        //
+        if ("onBlur".equals(event)) {
+            if ((!this.getVisibleMode()) || (!this.getEnabledMode())) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden or disabled.", event));
+            }
+            String text = parameters.get("text");
+            if (null == text) {
+                throw new MUnexpectedMessageWebException("Invalid message: text parameter not available.");
+            }
+            try {
+                String y = MWebString.getXhtmlSafeString(text);
+            }
+            catch (MXhtmlUnsafeStringWebException exception) {
+                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: unsafe Xhtml tags or attributes inside.", text)); // no need to propagate exception
+            }
+            this.onBlur(text);
+        }
+        else if ("onRefresh".equals(event)) {
+            this.onRefresh();
+        }
+        else {
+            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
+        }
+    }
+
+    public void onBlur(String text) {
+        this.setText(text, false);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebXhtmlLabel.java b/src/java/com/marcozanon/macaco/web/ui/MWebXhtmlLabel.java
new file mode 100644 (file)
index 0000000..5114876
--- /dev/null
@@ -0,0 +1,66 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MWebXhtmlLabel extends MWebLabel {
+
+    /* */
+
+    public MWebXhtmlLabel(MWebApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    public MWebXhtmlLabel(MWebApplicationContext applicationContext, String text) {
+        this(applicationContext);
+        //
+        this.setText(text);
+    }
+
+    /* Refresh */
+
+    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
+        this.checkPresence();
+        //
+        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
+        if (null == customClasses) {
+            customClasses = "";
+        }
+        String onClickFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onClick', {});", this.getId());
+        String onDoubleClickFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onDoubleClick', {});", this.getId());
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<div class=\"MWebXhtmlLabel %s\" style=\"display: inline-block;\" onclick=\"%s\" ondblclick=\"%s\" id=\"%s\"></div>'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onClickFunction), MWebString.getJavascriptEscapedString(onDoubleClickFunction), this.getId()));
+        //
+        super.refresh();
+        //
+        this.refreshText();
+    }
+
+    protected void refreshText() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(MWebString.getXhtmlNumericEntitiesString(this.getText()))));
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MXhtmlUnsafeStringWebException.java b/src/java/com/marcozanon/macaco/web/ui/MXhtmlUnsafeStringWebException.java
new file mode 100644 (file)
index 0000000..743df7b
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon
+ * 
+ * Released under the MIT License:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.marcozanon.macaco.web.ui;
+
+public class MXhtmlUnsafeStringWebException extends MSecurityWebException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MXhtmlUnsafeStringWebException() {
+        super();
+    }
+
+    public MXhtmlUnsafeStringWebException(String message) {
+        super(message);
+    }
+
+    public MXhtmlUnsafeStringWebException(Throwable error) {
+        super(error);
+    }
+
+    public MXhtmlUnsafeStringWebException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/webui/MApplicationServletWebException.java b/src/java/com/marcozanon/macaco/webui/MApplicationServletWebException.java
deleted file mode 100644 (file)
index 478a1c5..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MApplicationServletWebException extends MWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MApplicationServletWebException() {
-        super();
-    }
-
-    public MApplicationServletWebException(String message) {
-        super(message);
-    }
-
-    public MApplicationServletWebException(Throwable error) {
-        super(error);
-    }
-
-    public MApplicationServletWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MBrowserPageRequestPreprocessingWebException.java b/src/java/com/marcozanon/macaco/webui/MBrowserPageRequestPreprocessingWebException.java
deleted file mode 100644 (file)
index 7a77d0b..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MBrowserPageRequestPreprocessingWebException extends MWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MBrowserPageRequestPreprocessingWebException() {
-        super();
-    }
-
-    public MBrowserPageRequestPreprocessingWebException(String message) {
-        super(message);
-    }
-
-    public MBrowserPageRequestPreprocessingWebException(Throwable error) {
-        super(error);
-    }
-
-    public MBrowserPageRequestPreprocessingWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MDisplayWidgetNotFoundWebException.java b/src/java/com/marcozanon/macaco/webui/MDisplayWidgetNotFoundWebException.java
deleted file mode 100644 (file)
index 964695d..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MDisplayWidgetNotFoundWebException extends MSecurityWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MDisplayWidgetNotFoundWebException() {
-        super();
-    }
-
-    public MDisplayWidgetNotFoundWebException(String message) {
-        super(message);
-    }
-
-    public MDisplayWidgetNotFoundWebException(Throwable error) {
-        super(error);
-    }
-
-    public MDisplayWidgetNotFoundWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MDownloaderNotFoundWebException.java b/src/java/com/marcozanon/macaco/webui/MDownloaderNotFoundWebException.java
deleted file mode 100644 (file)
index 3abc13a..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MDownloaderNotFoundWebException extends MSecurityWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MDownloaderNotFoundWebException() {
-        super();
-    }
-
-    public MDownloaderNotFoundWebException(String message) {
-        super(message);
-    }
-
-    public MDownloaderNotFoundWebException(Throwable error) {
-        super(error);
-    }
-
-    public MDownloaderNotFoundWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MInvalidRemoteIpAddressWebException.java b/src/java/com/marcozanon/macaco/webui/MInvalidRemoteIpAddressWebException.java
deleted file mode 100644 (file)
index 7d1a239..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MInvalidRemoteIpAddressWebException extends MSecurityWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MInvalidRemoteIpAddressWebException() {
-        super();
-    }
-
-    public MInvalidRemoteIpAddressWebException(String message) {
-        super(message);
-    }
-
-    public MInvalidRemoteIpAddressWebException(Throwable error) {
-        super(error);
-    }
-
-    public MInvalidRemoteIpAddressWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MInvalidRequestWebException.java b/src/java/com/marcozanon/macaco/webui/MInvalidRequestWebException.java
deleted file mode 100644 (file)
index fc6c756..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MInvalidRequestWebException extends MSecurityWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MInvalidRequestWebException() {
-        super();
-    }
-
-    public MInvalidRequestWebException(String message) {
-        super(message);
-    }
-
-    public MInvalidRequestWebException(Throwable error) {
-        super(error);
-    }
-
-    public MInvalidRequestWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MInvalidResourceWebException.java b/src/java/com/marcozanon/macaco/webui/MInvalidResourceWebException.java
deleted file mode 100644 (file)
index 6896654..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MInvalidResourceWebException extends MSecurityWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MInvalidResourceWebException() {
-        super();
-    }
-
-    public MInvalidResourceWebException(String message) {
-        super(message);
-    }
-
-    public MInvalidResourceWebException(Throwable error) {
-        super(error);
-    }
-
-    public MInvalidResourceWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MInvalidSecurityIdWebException.java b/src/java/com/marcozanon/macaco/webui/MInvalidSecurityIdWebException.java
deleted file mode 100644 (file)
index 97890d6..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MInvalidSecurityIdWebException extends MSecurityWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MInvalidSecurityIdWebException() {
-        super();
-    }
-
-    public MInvalidSecurityIdWebException(String message) {
-        super(message);
-    }
-
-    public MInvalidSecurityIdWebException(Throwable error) {
-        super(error);
-    }
-
-    public MInvalidSecurityIdWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MMessagingWebException.java b/src/java/com/marcozanon/macaco/webui/MMessagingWebException.java
deleted file mode 100644 (file)
index 59f745b..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MMessagingWebException extends MWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MMessagingWebException() {
-        super();
-    }
-
-    public MMessagingWebException(String message) {
-        super(message);
-    }
-
-    public MMessagingWebException(Throwable error) {
-        super(error);
-    }
-
-    public MMessagingWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MNoBrowserPageWebException.java b/src/java/com/marcozanon/macaco/webui/MNoBrowserPageWebException.java
deleted file mode 100644 (file)
index d10e8f0..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MNoBrowserPageWebException extends MSetupWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MNoBrowserPageWebException() {
-        super();
-    }
-
-    public MNoBrowserPageWebException(String message) {
-        super(message);
-    }
-
-    public MNoBrowserPageWebException(Throwable error) {
-        super(error);
-    }
-
-    public MNoBrowserPageWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MNoCellContentWebException.java b/src/java/com/marcozanon/macaco/webui/MNoCellContentWebException.java
deleted file mode 100644 (file)
index 2c062fb..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MNoCellContentWebException extends MSetupWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MNoCellContentWebException() {
-        super();
-    }
-
-    public MNoCellContentWebException(String message) {
-        super(message);
-    }
-
-    public MNoCellContentWebException(Throwable error) {
-        super(error);
-    }
-
-    public MNoCellContentWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MNoLogFilterWebException.java b/src/java/com/marcozanon/macaco/webui/MNoLogFilterWebException.java
deleted file mode 100644 (file)
index f4ca1e2..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MNoLogFilterWebException extends MSetupWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MNoLogFilterWebException() {
-        super();
-    }
-
-    public MNoLogFilterWebException(String message) {
-        super(message);
-    }
-
-    public MNoLogFilterWebException(Throwable error) {
-        super(error);
-    }
-
-    public MNoLogFilterWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MNoProcessableMessageWebException.java b/src/java/com/marcozanon/macaco/webui/MNoProcessableMessageWebException.java
deleted file mode 100644 (file)
index 7408183..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MNoProcessableMessageWebException extends MWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MNoProcessableMessageWebException() {
-        super();
-    }
-
-    public MNoProcessableMessageWebException(String message) {
-        super(message);
-    }
-
-    public MNoProcessableMessageWebException(Throwable error) {
-        super(error);
-    }
-
-    public MNoProcessableMessageWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MNoViewContentWebException.java b/src/java/com/marcozanon/macaco/webui/MNoViewContentWebException.java
deleted file mode 100644 (file)
index 951679f..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MNoViewContentWebException extends MSetupWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MNoViewContentWebException() {
-        super();
-    }
-
-    public MNoViewContentWebException(String message) {
-        super(message);
-    }
-
-    public MNoViewContentWebException(Throwable error) {
-        super(error);
-    }
-
-    public MNoViewContentWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MNoViewWebException.java b/src/java/com/marcozanon/macaco/webui/MNoViewWebException.java
deleted file mode 100644 (file)
index badc665..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MNoViewWebException extends MSetupWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MNoViewWebException() {
-        super();
-    }
-
-    public MNoViewWebException(String message) {
-        super(message);
-    }
-
-    public MNoViewWebException(Throwable error) {
-        super(error);
-    }
-
-    public MNoViewWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MNoWidgetIdWebException.java b/src/java/com/marcozanon/macaco/webui/MNoWidgetIdWebException.java
deleted file mode 100644 (file)
index 03e1631..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MNoWidgetIdWebException extends MSetupWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MNoWidgetIdWebException() {
-        super();
-    }
-
-    public MNoWidgetIdWebException(String message) {
-        super(message);
-    }
-
-    public MNoWidgetIdWebException(Throwable error) {
-        super(error);
-    }
-
-    public MNoWidgetIdWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MNullPropertyWebException.java b/src/java/com/marcozanon/macaco/webui/MNullPropertyWebException.java
deleted file mode 100644 (file)
index 6d81d87..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MNullPropertyWebException extends MWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MNullPropertyWebException() {
-        super();
-    }
-
-    public MNullPropertyWebException(String message) {
-        super(message);
-    }
-
-    public MNullPropertyWebException(Throwable error) {
-        super(error);
-    }
-
-    public MNullPropertyWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MResponseWebException.java b/src/java/com/marcozanon/macaco/webui/MResponseWebException.java
deleted file mode 100644 (file)
index 3d82926..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MResponseWebException extends MWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MResponseWebException() {
-        super();
-    }
-
-    public MResponseWebException(String message) {
-        super(message);
-    }
-
-    public MResponseWebException(Throwable error) {
-        super(error);
-    }
-
-    public MResponseWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MSecurityWebException.java b/src/java/com/marcozanon/macaco/webui/MSecurityWebException.java
deleted file mode 100644 (file)
index f44d0e0..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public abstract class MSecurityWebException extends MWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MSecurityWebException() {
-        super();
-    }
-
-    public MSecurityWebException(String message) {
-        super(message);
-    }
-
-    public MSecurityWebException(Throwable error) {
-        super(error);
-    }
-
-    public MSecurityWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MSetupWebException.java b/src/java/com/marcozanon/macaco/webui/MSetupWebException.java
deleted file mode 100644 (file)
index 479aff5..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public abstract class MSetupWebException extends MWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MSetupWebException() {
-        super();
-    }
-
-    public MSetupWebException(String message) {
-        super(message);
-    }
-
-    public MSetupWebException(Throwable error) {
-        super(error);
-    }
-
-    public MSetupWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MUnexpectedMessageWebException.java b/src/java/com/marcozanon/macaco/webui/MUnexpectedMessageWebException.java
deleted file mode 100644 (file)
index 0614866..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MUnexpectedMessageWebException extends MSecurityWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MUnexpectedMessageWebException() {
-        super();
-    }
-
-    public MUnexpectedMessageWebException(String message) {
-        super(message);
-    }
-
-    public MUnexpectedMessageWebException(Throwable error) {
-        super(error);
-    }
-
-    public MUnexpectedMessageWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MUniqueWidgetIdNotAvailableWebException.java b/src/java/com/marcozanon/macaco/webui/MUniqueWidgetIdNotAvailableWebException.java
deleted file mode 100644 (file)
index 4d08d63..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MUniqueWidgetIdNotAvailableWebException extends MSetupWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MUniqueWidgetIdNotAvailableWebException() {
-        super();
-    }
-
-    public MUniqueWidgetIdNotAvailableWebException(String message) {
-        super(message);
-    }
-
-    public MUniqueWidgetIdNotAvailableWebException(Throwable error) {
-        super(error);
-    }
-
-    public MUniqueWidgetIdNotAvailableWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MValidationWebException.java b/src/java/com/marcozanon/macaco/webui/MValidationWebException.java
deleted file mode 100644 (file)
index a6db314..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MValidationWebException extends MWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MValidationWebException() {
-        super();
-    }
-
-    public MValidationWebException(String message) {
-        super(message);
-    }
-
-    public MValidationWebException(Throwable error) {
-        super(error);
-    }
-
-    public MValidationWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MViewNotUnloadableWebException.java b/src/java/com/marcozanon/macaco/webui/MViewNotUnloadableWebException.java
deleted file mode 100644 (file)
index 606a039..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MViewNotUnloadableWebException extends MSetupWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MViewNotUnloadableWebException() {
-        super();
-    }
-
-    public MViewNotUnloadableWebException(String message) {
-        super(message);
-    }
-
-    public MViewNotUnloadableWebException(Throwable error) {
-        super(error);
-    }
-
-    public MViewNotUnloadableWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MViewThreadStoppingWebRuntimeException.java b/src/java/com/marcozanon/macaco/webui/MViewThreadStoppingWebRuntimeException.java
deleted file mode 100644 (file)
index d5525b9..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MViewThreadStoppingWebRuntimeException extends MWebRuntimeException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MViewThreadStoppingWebRuntimeException() {
-        super();
-    }
-
-    public MViewThreadStoppingWebRuntimeException(String message) {
-        super(message);
-    }
-
-    public MViewThreadStoppingWebRuntimeException(Throwable error) {
-        super(error);
-    }
-
-    public MViewThreadStoppingWebRuntimeException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebApplicationContext.java b/src/java/com/marcozanon/macaco/webui/MWebApplicationContext.java
deleted file mode 100644 (file)
index ef3ceab..0000000
+++ /dev/null
@@ -1,266 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.MInformation;
-import com.marcozanon.macaco.MObject;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-import java.io.Writer;
-import java.net.MalformedURLException;
-import java.net.URL;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-public abstract class MWebApplicationContext extends MObject {
-
-    protected MWebApplicationServlet applicationServlet = null;
-    protected HttpServletRequest request = null;
-    protected HttpServletResponse response = null;
-
-    protected String responseContentType = null;
-    protected byte[] responseContent = new byte[0];
-
-    protected boolean roamingMode = false;
-
-    /* */
-
-    public MWebApplicationContext(MWebApplicationServlet applicationServlet, HttpServletRequest request, HttpServletResponse response) {
-        super();
-        //
-        if (null == applicationServlet) {
-            throw new IllegalArgumentException("Invalid 'applicationServlet': null.");
-        }
-        //
-        this.applicationServlet = applicationServlet;
-        this.refreshReferences(request, response);
-    }
-
-    protected void refreshReferences(HttpServletRequest request, HttpServletResponse response) {
-        if (null == request) {
-            throw new IllegalArgumentException("Invalid 'request': null.");
-        }
-        if (null == response) {
-            throw new IllegalArgumentException("Invalid 'response': null.");
-        }
-        //
-        this.request = request;
-        this.response = response;
-    }
-
-    /* Application servlet */
-
-    public MWebApplicationServlet getApplicationServletReference() {
-        return this.applicationServlet;
-    }
-
-    /* Request */
-
-    public HttpServletRequest getRequestReference() {
-        return this.request;
-    }
-
-    /* Response */
-
-    public HttpServletResponse getResponseReference() {
-        return this.response;
-    }
-
-    /* Session */
-
-    public HttpSession getSessionReference() {
-        return this.getRequestReference().getSession(false);
-    }
-
-    /* Response content */
-
-    protected void setResponseContentType(String responseContentType) {
-        if ((null == responseContentType) || ("".equals(responseContentType))) {
-            throw new IllegalArgumentException("Invalid 'responseContentType': null or empty.");
-        }
-        //
-        this.responseContentType = responseContentType;
-    }
-
-    protected String getResponseContentType() {
-        return this.responseContentType;
-    }
-
-    protected void clearResponseContent() {
-        this.responseContentType = null;
-        this.responseContent = new byte[0];
-    }
-
-    protected void addPlainTextResponseContent(String responseContent) throws MResponseWebException {
-        if ((null == responseContent) || ("".equals(responseContent))) {
-            throw new IllegalArgumentException("Invalid 'responseContent': null or empty.");
-        }
-        //
-        try {
-            this.addPlainTextResponseContent(responseContent.getBytes(MInformation.TEXT_ENCODING));
-        }
-        catch (UnsupportedEncodingException exception) { // cannot happen
-        }
-    }
-
-    protected void addPlainTextResponseContent(byte[] responseContent) throws MResponseWebException {
-        String currentResponseContentType = this.getResponseContentType();
-        if ((null != currentResponseContentType) && (!MInformation.HttpContentType.PLAIN.toString().equals(currentResponseContentType))) {
-            throw new MResponseWebException(String.format("Could not add plain text response content: content type already set to: %s.", currentResponseContentType));
-        }
-        //
-        this.setResponseContentType(MInformation.HttpContentType.PLAIN.toString());
-        this.addResponseContent(responseContent);
-    }
-
-    protected void setXhtmlResponseContent(String responseContent) throws MResponseWebException {
-        if ((null == responseContent) || ("".equals(responseContent))) {
-            throw new IllegalArgumentException("Invalid 'responseContent': null or empty.");
-        }
-        //
-        try {
-            this.setXhtmlResponseContent(responseContent.getBytes(MInformation.TEXT_ENCODING));
-        }
-        catch (UnsupportedEncodingException exception) { // cannot happen
-        }
-    }
-
-    protected void setXhtmlResponseContent(byte[] responseContent) throws MResponseWebException {
-        String currentResponseContentType = this.getResponseContentType();
-        if ((null != currentResponseContentType) && (!MInformation.HttpContentType.XHTML.toString().equals(currentResponseContentType))) { // XHtml can only override plain text
-            throw new MResponseWebException(String.format("Could not set Xhtml response content: content type already set to: %s.", currentResponseContentType));
-        }
-        //
-        this.clearResponseContent();
-        this.setResponseContentType(MInformation.HttpContentType.XHTML.toString());
-        this.addResponseContent(responseContent);
-    }
-
-    protected void setRawResponseContent(byte[] responseContent, String responseContentType) throws MResponseWebException {
-        String currentResponseContentType = this.getResponseContentType();
-        if (null != currentResponseContentType) {
-            throw new MResponseWebException(String.format("Could not set raw response content: content type already set to: %s.", currentResponseContentType));
-        }
-        //
-        this.setResponseContentType(responseContentType);
-        this.addResponseContent(responseContent);
-    }
-
-    protected void addResponseContent(byte[] responseContent) {
-        if (null == responseContent) {
-            throw new IllegalArgumentException("Invalid 'responseContent': null.");
-        }
-        //
-        byte[] tmp = new byte[this.responseContent.length + responseContent.length];
-        System.arraycopy(this.responseContent, 0, tmp, 0, this.responseContent.length);
-        System.arraycopy(responseContent, 0, tmp, this.responseContent.length, responseContent.length);
-        this.responseContent = tmp;
-    }
-
-    protected byte[] getResponseContent() {
-        byte[] tmp = new byte[this.responseContent.length];
-        System.arraycopy(this.responseContent, 0, tmp, 0, this.responseContent.length);
-        return tmp;
-    }
-
-    /* Notification area */
-
-    public void addNotificationAreaMessage(boolean error, String message) throws MResponseWebException {
-        this.addNotificationAreaMessage(error, message, false);
-    }
-
-    public void addNotificationAreaMessage(boolean error, String message, boolean framedOutput) throws MResponseWebException {
-        if ((null == message) || ("".equals(message))) {
-            throw new IllegalArgumentException("Invalid 'message': null or empty.");
-        }
-        //
-        if (framedOutput) {
-            String NL = System.getProperty("line.separator");
-            StringBuilder content = new StringBuilder("");
-            content.append(String.format("<?xml version=\"1.0\" encoding=\"%s\" ?>", MInformation.TEXT_ENCODING) + NL);
-            content.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" + NL);
-            content.append("<html xmlns=\"http://www.w3.org/1999/xhtml\">" + NL);
-            content.append(NL);
-            content.append("    <head>" + NL);
-            content.append(String.format("        <meta http-equiv=\"Content-type\" content=\"application/xhtml+xml; charset=%s\" />", MInformation.TEXT_ENCODING) + NL);
-            content.append("        <title />" + NL);
-            content.append("    </head>" + NL);
-            content.append(NL);
-            content.append("    <body>" + NL);
-            content.append("        <script type=\"text/javascript\">" + NL);
-            content.append("        // <![CDATA[" + NL);
-            content.append(String.format("            parent.m_notificationArea.addMessage(%s, '%s');", error, MWebString.getJavascriptEscapedString(MWebString.getXhtmlEscapedString(message))));
-            content.append("        // ]]>" + NL);
-            content.append("        </script>" + NL);
-            content.append("    </body>" + NL);
-            content.append(NL);
-            content.append("</html>" + NL);
-            try {
-                HttpServletResponse response = this.getResponseReference();
-                response.setContentType(MInformation.HttpContentType.XHTML.toString());
-                Writer writer = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), MInformation.TEXT_ENCODING));
-                writer.write(content.toString());
-                writer.flush();
-                writer.close();
-            }
-            catch (UnsupportedEncodingException exception) { // cannot happen
-            }
-            catch (IOException exception) { // put here not to bypass UnsupportedEncodingException
-                throw new MResponseWebException("Could not add notification area message.", exception);
-            }
-        }
-        else {
-            this.addPlainTextResponseContent(String.format("m_notificationArea.addMessage(%s, '%s');", error, MWebString.getJavascriptEscapedString(MWebString.getXhtmlEscapedString(message))));
-        }
-    }
-
-    /* Roaming mode */
-
-    public void setRoamingMode(boolean roamingMode) {
-        this.roamingMode = roamingMode;
-    }
-
-    public boolean getRoamingMode() {
-        return this.roamingMode;
-    }
-
-    /* Context full Url */
-
-    public String getContextFullUrl() {
-        HttpServletRequest request = this.getRequestReference();
-        String contextFullUrl = null;
-        try {
-            contextFullUrl = (new URL(request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath())).toString();
-        }
-        catch (MalformedURLException exception) { // cannot happen
-        }
-        return contextFullUrl;
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebApplicationServlet.java b/src/java/com/marcozanon/macaco/webui/MWebApplicationServlet.java
deleted file mode 100644 (file)
index d047252..0000000
+++ /dev/null
@@ -1,378 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.MHttpServlet;
-import com.marcozanon.macaco.MInformation;
-import com.marcozanon.macaco.json.MInvalidValueJsonException;
-import com.marcozanon.macaco.json.MJsonNumber;
-import com.marcozanon.macaco.json.MJsonObject;
-import com.marcozanon.macaco.json.MJsonString;
-import com.marcozanon.macaco.logging.MLogFilter;
-import com.marcozanon.macaco.logging.MLoggingException;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-public abstract class MWebApplicationServlet extends MHttpServlet {
-
-    private static final long serialVersionUID = 0L;
-
-    protected static enum ErrorMode {
-        CLEAN,
-        SILENT,
-        DEBUG
-    };
-
-    protected boolean debugMode = false;
-
-    protected MLogFilter logFilter = null;
-
-    /* */
-
-    public void destroy() {
-        try {
-            this.getLogFilterReference().close();
-        }
-        catch (MLoggingException exception) {
-        }
-        catch (MNoLogFilterWebException exception) {
-        }
-    }
-
-    /* Debug mode */
-
-    public void setDebugMode(boolean debugMode) {
-        this.debugMode = debugMode;
-    }
-
-    public boolean getDebugMode() {
-        return this.debugMode;
-    }
-
-    /* Logging */
-
-    public void setLogFilter(MLogFilter logFilter) {
-        this.logFilter = logFilter;
-    }
-
-    public MLogFilter getLogFilterReference() throws MNoLogFilterWebException {
-        if (null == this.logFilter) {
-            throw new MNoLogFilterWebException("Invalid log filter: null.");
-        }
-        //
-        return this.logFilter;
-    }
-
-    public void appendLogMessage(MLogFilter.Threshold level, String message) {
-        try {
-            this.getLogFilterReference().appendMessage(level, message);
-        }
-        catch (MLoggingException exception) {
-            this.log("[FALLBACK] " + message);
-        }
-        catch (MNoLogFilterWebException exception) {
-            this.log("[FALLBACK] " + message);
-        }
-    }
-
-    /* Requests */
-
-    protected void doGet(HttpServletRequest request, HttpServletResponse response) {
-        this.processRequest(request, response);
-    }
-
-    protected void doPost(HttpServletRequest request, HttpServletResponse response) {
-        this.processRequest(request, response);
-    }
-
-    protected void onRequestPreprocessing(HttpServletRequest request, HttpServletResponse response) throws MApplicationServletWebException {
-    }
-
-    protected abstract void processCustomRequest(HttpServletRequest request, HttpServletResponse response, MWebBrowserPage browserPage);
-
-    protected void processRequest(HttpServletRequest request, HttpServletResponse response) {
-        try {
-            request.setCharacterEncoding(MInformation.TEXT_ENCODING);
-            //
-            this.onRequestPreprocessing(request, response);
-            // check session security and refresh session parameters
-            MWebBrowserPage browserPage = this.getSafeBrowserPageReference(request, response);
-            // check for request type
-            String pathInfo = request.getPathInfo();
-            if (null == pathInfo) { // standard request
-                synchronized (browserPage) {
-                    // forward request
-                    browserPage.onRequestPreprocessing();
-                    browserPage.processRequest();
-                    // return standard response
-                    try {
-                        this.returnStandardResponse(response, browserPage.getApplicationContextReference().getResponseContentType(), browserPage.getApplicationContextReference().getResponseContent(), (null != request.getParameter("message") ? true : false));
-                    }
-                    catch (UnsupportedEncodingException exception) { // cannot happen
-                    }
-                }
-            }
-            else if (pathInfo.startsWith("/custom")) { // custom request
-                synchronized (browserPage) {
-                    this.processCustomRequest(request, response, browserPage);
-                    return;
-                }
-            }
-            else if ("/null".equals(pathInfo)) { // null request (used by some widgets)
-                return;
-            }
-            else if ("/ping".equals(pathInfo)) { // ping request (used to prevent session timeout)
-                response.setContentType(MInformation.HttpContentType.PLAIN.toString());
-                return;
-            }
-            else if (pathInfo.startsWith("/coreResources/")) { // resource request
-                String resourceInfo = pathInfo.substring("/coreResources/".length()).replace("\\", "/");
-                if ((resourceInfo.startsWith("/")) || (resourceInfo.startsWith("\\")) || (resourceInfo.contains("..")) || (resourceInfo.contains("~"))) {
-                    throw new MInvalidResourceWebException(String.format("Invalid resource request: %s.", pathInfo));
-                }
-                String httpContentType = null;
-                if (resourceInfo.toLowerCase().endsWith(".css")) { // Css resource
-                    httpContentType = MInformation.HttpContentType.CSS.toString();
-                }
-                else if (resourceInfo.toLowerCase().endsWith(".gif")) { // Gif resource
-                    httpContentType = MInformation.HttpContentType.GIF.toString();
-                }
-                else if (resourceInfo.toLowerCase().endsWith(".htm")) { // TinyMCE (X)html resource
-                    httpContentType = MInformation.HttpContentType.HTML.toString();
-                }
-                else if ((resourceInfo.toLowerCase().endsWith(".jpg")) || (resourceInfo.toLowerCase().endsWith(".jpeg"))) { // Jpeg resource
-                    httpContentType = MInformation.HttpContentType.JPEG.toString();
-                }
-                else if (resourceInfo.toLowerCase().endsWith(".js")) { // Javascript resource
-                    httpContentType = MInformation.HttpContentType.JAVASCRIPT.toString();
-                }
-                else if (resourceInfo.toLowerCase().endsWith(".png")) { // Png resource
-                    httpContentType = MInformation.HttpContentType.PNG.toString();
-                }
-                else if (resourceInfo.toLowerCase().endsWith(".txt")) { // Plain text resource
-                    httpContentType = MInformation.HttpContentType.PLAIN.toString();
-                }
-                else {
-                    throw new MInvalidResourceWebException(String.format("Invalid resource request: %s.", pathInfo));
-                }
-                this.returnRawResponse(response, httpContentType, MInformation.getCoreResource(resourceInfo));
-            }
-            else {
-                throw new MInvalidRequestWebException(String.format("Invalid request: %s.", pathInfo));
-            }
-        }
-        catch (Exception exception) {
-            this.returnErrorResponse(response, exception, (null != request.getParameter("message") ? true : false));
-        }
-    }
-
-    /* Responses */
-
-    protected void returnStandardResponse(HttpServletResponse response, String contentType, byte[] content, boolean ajaxMode) throws IOException {
-        if ((null == contentType) || ("".equals(contentType))) {
-            contentType = MInformation.HttpContentType.PLAIN.toString();
-        }
-        // prepare response content
-        byte[] responseContent = null;
-        if (ajaxMode) {
-            MJsonObject returnValue = null;
-            try {
-                returnValue = new MJsonObject();
-                returnValue.setValue("errorMode", new MJsonNumber(MWebApplicationServlet.ErrorMode.CLEAN.ordinal()));
-                MJsonString jsonParameter = new MJsonString();
-                jsonParameter.setValue(new String(content, MInformation.TEXT_ENCODING));
-                returnValue.setValue("parameter", jsonParameter);
-            }
-            catch (MInvalidValueJsonException exception) { // cannot happen
-            }
-            responseContent = returnValue.getFormattedValue().getBytes(MInformation.TEXT_ENCODING);
-        }
-        else {
-            responseContent = content;
-        }
-        //
-        try {
-            this.returnResponse(response, contentType, responseContent);
-        }
-        catch (UnsupportedEncodingException exception) { // cannot happen
-        }
-    }
-
-    protected void returnErrorResponse(HttpServletResponse response, Exception content, boolean ajaxMode) {
-        // log exception
-        this.appendLogMessage(MLogFilter.Threshold.DEBUG, String.format("Exception: %s.", MInformation.getExceptionAsString(content)));
-        // special check: maybe the client fired two or more consecutive (asynchronous) messages and some of them became unfireable later?
-        if (content instanceof MUnexpectedMessageWebException) {
-            return;
-        }
-        // set error mode
-        MWebApplicationServlet.ErrorMode errorMode = MWebApplicationServlet.ErrorMode.SILENT;
-        if (this.getDebugMode()) {
-            errorMode = MWebApplicationServlet.ErrorMode.DEBUG;
-        }
-        // prepare response content
-        byte[] responseContent = null;
-        try {
-            if (MWebApplicationServlet.ErrorMode.DEBUG == errorMode) {
-                if (ajaxMode) {
-                    MJsonObject returnValue = null;
-                    try {
-                        returnValue = new MJsonObject();
-                        returnValue.setValue("errorMode", new MJsonNumber(errorMode.ordinal()));
-                        MJsonString jsonParameter = new MJsonString();
-                        if (null != content.getMessage()) {
-                            jsonParameter.setValue(content.getClass().getName() + ": " + content.getMessage());
-                        }
-                        else {
-                            jsonParameter.setValue(content.getClass().getName());
-                        }
-                        returnValue.setValue("parameter", jsonParameter);
-                    }
-                    catch (MInvalidValueJsonException exception) { // should not happen
-                    }
-                    responseContent = returnValue.getFormattedValue().getBytes(MInformation.TEXT_ENCODING);
-                }
-                else {
-                    if (null != content.getMessage()) {
-                        responseContent = (content.getClass().getName() + ": " + content.getMessage()).getBytes(MInformation.TEXT_ENCODING);
-                    }
-                    else {
-                        responseContent = (content.getClass().getName()).getBytes(MInformation.TEXT_ENCODING);
-                    }
-                }
-            }
-            else {
-                if (ajaxMode) {
-                    responseContent = "An error occurred while processing the message.".getBytes(MInformation.TEXT_ENCODING);
-                }
-                else {
-                    responseContent = "An error occurred while processing the request.".getBytes(MInformation.TEXT_ENCODING);
-                }
-            }
-        }
-        catch (UnsupportedEncodingException exception) { // cannot happen
-        }
-        //
-        try {
-            this.returnResponse(response, MInformation.HttpContentType.PLAIN.toString(), responseContent);
-        }
-        catch (UnsupportedEncodingException exception) { // cannot happen
-        }
-        catch (IOException exception) { // put here not to bypass UnsupportedEncodingException
-        }
-    }
-
-    protected void returnRawResponse(HttpServletResponse response, String contentType, byte[] content) throws IOException {
-        this.returnResponse(response, contentType, content);
-    }
-
-    protected void returnResponse(HttpServletResponse response, String contentType, byte[] content) throws IOException { // some lines taken from http://onjava.com/pub/a/onjava/excerpt/jebp_3/index2.html
-        if (null == response) {
-            throw new IllegalArgumentException("Invalid 'response': null.");
-        }
-        if ((null == contentType) || ("".equals(contentType))) {
-            throw new IllegalArgumentException("Invalid 'contentType': null or empty.");
-        }
-        if (null == content) {
-            throw new IllegalArgumentException("Invalid 'content': null.");
-        }
-        // disable cache
-        response.setHeader("Expires", "Sun, 01 Nov 1992 02:00:00 GMT"); // already expired
-        response.setHeader("Pragma", "no-cache"); // standard HTTP/1.0 no-cache header
-        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); // standard HTTP/1.1 no-cache header
-        // send response
-        response.setContentType(contentType);
-        response.getOutputStream().write(content);
-    }
-
-    /* Application context */
-
-    protected abstract MWebApplicationContext getInitializedApplicationContext(HttpServletRequest request, HttpServletResponse response) throws MApplicationServletWebException; // abstract => not static => no other static methods in this class
-
-    /* Browser page */
-
-    protected abstract MWebBrowserPage getInitializedBrowserPage(MWebApplicationContext applicationContext) throws MApplicationServletWebException; // abstract => not static => no other static methods in this class
-
-    /* Session */
-
-    protected synchronized MWebBrowserPage getSafeBrowserPageReference(HttpServletRequest request, HttpServletResponse response) throws MApplicationServletWebException, MInvalidRemoteIpAddressWebException {
-        if (null == request) {
-            throw new IllegalArgumentException("Invalid 'request': null.");
-        }
-        //
-        MWebApplicationContext applicationContext = null;
-        MWebBrowserPage browserPage = null;
-        HttpSession session = request.getSession(false);
-        if ((null == session) || (null == (MWebApplicationContext)session.getAttribute("m_applicationContext")) || (null == (MWebBrowserPage)session.getAttribute("m_browserPage"))) { // no previous valid session
-            if (null != session) {
-                // clear complete session (including persistent Serializable objects)
-                session.invalidate();
-            }
-            // setup whole new session
-            session = request.getSession();
-            response.setHeader("Set-Cookie", "JSESSIONID=" + session.getId() + "; HttpOnly");
-            session.setAttribute("m_remoteAddress", request.getRemoteAddr());
-            try {
-                // application context
-                applicationContext = this.getInitializedApplicationContext(request, response);
-                if (null == applicationContext) {
-                    throw new MApplicationServletWebException("Invalid application context: null.");
-                }
-                session.setAttribute("m_applicationContext", applicationContext);
-                // browser page
-                browserPage = this.getInitializedBrowserPage(applicationContext);
-                if (null == browserPage) {
-                    throw new MApplicationServletWebException("Invalid browser page: null.");
-                }
-                session.setAttribute("m_browserPage", browserPage);
-            }
-            catch (MApplicationServletWebException exception) {
-                session.invalidate();
-                throw new MApplicationServletWebException("Session not initialized.", exception);
-            }
-        }
-        else { // valid session
-            // retrieve application context, refresh references and clear response content
-            applicationContext = ((MWebApplicationContext)session.getAttribute("m_applicationContext"));
-            applicationContext.refreshReferences(request, response);
-            applicationContext.clearResponseContent();
-            // retrieve browser page
-            browserPage = ((MWebBrowserPage)session.getAttribute("m_browserPage"));
-            // check whether session and current ip match
-            String sessionRemoteAddress = (String)session.getAttribute("m_remoteAddress");
-            String currentRemoteAddress = request.getRemoteAddr();
-            if ((!applicationContext.getRoamingMode()) && (!sessionRemoteAddress.equals(currentRemoteAddress))) {
-                throw new MInvalidRemoteIpAddressWebException(String.format("Invalid request: no match for session (%s) and current (%s) ip addresses.", sessionRemoteAddress, currentRemoteAddress));
-            }
-        }
-        //
-        return browserPage;
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebBorder.java b/src/java/com/marcozanon/macaco/webui/MWebBorder.java
deleted file mode 100644 (file)
index b331732..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.MObject;
-
-public class MWebBorder extends MObject {
-
-    public static enum Style {
-        DASHED("dashed"),
-        DOTTED("dotted"),
-        DOUBLE("double"),
-        GROOVE("groove"),
-        INSET("inset"),
-        OUTSET("outset"),
-        RIDGE("ridge"),
-        SOLID("solid");
-        private String name = null;
-        private Style(String name) {
-            this.name = name;
-        }
-        public String toString() {
-            return this.name;
-        }
-    };
-
-    protected MWebMeasure width = null;
-    protected MWebBorder.Style style = null;
-    protected MWebColor color = null;
-
-    /* */
-
-    public MWebBorder(MWebMeasure width, MWebBorder.Style style, MWebColor color) {
-        super();
-        //
-        if (null == width) {
-            throw new IllegalArgumentException("Invalid 'width': null.");
-        }
-        if (null == style) {
-            throw new IllegalArgumentException("Invalid 'style': null.");
-        }
-        if (null == color) {
-            throw new IllegalArgumentException("Invalid 'color': null.");
-        }
-        //
-        this.width = width;
-        this.style = style;
-        this.color = color;
-    }
-
-    public MWebBorder clone() {
-        return new MWebBorder(this.getWidthReference().clone(), this.getStyle(), this.getColorReference().clone());
-    }
-
-    /* Border */
-
-    protected MWebMeasure getWidthReference() {
-        return this.width;
-    }
-
-    protected MWebBorder.Style getStyle() {
-        return this.style;
-    }
-
-    protected MWebColor getColorReference() {
-        return this.color;
-    }
-
-    public Object[] getValue() {
-        Object[] value = new Object[3];
-        value[0] = this.getWidthReference().clone();
-        value[1] = this.getStyle();
-        value[2] = this.getColorReference().clone();
-        return value;
-    }
-
-    public String getFormattedValue() {
-        return this.getWidthReference().getFormattedValue() + " " + this.getStyle().toString() + " " + this.getColorReference().getFormattedValue();
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebBreadcrumbs.java b/src/java/com/marcozanon/macaco/webui/MWebBreadcrumbs.java
deleted file mode 100644 (file)
index 961cc99..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-
-public class MWebBreadcrumbs extends MWebDirectWidget {
-
-    protected String prefix = "";
-
-    /* */
-
-    public MWebBreadcrumbs(MWebApplicationContext applicationContext, String prefix) {
-        super(applicationContext);
-        //
-        this.setPrefix(prefix);
-    }
-
-    /* Prefix */
-
-    public void setPrefix(String prefix) {
-        this.setPrefix(prefix, true);
-    }
-
-    protected void setPrefix(String prefix, boolean refreshMode) {
-        if (null == prefix) {
-            throw new IllegalArgumentException("Invalid 'prefix': null.");
-        }
-        //
-        this.prefix = prefix;
-        //
-        if (refreshMode) {
-            try {
-                this.refresh(); // must refresh everything
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-            catch (MUniqueWidgetIdNotAvailableWebException exception) {
-            }
-        }
-    }
-
-    public String getPrefix() {
-        return this.prefix;
-    }
-
-    /* Refresh */
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<div class=\"MWebBreadcrumbs %s\" style=\"display: inline-block;\" id=\"%s\"></div>'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), this.getId()));
-        //
-        super.refresh();
-        //
-        StringBuilder content = new StringBuilder("");
-        content.append(String.format("<span class=\"MWebBreadcrumbPrefix %s\">%s</span>", customClasses, MWebString.getXhtmlEscapedString(this.getPrefix())));
-        LinkedList<String> viewBreadcrumbs = this.getViewReference().getBrowserPageReference().getViewBreadcrumbs();
-        for (int t = 0; t < viewBreadcrumbs.size(); t++) {
-            content.append(" ");
-            if (t > 0) {
-                content.append("» ");
-            }
-            if (t < (viewBreadcrumbs.size() - 1))  {
-                String onItemSelectionFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onItemSelection', {'viewCount': '%s'});", this.getId(), viewBreadcrumbs.size() - 1 - t);
-                content.append(String.format("<span class=\"MWebBreadcrumbItem %s\" onclick=\"%s\">%s</span>", customClasses, onItemSelectionFunction, MWebString.getXhtmlEscapedString(viewBreadcrumbs.get(t))));
-            }
-            else {
-                content.append(String.format("<span class=\"MWebBreadcrumbLastItem %s\">%s</span>", customClasses, MWebString.getXhtmlEscapedString(viewBreadcrumbs.get(t))));
-            }
-        }
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(content.toString())));
-    }
-
-    /* Messages */
-
-    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
-        super.processMessage(event, parameters);
-        //
-        if ("onItemSelection".equals(event)) {
-            if (!this.getVisibleMode()) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
-            }
-            String viewCount = parameters.get("viewCount");
-            if (null == viewCount) {
-                throw new MUnexpectedMessageWebException("Invalid message: view count parameter not available.");
-            }
-            int v = 0;
-            try {
-                v = Integer.parseInt(viewCount);
-            }
-            catch (NumberFormatException exception) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: view count parameter not recognized.", viewCount)); // no need to propagate exception
-            }
-            this.onItemSelection(v);
-        }
-        else if ("onRefresh".equals(event)) {
-            this.onRefresh();
-        }
-        else {
-            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
-        }
-    }
-
-    public void onItemSelection(int viewCount) {
-        try {
-            this.getViewReference().getBrowserPageReference().unloadViewThreads(null, viewCount, null);
-        }
-        catch (MNoBrowserPageWebException exception) {
-        }
-        catch (MNoViewWebException exception) {
-        }
-        catch (MViewNotUnloadableWebException exception) {
-        }
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebBrowserPage.java b/src/java/com/marcozanon/macaco/webui/MWebBrowserPage.java
deleted file mode 100644 (file)
index e06fd06..0000000
+++ /dev/null
@@ -1,440 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.MInformation;
-import com.marcozanon.macaco.MObject;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.Random;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-public abstract class MWebBrowserPage extends MObject {
-
-    protected MWebApplicationContext applicationContext = null;
-
-    protected int securityId = -1;
-    protected String author = "";
-    protected String cssSource = null;
-
-    protected String lastViewThreadReturnValue = null;
-    protected Exception lastViewThreadException = null;
-    protected MWebMessage processableMessage = null;
-    protected Object stoppingViewThreadCountMutexObject = new Object();
-    protected int stoppingViewThreadCount = 0;
-    protected boolean forcedLoopMode = false;
-    protected LinkedList<Thread> viewThreads = new LinkedList<Thread>();
-
-    protected LinkedList<String> viewBreadcrumbs = new LinkedList<String>();
-
-    /* */
-
-    public MWebBrowserPage(MWebApplicationContext applicationContext, MWebView defaultView) {
-        super();
-        //
-        if (null == applicationContext) {
-            throw new IllegalArgumentException("Invalid 'applicationContext': null.");
-        }
-        //
-        this.applicationContext = applicationContext;
-        this.loadViewThread(defaultView, false);
-    }
-
-    /* Application context */
-
-    public MWebApplicationContext getApplicationContextReference() {
-        return this.applicationContext;
-    }
-
-    /* Security id */
-
-    protected void resetSecurityId() {
-        this.securityId = (new Random((new Date()).getTime())).nextInt(Integer.MAX_VALUE);
-    }
-
-    protected int getSecurityId() {
-        return this.securityId;
-    }
-
-    /* Author */
-
-    public void setAuthor(String author) {
-        if (null == author) {
-            throw new IllegalArgumentException("Invalid 'author': null.");
-        }
-        //
-        this.author = author;
-        try {
-            this.refreshAuthor();
-        }
-        catch (MResponseWebException exception) {
-        }
-    }
-
-    public String getAuthor() {
-        return this.author;
-    }
-
-    /* Css */
-
-    public void setCssSource(String cssSource) {
-        this.cssSource = cssSource;
-        try {
-            this.refreshCssSource();
-        }
-        catch (MResponseWebException exception) {
-        }
-    }
-
-    public String getCssSource() {
-        return this.cssSource;
-    }
-
-    /* Views threads */
-
-    protected void setLastViewThreadReturnValue(String lastViewThreadReturnValue) {
-        this.lastViewThreadReturnValue = lastViewThreadReturnValue;
-    }
-
-    protected String getLastViewThreadReturnValue() {
-        return this.lastViewThreadReturnValue;
-    }
-
-    protected void setLastViewThreadException(Exception lastViewThreadException) {
-        this.lastViewThreadException = lastViewThreadException;
-    }
-
-    protected Exception getLastViewThreadExceptionReference() {
-        return this.lastViewThreadException;
-    }
-
-    protected void setProcessableMessage(MWebMessage processableMessage) {
-        if (null == processableMessage) {
-            throw new IllegalArgumentException("Invalid 'processableMessage': null.");
-        }
-        //
-        this.processableMessage = processableMessage;
-    }
-
-    protected MWebMessage getProcessableMessageReference() {
-        return this.processableMessage;
-    }
-
-    protected MWebMessage getProcessableMessage() throws MNoProcessableMessageWebException {
-        if (null == this.getProcessableMessageReference()) {
-            throw new MNoProcessableMessageWebException("Invalid processable message: reference null.");
-        }
-        //
-        return this.getProcessableMessageReference().clone();
-    }
-
-    protected void setStoppingViewThreadCount(int stoppingViewThreadCount) {
-        if (stoppingViewThreadCount < 0) {
-            throw new IllegalArgumentException(String.format("Invalid 'stoppingViewThreadCount': %s.", stoppingViewThreadCount));
-        }
-        //
-        synchronized (this.stoppingViewThreadCountMutexObject) {
-            this.stoppingViewThreadCount = stoppingViewThreadCount;
-        }
-    }
-
-    protected void decrementStoppingViewThreadCount() {
-        synchronized (this.stoppingViewThreadCountMutexObject) {
-            this.stoppingViewThreadCount--;
-        }
-    }
-
-    protected int getStoppingViewThreadCount() {
-        synchronized (this.stoppingViewThreadCountMutexObject) {
-            return this.stoppingViewThreadCount;
-        }
-    }
-
-    protected void setForcedLoopMode(boolean forcedLoopMode) {
-        this.forcedLoopMode = forcedLoopMode;
-    }
-
-    protected boolean getForcedLoopMode() {
-        return this.forcedLoopMode;
-    }
-
-    protected LinkedList<Thread> getViewThreadsReference() {
-        return this.viewThreads;
-    }
-
-    protected void loadViewThread(MWebView view) {
-        this.loadViewThread(view, true);
-    }
-
-    protected void loadViewThread(MWebView view, boolean start) {
-        if (null == view) {
-            throw new IllegalArgumentException("Invalid 'view': null.");
-        }
-        //
-        view.setBrowserPage(this);
-        //
-        synchronized (this.getViewThreadsReference()) {
-            this.setLastViewThreadReturnValue(null);
-            this.setLastViewThreadException(null);
-            //
-            this.getViewThreadsReference().add(new Thread(view));
-            this.getViewBreadcrumbsReference().add(view.getBreadcrumb());
-            //
-            if (start) {
-                try {
-                    this.setProcessableMessage(new MWebMessage("{\"widgetId\": \"\", \"event\": \"onRefresh\", \"parameters\": {}}"));
-                }
-                catch (MMessagingWebException exception) { // cannot happen
-                }
-                this.getCurrentViewThreadReference().start();
-            }
-        }
-    }
-
-    protected void unloadViewThreads(String lastViewThreadReturnValue, int viewThreadCount, MWebView replacingView) throws MViewNotUnloadableWebException {
-        if ((null == lastViewThreadReturnValue) && (viewThreadCount < 1) && (null == replacingView)) {
-            throw new IllegalArgumentException("Invalid call mode: (null, < 1, null).");
-        }
-        if (viewThreadCount < 1) {
-            throw new IllegalArgumentException(String.format("Invalid 'viewThreadCount': %s.", viewThreadCount));
-        }
-        else if ((this.getViewThreadCount() <= viewThreadCount) && (null == replacingView)) {
-            throw new MViewNotUnloadableWebException("Invalid 'viewThreadCount': size exceeded.");
-        }
-        //
-        synchronized (this.getViewThreadsReference()) {
-            this.setForcedLoopMode(true);
-            //
-            this.setLastViewThreadReturnValue(lastViewThreadReturnValue);
-            this.setLastViewThreadException(null);
-            //
-            this.setStoppingViewThreadCount(viewThreadCount - 1); // calling view excluded
-            //
-            for (int x = viewThreadCount; x > 0; x--) {
-                Thread t = this.getViewThreadsReference().get(this.getViewThreadCount() - 1);
-                this.getViewThreadsReference().remove(this.getViewThreadCount() - 1);
-                this.getViewBreadcrumbsReference().remove(this.getViewBreadcrumbsReference().size() - 1);
-                synchronized (t) {
-                    t.notify();
-                }
-            }
-            while (this.getStoppingViewThreadCount() > 0) {
-            }
-            //
-            if (null != replacingView) {
-                replacingView.setBrowserPage(this);
-                this.loadViewThread(replacingView, false);
-            }
-            //
-            if (Thread.State.NEW == this.getCurrentViewThreadReference().getState()) {
-                try {
-                    this.setProcessableMessage(new MWebMessage("{\"widgetId\": \"\", \"event\": \"onRefresh\", \"parameters\": {}}"));
-                }
-                catch (MMessagingWebException exception) { // cannot happen
-                }
-                this.getCurrentViewThreadReference().start();
-            }
-            else {
-                synchronized (this.getCurrentViewThreadReference()) {
-                    this.getCurrentViewThreadReference().notify();
-                }
-            }
-            //
-            this.setForcedLoopMode(false);
-        }
-    }
-
-    protected int getViewThreadCount() {
-        synchronized (this.getViewThreadsReference()) {
-            return this.getViewThreadsReference().size();
-        }
-    }
-
-    protected Thread getCurrentViewThreadReference() {
-        synchronized (this.getViewThreadsReference()) {
-            return this.getViewThreadsReference().get(this.getViewThreadCount() - 1);
-        }
-    }
-
-    /* Breadcrumbs */
-
-    protected LinkedList<String> getViewBreadcrumbsReference() {
-        return this.viewBreadcrumbs;
-    }
-
-    public LinkedList<String> getViewBreadcrumbs() {
-        LinkedList<String> viewBreadcrumbs = new LinkedList<String>();
-        for (String viewBreadcrumb: this.getViewBreadcrumbsReference()) {
-            viewBreadcrumbs.add(viewBreadcrumb);
-        }
-        return viewBreadcrumbs;
-    }
-
-    /* Redirection */
-
-    public void redirect(String url) throws MResponseWebException {
-        if ((null == url) || ("".equals(url))) {
-            throw new IllegalArgumentException("Invalid 'url': null or empty.");
-        }
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("window.location = '%s';", MWebString.getJavascriptEscapedString(url)));
-    }
-
-    /* Refresh */
-
-    protected void refresh() throws MResponseWebException {
-        this.resetSecurityId();
-        //
-        String cssSource = MWebString.getXhtmlEscapedString(this.getCssSource());
-        if (null == cssSource) {
-            cssSource = String.format("%s/coreResources/css/default.css", this.getApplicationContextReference().getRequestReference().getRequestURL());
-        }
-        //
-        String NL = System.getProperty("line.separator");
-        StringBuilder content = new StringBuilder("");
-        content.append(String.format("<?xml version=\"1.0\" encoding=\"%s\" ?>", MInformation.TEXT_ENCODING) + NL);
-        content.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" + NL);
-        content.append("<html xmlns=\"http://www.w3.org/1999/xhtml\">" + NL);
-        content.append(NL);
-        content.append("    <head>" + NL);
-        content.append(String.format("        <meta name=\"author\" content=\"%s\" />", MWebString.getXhtmlEscapedString(this.getAuthor())) + NL);
-        content.append(String.format("        <meta name=\"generator\" content=\"%s\" />", MWebString.getXhtmlEscapedString(MInformation.getMacacoFullName())) + NL);
-        content.append(String.format("        <meta http-equiv=\"Content-type\" content=\"%s\" />", MInformation.HttpContentType.XHTML.toString()) + NL);
-        content.append(String.format("        <link rel=\"stylesheet\" type=\"text/css\" href=\"%s\" />", cssSource) + NL);
-        content.append("        <title>Loading...</title>" + NL);
-        content.append(String.format("        <script type=\"text/javascript\" src=\"%s/coreResources/javascript/$.js\" />", this.getApplicationContextReference().getRequestReference().getRequestURL()) + NL);
-        content.append(String.format("        <script type=\"text/javascript\" src=\"%s/coreResources/javascript/MWebCustomJsonHelper.js\" />", this.getApplicationContextReference().getRequestReference().getRequestURL()) + NL);
-        content.append(String.format("        <script type=\"text/javascript\" src=\"%s/coreResources/javascript/MWebMessageInterface.js\" />", this.getApplicationContextReference().getRequestReference().getRequestURL()) + NL);
-        content.append(String.format("        <script type=\"text/javascript\" src=\"%s/coreResources/javascript/MWebNotificationArea.js\" />", this.getApplicationContextReference().getRequestReference().getRequestURL()) + NL);
-        content.append(String.format("        <script type=\"text/javascript\" src=\"%s/coreResources/javascript/TinyMCE/tiny_mce.js\" />", this.getApplicationContextReference().getRequestReference().getRequestURL()) + NL);
-        content.append("        <style type=\"text/css\" id=\"m_styleSheet\">" + NL);
-        content.append("        </style>" + NL);
-        content.append("        <script type=\"text/javascript\">" + NL);
-        content.append("        // <![CDATA[" + NL);
-        content.append("            if ('Gecko' == $getRenderingEngine()) {" + NL);
-        content.append("                $('m_styleSheet').innerHTML = '* { -moz-box-sizing: border-box; }';" + NL);
-        content.append("            }" + NL);
-        content.append("            else if ('Ie' == $getRenderingEngine()) {" + NL);
-        content.append("                $('m_styleSheet').innerHTML = '* { -ms-box-sizing: border-box; }';" + NL);
-        content.append("            }" + NL);
-        content.append("            else if ('Webkit' == $getRenderingEngine()) {" + NL);
-        content.append("                $('m_styleSheet').innerHTML = '* { -webkit-box-sizing: border-box; }';" + NL);
-        content.append("            }" + NL);
-        content.append("            else {" + NL);
-        content.append("                $('m_styleSheet').innerHTML = '* { box-sizing: border-box; }';" + NL);
-        content.append("            }" + NL);
-        content.append("            var m_notificationArea = new MWebNotificationArea();" + NL);
-        content.append("            var m_waitingIcon = new Image();" + NL);
-        content.append(String.format("            m_waitingIcon.src = '%s/coreResources/gif/waitingIcon.gif';", this.getApplicationContextReference().getRequestReference().getRequestURL()) + NL);
-        content.append(String.format("            var m_messageInterface = new MWebMessageInterface('%s', '%s', m_waitingIcon);", this.getApplicationContextReference().getRequestReference().getRequestURL(), this.getSecurityId()) + NL);
-        content.append(String.format("            setInterval('m_messageInterface.sendPingRequest();', %s * 1000);", (int)Math.floor(this.getApplicationContextReference().getRequestReference().getSession(false).getMaxInactiveInterval() / 2)) + NL);
-        content.append("        // ]]>" + NL);
-        content.append("        </script>" + NL);
-        content.append("    </head>" + NL);
-        content.append(NL);
-        content.append("    <body onload=\"javascript: m_messageInterface.fireMessage('', 'onRefresh', {});\" onmousemove=\"javascript: m_notificationArea.hide();\" onkeypress=\"javascript: m_notificationArea.hide();\">" + NL);
-        content.append("        <iframe style=\"display: none;\" id=\"m_downloader\" src=\"\"></iframe>" + NL);
-        content.append("        <iframe style=\"display: none;\" id=\"m_uploader\" src=\"\"></iframe>" + NL);
-        content.append("        <div class=\"MWebView\" id=\"m_view\">Loading...</div>" + NL);
-        content.append("    </body>" + NL);
-        content.append(NL);
-        content.append("</html>" + NL);
-        //
-        this.getApplicationContextReference().setXhtmlResponseContent(content.toString());
-    }
-
-    protected void refreshAuthor() throws MResponseWebException { // inspired by http://www.programminghelp.com/forums/Topic81-20-1.aspx#bm334
-        String commands = "metaTags = $T('meta');"
-                        + "for (m = 0; m < metaTags.length; m++) {"
-                        + "    if ('author' == metaTags[m].getAttribute('name')) {"
-                        + "        metaTags[m].setAttribute('content', '%s');"
-                        + "    }"
-                        + "}";
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format(commands, MWebString.getJavascriptEscapedString(this.getAuthor())));
-    }
-
-    protected void refreshCssSource() throws MResponseWebException { // inspired by http://www.thesitewizard.com/javascripts/change-style-sheets.shtml
-        String cssSource = this.getCssSource();
-        if (null == cssSource) {
-            cssSource = String.format("%s/coreResources/css/default.css", this.getApplicationContextReference().getRequestReference().getRequestURL());
-        }
-        //
-        String commands = "linkTags = $T('link');"
-                        + "for (l = 0; l < linkTags.length; l++) {"
-                        + "    if ('stylesheet' == linkTags[l].rel) {"
-                        + "        linkTags[l].href = '%s';"
-                        + "    }"
-                        + "}";
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format(commands, MWebString.getJavascriptEscapedString(cssSource)));
-    }
-
-    /* Requests */
-
-    protected void onRequestPreprocessing() throws MBrowserPageRequestPreprocessingWebException {
-    }
-
-    protected void processRequest() throws Exception {
-        // check for proper security id, then determine request type
-        String securityId = this.getApplicationContextReference().getRequestReference().getParameter("securityId");
-        if (null == securityId) {
-            this.refresh();
-        }
-        else if (Integer.parseInt(securityId) != this.getSecurityId()) {
-            throw new MInvalidSecurityIdWebException(String.format("Invalid request: no match for security ids (%s vs %s).", securityId, this.getSecurityId()));
-        }
-        else {
-            String message = this.getApplicationContextReference().getRequestReference().getParameter("message");
-            if (null == message) {
-                throw new MUnexpectedMessageWebException("Invalid request: message null.");
-            }
-            //
-            this.setProcessableMessage(new MWebMessage(message));
-            //
-            this.setLastViewThreadReturnValue(null);
-            this.setLastViewThreadException(null);
-            //
-            if (Thread.State.NEW == this.getCurrentViewThreadReference().getState()) {
-                this.getCurrentViewThreadReference().start();
-            }
-            else {
-                synchronized (this.getCurrentViewThreadReference()) {
-                    this.getCurrentViewThreadReference().notify();
-                }
-            }
-            //
-            while (true) {
-                if (null != this.getLastViewThreadExceptionReference()) {
-                    throw this.getLastViewThreadExceptionReference();
-                }
-                if ((Thread.State.WAITING == this.getCurrentViewThreadReference().getState()) && (!this.getForcedLoopMode())) {
-                    break;
-                }
-            }
-        }
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebCellWidget.java b/src/java/com/marcozanon/macaco/webui/MWebCellWidget.java
deleted file mode 100644 (file)
index 1cc59f1..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public abstract class MWebCellWidget extends MWebDisplayWidget {
-
-    public static enum VerticalAlignment {
-        TOP("top"),
-        MIDDLE("middle"),
-        BOTTOM("bottom");
-        private String name = null;
-        private VerticalAlignment(String name) {
-            this.name = name;
-        }
-        public String toString() {
-            return this.name;
-        }
-    };
-
-    public static enum HorizontalAlignment {
-        LEFT("left"),
-        CENTER("center"),
-        RIGHT("right");
-        private String name = null;
-        private HorizontalAlignment(String name) {
-            this.name = name;
-        }
-        public String toString() {
-            return this.name;
-        }
-    };
-
-    protected MWebCellWidget.VerticalAlignment verticalAlignment = null;
-    protected MWebCellWidget.HorizontalAlignment horizontalAlignment = null;
-
-    /* */
-
-    public MWebCellWidget(MWebApplicationContext applicationContext) {
-        super(applicationContext);
-    }
-
-    public void cloneCellWidgetProperties(MWebCellWidget cellWidget) {
-        super.cloneDisplayWidgetProperties(cellWidget);
-        //
-        cellWidget.setVerticalAlignment(this.getVerticalAlignment());
-        cellWidget.setHorizontalAlignment(this.getHorizontalAlignment());
-    }
-
-    /* Vertical alignment */
-
-    public void setVerticalAlignment(MWebCellWidget.VerticalAlignment verticalAlignment) {
-        this.setVerticalAlignment(verticalAlignment, true);
-    }
-
-    protected void setVerticalAlignment(MWebCellWidget.VerticalAlignment verticalAlignment, boolean refreshMode) {
-        this.verticalAlignment = verticalAlignment;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshVerticalAlignment(false);
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public MWebCellWidget.VerticalAlignment getVerticalAlignment() {
-        return this.verticalAlignment;
-    }
-
-    public String getFormattedVerticalAlignment() throws MNullPropertyWebException {
-        if (null == this.getVerticalAlignment()) {
-            throw new MNullPropertyWebException("Invalid vertical alignment: property null.");
-        }
-        return this.getVerticalAlignment().toString();
-    }
-
-    /* Horizontal alignment */
-
-    public void setHorizontalAlignment(MWebCellWidget.HorizontalAlignment horizontalAlignment) {
-        this.setHorizontalAlignment(horizontalAlignment, true);
-    }
-
-    protected void setHorizontalAlignment(MWebCellWidget.HorizontalAlignment horizontalAlignment, boolean refreshMode) {
-        this.horizontalAlignment = horizontalAlignment;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshHorizontalAlignment(false);
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public MWebCellWidget.HorizontalAlignment getHorizontalAlignment() {
-        return this.horizontalAlignment;
-    }
-
-    public String getFormattedHorizontalAlignment() throws MNullPropertyWebException {
-        if (null == this.getHorizontalAlignment()) {
-            throw new MNullPropertyWebException("Invalid horizontal alignment: property null.");
-        }
-        return this.getHorizontalAlignment().toString();
-    }
-
-    /* Refresh */
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        super.refresh();
-        //
-        this.refreshVerticalAlignment(true);
-        this.refreshHorizontalAlignment(true);
-    }
-
-    protected void refreshVerticalAlignment(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        try {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').verticalAlign = '%s'; }", this.getId(), this.getId(), this.getFormattedVerticalAlignment()));
-        }
-        catch (MNullPropertyWebException exception) {
-            if (!directRefreshMode) {
-                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').verticalAlign = null; }", this.getId(), this.getId()));
-            }
-        }
-    }
-
-    protected void refreshHorizontalAlignment(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        try {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textAlign = '%s'; }", this.getId(), this.getId(), this.getFormattedHorizontalAlignment()));
-        }
-        catch (MNullPropertyWebException exception) {
-            if (!directRefreshMode) {
-                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textAlign = null; }", this.getId(), this.getId()));
-            }
-        }
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebCheckBox.java b/src/java/com/marcozanon/macaco/webui/MWebCheckBox.java
deleted file mode 100644 (file)
index baae86d..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import java.util.LinkedHashMap;
-
-public class MWebCheckBox extends MWebDirectWidget {
-
-    protected boolean checkedMode = false;
-
-    protected boolean enabledMode = true;
-
-    /* */
-
-    public MWebCheckBox(MWebApplicationContext applicationContext) {
-        super(applicationContext);
-    }
-
-    public MWebCheckBox(MWebApplicationContext applicationContext, boolean checkedMode) {
-        this(applicationContext);
-        //
-        this.setCheckedMode(checkedMode);
-    }
-
-    /* Focus */
-
-    public void setFocus() {
-        try {
-            this.refreshFocus();
-        }
-        catch (MNoBrowserPageWebException exception) {
-        }
-        catch (MNoViewWebException exception) {
-        }
-        catch (MNoWidgetIdWebException exception) {
-        }
-        catch (MResponseWebException exception) {
-        }
-    }
-
-    /* Checked mode */
-
-    public void setCheckedMode(boolean checkedMode) {
-        this.setCheckedMode(checkedMode, true);
-    }
-
-    protected void setCheckedMode(boolean checkedMode, boolean refreshMode) {
-        this.checkedMode = checkedMode;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshCheckedMode();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public boolean getCheckedMode() {
-        return this.checkedMode;
-    }
-
-    /* Enabled mode */
-
-    public void setEnabledMode(boolean enabledMode) {
-        this.setEnabledMode(enabledMode, true);
-    }
-
-    protected void setEnabledMode(boolean enabledMode, boolean refreshMode) {
-        this.enabledMode = enabledMode;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshEnabledMode();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public boolean getEnabledMode() {
-        return this.enabledMode;
-    }
-
-    /* Refresh */
-
-    protected void refreshFocus() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').focus(); }", this.getId(), this.getId()));
-    }
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        String onChangeFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onChange', {'checkedMode': (this.checked ? '1' : '0')});", this.getId());
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<input type=\"checkbox\" class=\"MWebCheckBox %s\" style=\"display: inline-block;\" onchange=\"%s\" id=\"%s\" />'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onChangeFunction), this.getId()));
-        //
-        super.refresh();
-        //
-        this.refreshCheckedMode();
-        this.refreshEnabledMode();
-    }
-
-    protected void refreshCheckedMode() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').checked = %s; }", this.getId(), this.getId(), this.getCheckedMode()));
-    }
-
-    protected void refreshEnabledMode() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').disabled = %s; }", this.getId(), this.getId(), !this.getEnabledMode()));
-    }
-
-    /* Messages */
-
-    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
-        super.processMessage(event, parameters);
-        //
-        if ("onChange".equals(event)) {
-            if ((!this.getVisibleMode()) || (!this.getEnabledMode())) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden or disabled.", event));
-            }
-            String checkedMode = parameters.get("checkedMode");
-            if (null == checkedMode) {
-                throw new MUnexpectedMessageWebException("Invalid message: checked mode parameter not available.");
-            }
-            else if ((!"0".equals(checkedMode)) && (!"1".equals(checkedMode))) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: checked mode parameter not recognized.", checkedMode));
-            }
-            this.onChange("1".equals(checkedMode));
-        }
-        else if ("onRefresh".equals(event)) {
-            this.onRefresh();
-        }
-        else {
-            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
-        }
-    }
-
-    public void onChange(boolean checkedMode) {
-        this.setCheckedMode(checkedMode, false);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebColor.java b/src/java/com/marcozanon/macaco/webui/MWebColor.java
deleted file mode 100644 (file)
index ab80742..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.MObject;
-
-public class MWebColor extends MObject {
-
-    protected Integer color = null;
-
-    /* */
-
-    public MWebColor(Integer color) {
-        super();
-        //
-        if (null == color) {
-            throw new IllegalArgumentException("Invalid 'color': null.");
-        }
-        else if ((color < 0) || (color > 0xFFFFFF)) {
-            throw new IllegalArgumentException(String.format("Invalid 'color': %s.", color));
-        }
-        //
-        this.color = color;
-    }
-
-    public MWebColor clone() {
-        return new MWebColor(this.getValue());
-    }
-
-    /* Color */
-
-    public Integer getValue() {
-        return this.color;
-    }
-
-    public String getFormattedValue() {
-        return "#" + String.format("%6H", this.getValue()).replace(" ", "0");
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebComboBox.java b/src/java/com/marcozanon/macaco/webui/MWebComboBox.java
deleted file mode 100644 (file)
index 716bd18..0000000
+++ /dev/null
@@ -1,360 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-
-public class MWebComboBox extends MWebDirectWidget {
-
-    public static enum TextAlignment {
-        LEFT("left"),
-        CENTER("center"),
-        RIGHT("right");
-        private String name = null;
-        private TextAlignment(String name) {
-            this.name = name;
-        }
-        public String toString() {
-            return this.name;
-        }
-    };
-
-    protected LinkedHashMap<String, String> items = new LinkedHashMap<String, String>();
-    protected String selectedItemKey = "";
-    protected MWebComboBox.TextAlignment textAlignment = null;
-
-    protected boolean enabledMode = true;
-
-    /* */
-
-    public MWebComboBox(MWebApplicationContext applicationContext) {
-        super(applicationContext);
-    }
-
-    public MWebComboBox(MWebApplicationContext applicationContext, LinkedHashMap<String, String> items, String selectedItemKey) {
-        this(applicationContext);
-        //
-        this.setItems(items, selectedItemKey);
-    }
-
-    /* Focus */
-
-    public void setFocus() {
-        try {
-            this.refreshFocus();
-        }
-        catch (MNoBrowserPageWebException exception) {
-        }
-        catch (MNoViewWebException exception) {
-        }
-        catch (MNoWidgetIdWebException exception) {
-        }
-        catch (MResponseWebException exception) {
-        }
-    }
-
-    /* Items */
-
-    public void setItems(LinkedHashMap<String, String> items, String selectedItemKey) {
-        this.setItems(items, selectedItemKey, true);
-    }
-
-    protected void setItems(LinkedHashMap<String, String> items, String selectedItemKey, boolean refreshMode) {
-        if (null == items) {
-            throw new IllegalArgumentException("Invalid 'items': null.");
-        }
-        else {
-            for (String k: items.keySet()) {
-                if ((null == k) || ("".equals(k))) {
-                    throw new IllegalArgumentException("Invalid 'items': item key null or empty.");
-                }
-                else if (null == items.get(k)) {
-                    throw new IllegalArgumentException("Invalid 'items': item null.");
-                }
-            }
-        }
-        //
-        this.items = items;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshItems();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-        //
-        this.setSelectedItem(selectedItemKey, refreshMode);
-    }
-
-    protected LinkedHashMap<String, String> getItemsReference() {
-        return this.items;
-    }
-
-    public LinkedHashMap<String, String> getItems() {
-        LinkedHashMap<String, String> tmpItems = new LinkedHashMap<String, String>();
-        for (String itemKey: this.getItemsReference().keySet()) {
-            tmpItems.put(itemKey, this.getItemsReference().get(itemKey));
-        }
-        return tmpItems;
-    }
-
-    public LinkedHashSet<String> getItemKeys() {
-        LinkedHashSet<String> tmpItemKeys = new LinkedHashSet<String>();
-        for (String itemKey: this.getItemsReference().keySet()) {
-            tmpItemKeys.add(itemKey);
-        }
-        return tmpItemKeys;
-    }
-
-    public void setSelectedItem(String selectedItemKey) {
-        this.setSelectedItem(selectedItemKey, true);
-    }
-
-    protected void setSelectedItem(String selectedItemKey, boolean refreshMode) {
-        if (null == selectedItemKey) {
-            throw new IllegalArgumentException("Invalid 'selectedItemKey': null.");
-        }
-        else if ((!"".equals(selectedItemKey)) && (!this.getItemsReference().containsKey(selectedItemKey))) {
-            throw new IllegalArgumentException(String.format("Invalid 'selectedItemKey': %s: not available.", selectedItemKey));
-        }
-        //
-        this.selectedItemKey = selectedItemKey;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshSelectedItem();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public String getSelectedItemKey() {
-        return this.selectedItemKey;
-    }
-
-    public int getSelectedItemIndex() {
-        String selectedItemKey = this.getSelectedItemKey();
-        int selectedItemIndex = 0;
-        if ("".equals(selectedItemKey)) {
-            return selectedItemIndex;
-        }
-        for (String k: this.getItemsReference().keySet()) {
-            selectedItemIndex++;
-            if (k.equals(selectedItemKey)) {
-                break;
-            }
-        }
-        return selectedItemIndex;
-    }
-
-    /* Text alignment */
-
-    public void setTextAlignment(MWebComboBox.TextAlignment textAlignment) {
-        this.setTextAlignment(textAlignment, true);
-    }
-
-    protected void setTextAlignment(MWebComboBox.TextAlignment textAlignment, boolean refreshMode) {
-        this.textAlignment = textAlignment;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshTextAlignment(false);
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public MWebComboBox.TextAlignment getTextAlignment() {
-        return this.textAlignment;
-    }
-
-    public String getFormattedTextAlignment() throws MNullPropertyWebException {
-        if (null == this.getTextAlignment()) {
-            throw new MNullPropertyWebException("Invalid text alignment: property null.");
-        }
-        return this.getTextAlignment().toString();
-    }
-
-    /* Enabled mode */
-
-    public void setEnabledMode(boolean enabledMode) {
-        this.setEnabledMode(enabledMode, true);
-    }
-
-    protected void setEnabledMode(boolean enabledMode, boolean refreshMode) {
-        this.enabledMode = enabledMode;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshEnabledMode();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public boolean getEnabledMode() {
-        return this.enabledMode;
-    }
-
-    /* Refresh */
-
-    protected void refreshFocus() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').focus(); }", this.getId(), this.getId()));
-    }
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        String onBlurFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onBlur', {'selectedItemKey': this.value});", this.getId());
-        String onChangeFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onChange', {'selectedItemKey': this.value});", this.getId());
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<select class=\"MWebComboBox %s\" style=\"display: inline-block;\" onblur=\"%s\" onchange=\"%s\" id=\"%s\"><option value=\"\"></option></select>'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onBlurFunction), MWebString.getJavascriptEscapedString(onChangeFunction), this.getId()));
-        //
-        super.refresh();
-        //
-        this.refreshItems();
-        this.refreshSelectedItem();
-        this.refreshTextAlignment(true);
-        this.refreshEnabledMode();
-    }
-
-    protected void refreshItems() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').options.length = 0; }", this.getId(), this.getId()));
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').options[$('%s').options.length] = new Option('', ''); }", this.getId(), this.getId(), this.getId()));
-        for (String itemKey: this.getItemsReference().keySet()) {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').options[$('%s').options.length] = new Option('%s', '%s'); }", this.getId(), this.getId(), this.getId(), MWebString.getJavascriptEscapedString(this.getItemsReference().get(itemKey)), MWebString.getJavascriptEscapedString(itemKey)));
-        }
-    }
-
-    protected void refreshSelectedItem() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').selectedIndex = %s; }", this.getId(), this.getId(), this.getSelectedItemIndex()));
-    }
-
-    protected void refreshTextAlignment(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        try {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textAlign = '%s'; }", this.getId(), this.getId(), this.getFormattedTextAlignment()));
-        }
-        catch (MNullPropertyWebException exception) {
-            if (!directRefreshMode) {
-                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textAlign = null; }", this.getId(), this.getId()));
-            }
-        }
-    }
-
-    protected void refreshEnabledMode() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').disabled = %s; }", this.getId(), this.getId(), !this.getEnabledMode()));
-    }
-
-    /* Messages */
-
-    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
-        super.processMessage(event, parameters);
-        //
-        if ("onBlur".equals(event)) {
-            if ((!this.getVisibleMode()) || (!this.getEnabledMode())) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden or disabled.", event));
-            }
-            String selectedItemKey = parameters.get("selectedItemKey");
-            if (null == selectedItemKey) {
-                throw new MUnexpectedMessageWebException("Invalid message: selected item key parameter not available.");
-            }
-            else if ((!"".equals(selectedItemKey)) && (!this.getItemsReference().keySet().contains(selectedItemKey))) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: selected item key parameter not recognized.", selectedItemKey));
-            }
-            this.onBlur(selectedItemKey);
-        }
-        else if ("onChange".equals(event)) {
-            if ((!this.getVisibleMode()) || (!this.getEnabledMode())) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden or disabled.", event));
-            }
-            String selectedItemKey = parameters.get("selectedItemKey");
-            if (null == selectedItemKey) {
-                throw new MUnexpectedMessageWebException("Invalid message: selected item key parameter not available.");
-            }
-            else if ((!"".equals(selectedItemKey)) && (!this.getItemsReference().keySet().contains(selectedItemKey))) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: selected item key parameter not recognized.", selectedItemKey));
-            }
-            this.onChange(selectedItemKey);
-        }
-        else if ("onRefresh".equals(event)) {
-            this.onRefresh();
-        }
-        else {
-            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
-        }
-    }
-
-    public void onBlur(String selectedItemKey) {
-        this.setSelectedItem(selectedItemKey, false);
-    }
-
-    public void onChange(String selectedItemKey) {
-        this.setSelectedItem(selectedItemKey, false);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebDateBox.java b/src/java/com/marcozanon/macaco/webui/MWebDateBox.java
deleted file mode 100644 (file)
index be33fc1..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.filtering.MConstraintFilteringException;
-import com.marcozanon.macaco.filtering.MDateFilter;
-import com.marcozanon.macaco.filtering.MFormatFilteringException;
-
-public class MWebDateBox extends MWebTextBox {
-
-    protected MDateFilter dateFilter = null;
-
-    /* */
-
-    public MWebDateBox(MWebApplicationContext applicationContext, MDateFilter dateFilter) {
-        super(applicationContext);
-        //
-        if (null == dateFilter) {
-            throw new IllegalArgumentException("Invalid 'dateFilter': null.");
-        }
-        //
-        this.dateFilter = dateFilter;
-    }
-
-    public MWebDateBox(MWebApplicationContext applicationContext, MDateFilter dateFilter, String text) {
-        this(applicationContext, dateFilter);
-        //
-        this.setText(text);
-    }
-
-    /* Date filter */
-
-    protected MDateFilter getDateFilterReference() {
-        return this.dateFilter;
-    }
-
-    public MDateFilter getDateFilter() {
-        return this.getDateFilterReference().clone();
-    }
-
-    /* Validation */
-
-    public void validate() throws MValidationWebException {
-        String text = this.getText();
-        try {
-            this.setText(this.getDateFilterReference().getValidatedUserDate(text, null));
-        }
-        catch (MConstraintFilteringException exception) {
-            throw new MValidationWebException(String.format("Invalid date: %s.", text), exception);
-        }
-        catch (MFormatFilteringException exception) {
-            throw new MValidationWebException(String.format("Invalid date: %s.", text), exception);
-        }
-    }
-
-    /* Refresh */
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        String onBlurFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onBlur', {'text': this.value});", this.getId());
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<input type=\"text\" class=\"MWebDateBox %s\" style=\"display: inline-block;\" onblur=\"%s\" id=\"%s\" />'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onBlurFunction), this.getId()));
-        //
-        super.refresh();
-        //
-        this.refreshText();
-        this.refreshTextAlignment(true);
-        this.refreshEnabledMode();
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebDatetimeBox.java b/src/java/com/marcozanon/macaco/webui/MWebDatetimeBox.java
deleted file mode 100644 (file)
index 5610006..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.filtering.MConstraintFilteringException;
-import com.marcozanon.macaco.filtering.MDatetimeFilter;
-import com.marcozanon.macaco.filtering.MFormatFilteringException;
-
-public class MWebDatetimeBox extends MWebTextBox {
-
-    protected MDatetimeFilter datetimeFilter = null;
-
-    /* */
-
-    public MWebDatetimeBox(MWebApplicationContext applicationContext, MDatetimeFilter datetimeFilter) {
-        super(applicationContext);
-        //
-        if (null == datetimeFilter) {
-            throw new IllegalArgumentException("Invalid 'datetimeFilter': null.");
-        }
-        //
-        this.datetimeFilter = datetimeFilter;
-    }
-
-    public MWebDatetimeBox(MWebApplicationContext applicationContext, MDatetimeFilter datetimeFilter, String text) {
-        this(applicationContext, datetimeFilter);
-        //
-        this.setText(text);
-    }
-
-    /* Datetime filter */
-
-    protected MDatetimeFilter getDatetimeFilterReference() {
-        return this.datetimeFilter;
-    }
-
-    public MDatetimeFilter getDatetimeFilter() {
-        return this.getDatetimeFilterReference().clone();
-    }
-
-    /* Validation */
-
-    public void validate() throws MValidationWebException {
-        String text = this.getText();
-        try {
-            this.setText(this.getDatetimeFilterReference().getValidatedUserDatetime(text, null));
-        }
-        catch (MConstraintFilteringException exception) {
-            throw new MValidationWebException(String.format("Invalid datetime: %s.", text), exception);
-        }
-        catch (MFormatFilteringException exception) {
-            throw new MValidationWebException(String.format("Invalid datetime: %s.", text), exception);
-        }
-    }
-
-    /* Refresh */
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        String onBlurFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onBlur', {'text': this.value});", this.getId());
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<input type=\"text\" class=\"MWebDatetimeBox %s\" style=\"display: inline-block;\" onblur=\"%s\" id=\"%s\" />'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onBlurFunction), this.getId()));
-        //
-        super.refresh();
-        //
-        this.refreshText();
-        this.refreshTextAlignment(true);
-        this.refreshEnabledMode();
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebDirectWidget.java b/src/java/com/marcozanon/macaco/webui/MWebDirectWidget.java
deleted file mode 100644 (file)
index 9724c66..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public abstract class MWebDirectWidget extends MWebDisplayWidget {
-
-    /* */
-
-    public MWebDirectWidget(MWebApplicationContext applicationContext) {
-        super(applicationContext);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebDisplayWidget.java b/src/java/com/marcozanon/macaco/webui/MWebDisplayWidget.java
deleted file mode 100644 (file)
index 1288998..0000000
+++ /dev/null
@@ -1,946 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public abstract class MWebDisplayWidget extends MWebWidget {
-
-    public static enum Side {
-        TOP("top"),
-        RIGHT("right"),
-        BOTTOM("bottom"),
-        LEFT("left");
-        private String name = null;
-        private Side(String name) {
-            this.name = name;
-        }
-        public String toString() {
-            return this.name;
-        }
-    };
-
-    public static enum TextDirection {
-        LTR("ltr"),
-        RTL("rtl");
-        private String name = null;
-        private TextDirection(String name) {
-            this.name = name;
-        }
-        public String toString() {
-            return this.name;
-        }
-    };
-
-    protected String customClasses = null;
-
-    protected MWebMeasure width = null;
-    protected MWebMeasure height = null;
-    protected MWebColor foregroundColor = null;
-    protected MWebColor backgroundColor = null;
-    protected MWebBorder topBorder = null;
-    protected MWebBorder rightBorder = null;
-    protected MWebBorder bottomBorder = null;
-    protected MWebBorder leftBorder = null;
-    protected MWebFont font = null;
-    protected MWebMeasure topPadding = null;
-    protected MWebMeasure rightPadding = null;
-    protected MWebMeasure bottomPadding = null;
-    protected MWebMeasure leftPadding = null;
-    protected MWebDisplayWidget.TextDirection textDirection = null;
-
-    protected boolean visibleMode = true;
-
-    /* */
-
-    public MWebDisplayWidget(MWebApplicationContext applicationContext) {
-        super(applicationContext);
-    }
-
-    public void cloneDisplayWidgetProperties(MWebDisplayWidget displayWidget) {
-        displayWidget.setWidth(this.getWidth());
-        displayWidget.setHeight(this.getHeight());
-        displayWidget.setForegroundColor(this.getForegroundColor());
-        displayWidget.setBackgroundColor(this.getBackgroundColor());
-        displayWidget.setTopBorder(this.getTopBorder());
-        displayWidget.setRightBorder(this.getRightBorder());
-        displayWidget.setBottomBorder(this.getBottomBorder());
-        displayWidget.setLeftBorder(this.getLeftBorder());
-        displayWidget.setFont(this.getFont());
-        displayWidget.setTopPadding(this.getTopPadding());
-        displayWidget.setRightPadding(this.getRightPadding());
-        displayWidget.setBottomPadding(this.getBottomPadding());
-        displayWidget.setLeftPadding(this.getLeftPadding());
-        displayWidget.setTextDirection(this.getTextDirection());
-        displayWidget.setVisibleMode(this.getVisibleMode());
-    }
-
-    /* Custom classes */
-
-    public void setCustomClasses(String customClasses) {
-        this.setCustomClasses(customClasses, true);
-    }
-
-    protected void setCustomClasses(String customClasses, boolean refreshMode) {
-        if ("".equals(customClasses)) {
-            throw new IllegalArgumentException("Invalid 'customClasses': empty.");
-        }
-        //
-        this.customClasses = customClasses;
-        //
-        if (refreshMode) {
-            try {
-                this.refresh(); // must refresh everything
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-            catch (MUniqueWidgetIdNotAvailableWebException exception) {
-            }
-        }
-    }
-
-    public String getCustomClasses() {
-        return this.customClasses;
-    }
-
-    /* Width */
-
-    public void setWidth(MWebMeasure width) {
-        this.setWidth(width, true);
-    }
-
-    protected void setWidth(MWebMeasure width, boolean refreshMode) {
-        this.width = width;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshWidth(false);
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    protected MWebMeasure getWidthReference() {
-        return this.width;
-    }
-
-    public MWebMeasure getWidth() {
-        if (null == this.getWidthReference()) {
-            return null;
-        }
-        return this.getWidthReference().clone();
-    }
-
-    public String getFormattedWidth() throws MNullPropertyWebException {
-        if (null == this.getWidthReference()) {
-            throw new MNullPropertyWebException("Invalid width: reference null.");
-        }
-        return this.getWidthReference().getFormattedValue();
-    }
-
-    /* Height */
-
-    public void setHeight(MWebMeasure height) {
-        this.setHeight(height, true);
-    }
-
-    protected void setHeight(MWebMeasure height, boolean refreshMode) {
-        this.height = height;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshHeight(false);
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    protected MWebMeasure getHeightReference() {
-        return this.height;
-    }
-
-    public MWebMeasure getHeight() {
-        if (null == this.getHeightReference()) {
-            return null;
-        }
-        return this.getHeightReference().clone();
-    }
-
-    public String getFormattedHeight() throws MNullPropertyWebException {
-        if (null == this.getHeightReference()) {
-            throw new MNullPropertyWebException("Invalid height: reference null.");
-        }
-        return this.getHeightReference().getFormattedValue();
-    }
-
-    /* Foreground color */
-
-    public void setForegroundColor(MWebColor foregroundColor) {
-        this.setForegroundColor(foregroundColor, true);
-    }
-
-    protected void setForegroundColor(MWebColor foregroundColor, boolean refreshMode) {
-        this.foregroundColor = foregroundColor;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshForegroundColor(false);
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    protected MWebColor getForegroundColorReference() {
-        return this.foregroundColor;
-    }
-
-    public MWebColor getForegroundColor() {
-        if (null == this.getForegroundColorReference()) {
-            return null;
-        }
-        return this.getForegroundColorReference().clone();
-    }
-
-    public String getFormattedForegroundColor() throws MNullPropertyWebException {
-        if (null == this.getForegroundColorReference()) {
-            throw new MNullPropertyWebException("Invalid foreground color: reference null.");
-        }
-        return this.getForegroundColorReference().getFormattedValue();
-    }
-
-    /* Background color */
-
-    public void setBackgroundColor(MWebColor backgroundColor) {
-        this.setBackgroundColor(backgroundColor, true);
-    }
-
-    protected void setBackgroundColor(MWebColor backgroundColor, boolean refreshMode) {
-        this.backgroundColor = backgroundColor;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshBackgroundColor(false);
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    protected MWebColor getBackgroundColorReference() {
-        return this.backgroundColor;
-    }
-
-    public MWebColor getBackgroundColor() {
-        if (null == this.getBackgroundColorReference()) {
-            return null;
-        }
-        return this.getBackgroundColorReference().clone();
-    }
-
-    public String getFormattedBackgroundColor() throws MNullPropertyWebException {
-        if (null == this.getBackgroundColorReference()) {
-            throw new MNullPropertyWebException("Invalid background color: reference null.");
-        }
-        return this.getBackgroundColorReference().getFormattedValue();
-    }
-
-    /* Borders */
-
-    public void setTopBorder(MWebBorder border) {
-        this.setTopBorder(border, true);
-    }
-
-    protected void setTopBorder(MWebBorder border, boolean refreshMode) {
-        this.setBorder(border, MWebDisplayWidget.Side.TOP, refreshMode);
-    }
-
-    public void setRightBorder(MWebBorder border) {
-        this.setRightBorder(border, true);
-    }
-
-    protected void setRightBorder(MWebBorder border, boolean refreshMode) {
-        this.setBorder(border, MWebDisplayWidget.Side.RIGHT, refreshMode);
-    }
-
-    public void setBottomBorder(MWebBorder border) {
-        this.setBottomBorder(border, true);
-    }
-
-    protected void setBottomBorder(MWebBorder border, boolean refreshMode) {
-        this.setBorder(border, MWebDisplayWidget.Side.BOTTOM, refreshMode);
-    }
-
-    public void setLeftBorder(MWebBorder border) {
-        this.setLeftBorder(border, true);
-    }
-
-    protected void setLeftBorder(MWebBorder border, boolean refreshMode) {
-        this.setBorder(border, MWebDisplayWidget.Side.LEFT, refreshMode);
-    }
-
-    public void setBorder(MWebBorder border) {
-        this.setBorder(border, null, true);
-    }
-
-    protected void setBorder(MWebBorder border, boolean refreshMode) {
-        this.setBorder(border, null, refreshMode);
-    }
-
-    public void setBorder(MWebBorder border, MWebDisplayWidget.Side borderSide) {
-        this.setBorder(border, borderSide, true);
-    }
-
-    protected void setBorder(MWebBorder border, MWebDisplayWidget.Side borderSide, boolean refreshMode) {
-        if (null == borderSide) {
-            this.topBorder = border;
-            this.rightBorder = border;
-            this.bottomBorder = border;
-            this.leftBorder = border;
-        }
-        else if (MWebDisplayWidget.Side.TOP == borderSide) {
-            this.topBorder = border;
-        }
-        else if (MWebDisplayWidget.Side.RIGHT == borderSide) {
-            this.rightBorder = border;
-        }
-        else if (MWebDisplayWidget.Side.BOTTOM == borderSide) {
-            this.bottomBorder = border;
-        }
-        else if (MWebDisplayWidget.Side.LEFT == borderSide) {
-            this.leftBorder = border;
-        }
-        //
-        if (refreshMode) {
-            try {
-                this.refreshBorder(borderSide, false);
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    protected MWebBorder getTopBorderReference() {
-        return this.topBorder;
-    }
-
-    public MWebBorder getTopBorder() {
-        if (null == this.getTopBorderReference()) {
-            return null;
-        }
-        return this.getTopBorderReference().clone();
-    }
-
-    public String getFormattedTopBorder() throws MNullPropertyWebException {
-        if (null == this.getTopBorderReference()) {
-            throw new MNullPropertyWebException("Invalid top border: reference null.");
-        }
-        return this.getTopBorderReference().getFormattedValue();
-    }
-
-    protected MWebBorder getRightBorderReference() {
-        return this.rightBorder;
-    }
-
-    public MWebBorder getRightBorder() {
-        if (null == this.getRightBorderReference()) {
-            return null;
-        }
-        return this.getRightBorderReference().clone();
-    }
-
-    public String getFormattedRightBorder() throws MNullPropertyWebException {
-        if (null == this.getRightBorderReference()) {
-            throw new MNullPropertyWebException("Invalid right border: reference null.");
-        }
-        return this.getRightBorderReference().getFormattedValue();
-    }
-
-    protected MWebBorder getBottomBorderReference() {
-        return this.bottomBorder;
-    }
-
-    public MWebBorder getBottomBorder() {
-        if (null == this.getBottomBorderReference()) {
-            return null;
-        }
-        return this.getBottomBorderReference().clone();
-    }
-
-    public String getFormattedBottomBorder() throws MNullPropertyWebException {
-        if (null == this.getBottomBorderReference()) {
-            throw new MNullPropertyWebException("Invalid bottom border: reference null.");
-        }
-        return this.getBottomBorderReference().getFormattedValue();
-    }
-
-    protected MWebBorder getLeftBorderReference() {
-        return this.leftBorder;
-    }
-
-    public MWebBorder getLeftBorder() {
-        if (null == this.getLeftBorderReference()) {
-            return null;
-        }
-        return this.getLeftBorderReference().clone();
-    }
-
-    public String getFormattedLeftBorder() throws MNullPropertyWebException {
-        if (null == this.getLeftBorderReference()) {
-            throw new MNullPropertyWebException("Invalid left border: reference null.");
-        }
-        return this.getLeftBorderReference().getFormattedValue();
-    }
-
-    /* Font */
-
-    public void setFont(MWebFont font) {
-        this.setFont(font, true);
-    }
-
-    protected void setFont(MWebFont font, boolean refreshMode) {
-        this.font = font;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshFont(false);
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    protected MWebFont getFontReference() {
-        return this.font;
-    }
-
-    public MWebFont getFont() {
-        if (null == this.getFontReference()) {
-            return null;
-        }
-        return this.getFontReference().clone();
-    }
-
-    public String[] getFormattedFont() throws MNullPropertyWebException {
-        if (null == this.getFontReference()) {
-            throw new MNullPropertyWebException("Invalid font: reference null.");
-        }
-        return this.getFontReference().getFormattedValue();
-    }
-
-    /* Paddings */
-
-    public void setTopPadding(MWebMeasure padding) {
-        this.setTopPadding(padding, true);
-    }
-
-    protected void setTopPadding(MWebMeasure padding, boolean refreshMode) {
-        this.setPadding(padding, MWebDisplayWidget.Side.TOP, refreshMode);
-    }
-
-    public void setRightPadding(MWebMeasure padding) {
-        this.setRightPadding(padding, true);
-    }
-
-    protected void setRightPadding(MWebMeasure padding, boolean refreshMode) {
-        this.setPadding(padding, MWebDisplayWidget.Side.RIGHT, refreshMode);
-    }
-
-    public void setBottomPadding(MWebMeasure padding) {
-        this.setBottomPadding(padding, true);
-    }
-
-    protected void setBottomPadding(MWebMeasure padding, boolean refreshMode) {
-        this.setPadding(padding, MWebDisplayWidget.Side.BOTTOM, refreshMode);
-    }
-
-    public void setLeftPadding(MWebMeasure padding) {
-        this.setLeftPadding(padding, true);
-    }
-
-    protected void setLeftPadding(MWebMeasure padding, boolean refreshMode) {
-        this.setPadding(padding, MWebDisplayWidget.Side.LEFT, refreshMode);
-    }
-
-    public void setPadding(MWebMeasure padding) {
-        this.setPadding(padding, null, true);
-    }
-
-    protected void setPadding(MWebMeasure padding, boolean refreshMode) {
-        this.setPadding(padding, null, refreshMode);
-    }
-
-    public void setPadding(MWebMeasure padding, MWebDisplayWidget.Side paddingSide) {
-        this.setPadding(padding, paddingSide, true);
-    }
-
-    protected void setPadding(MWebMeasure padding, MWebDisplayWidget.Side paddingSide, boolean refreshMode) {
-        if (null == paddingSide) {
-            this.topPadding = padding;
-            this.rightPadding = padding;
-            this.bottomPadding = padding;
-            this.leftPadding = padding;
-        }
-        else if (MWebDisplayWidget.Side.TOP == paddingSide) {
-            this.topPadding = padding;
-        }
-        else if (MWebDisplayWidget.Side.RIGHT == paddingSide) {
-            this.rightPadding = padding;
-        }
-        else if (MWebDisplayWidget.Side.BOTTOM == paddingSide) {
-            this.bottomPadding = padding;
-        }
-        else if (MWebDisplayWidget.Side.LEFT == paddingSide) {
-            this.leftPadding = padding;
-        }
-        //
-        if (refreshMode) {
-            try {
-                this.refreshPadding(paddingSide, false);
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    protected MWebMeasure getTopPaddingReference() {
-        return this.topPadding;
-    }
-
-    public MWebMeasure getTopPadding() {
-        if (null == this.getTopPaddingReference()) {
-            return null;
-        }
-        return this.getTopPaddingReference().clone();
-    }
-
-    public String getFormattedTopPadding() throws MNullPropertyWebException {
-        if (null == this.getTopPaddingReference()) {
-            throw new MNullPropertyWebException("Invalid top padding: reference null.");
-        }
-        return this.getTopPaddingReference().getFormattedValue();
-    }
-
-    protected MWebMeasure getRightPaddingReference() {
-        return this.rightPadding;
-    }
-
-    public MWebMeasure getRightPadding() {
-        if (null == this.getRightPaddingReference()) {
-            return null;
-        }
-        return this.getRightPaddingReference().clone();
-    }
-
-    public String getFormattedRightPadding() throws MNullPropertyWebException {
-        if (null == this.getRightPaddingReference()) {
-            throw new MNullPropertyWebException("Invalid right padding: reference null.");
-        }
-        return this.getRightPaddingReference().getFormattedValue();
-    }
-
-    protected MWebMeasure getBottomPaddingReference() {
-        return this.bottomPadding;
-    }
-
-    public MWebMeasure getBottomPadding() {
-        if (null == this.getBottomPaddingReference()) {
-            return null;
-        }
-        return this.getBottomPaddingReference().clone();
-    }
-
-    public String getFormattedBottomPadding() throws MNullPropertyWebException {
-        if (null == this.getBottomPaddingReference()) {
-            throw new MNullPropertyWebException("Invalid bottom padding: reference null.");
-        }
-        return this.getBottomPaddingReference().getFormattedValue();
-    }
-
-    protected MWebMeasure getLeftPaddingReference() {
-        return this.leftPadding;
-    }
-
-    public MWebMeasure getLeftPadding() {
-        if (null == this.getLeftPaddingReference()) {
-            return null;
-        }
-        return this.getLeftPaddingReference().clone();
-    }
-
-    public String getFormattedLeftPadding() throws MNullPropertyWebException {
-        if (null == this.getLeftPaddingReference()) {
-            throw new MNullPropertyWebException("Invalid left padding: reference null.");
-        }
-        return this.getLeftPaddingReference().getFormattedValue();
-    }
-
-    /* Text direction */
-
-    public void setTextDirection(MWebDisplayWidget.TextDirection textDirection) {
-        this.setTextDirection(textDirection, true);
-    }
-
-    protected void setTextDirection(MWebDisplayWidget.TextDirection textDirection, boolean refreshMode) {
-        this.textDirection = textDirection;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshTextDirection(false);
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public MWebDisplayWidget.TextDirection getTextDirection() {
-        return this.textDirection;
-    }
-
-    public String getFormattedTextDirection() throws MNullPropertyWebException {
-        if (null == this.getTextDirection()) {
-            throw new MNullPropertyWebException("Invalid text direction: property null.");
-        }
-        return this.getTextDirection().toString();
-    }
-
-    /* Visible mode */
-
-    public void setVisibleMode(boolean visibleMode) {
-        this.setVisibleMode(visibleMode, true);
-    }
-
-    protected void setVisibleMode(boolean visibleMode, boolean refreshMode) {
-        this.visibleMode = visibleMode;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshVisibleMode();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public boolean getVisibleMode() {
-        return this.visibleMode;
-    }
-
-    /* Display widgets */
-
-    protected MWebDisplayWidget getDisplayWidgetReferenceById(String id) throws MDisplayWidgetNotFoundWebException {
-        if ((null == id) || ("".equals(id))) {
-            throw new IllegalArgumentException("Invalid 'id': null or empty.");
-        }
-        //
-        String myId = null;
-        try {
-            myId = this.getId();
-        }
-        catch (MNoWidgetIdWebException exception) {
-            throw new MDisplayWidgetNotFoundWebException("Display widget id not available."); // no need to propagate exception
-        }
-        if (myId.equals(id)) {
-            return this;
-        }
-        throw new MDisplayWidgetNotFoundWebException(String.format("Invalid 'id': %s: display widget not available on this path.", id));
-    }
-
-    /* Validation */
-
-    public void validate() throws MValidationWebException {
-    }
-
-    /* Refresh */
-
-    public void checkPresence() throws MNoBrowserPageWebException, MNoViewWebException {
-        this.getViewReference().checkPresence();
-    }
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        this.refreshWidth(true);
-        this.refreshHeight(true);
-        this.refreshForegroundColor(true);
-        this.refreshBackgroundColor(true);
-        this.refreshBorder(null, true);
-        this.refreshFont(true);
-        this.refreshPadding(null, true);
-        this.refreshTextDirection(true);
-        //
-        this.refreshVisibleMode();
-    }
-
-    protected void refreshWidth(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        try {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').width = '%s'; }", this.getId(), this.getId(), this.getFormattedWidth()));
-        }
-        catch (MNullPropertyWebException exception) {
-            if (!directRefreshMode) {
-                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').width = null; }", this.getId(), this.getId()));
-            }
-        }
-    }
-
-    protected void refreshHeight(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        try {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').height = '%s'; }", this.getId(), this.getId(), this.getFormattedHeight()));
-        }
-        catch (MNullPropertyWebException exception) {
-            if (!directRefreshMode) {
-                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').height = null; }", this.getId(), this.getId()));
-            }
-        }
-    }
-
-    protected void refreshForegroundColor(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        try {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').color = '%s'; }", this.getId(), this.getId(), this.getFormattedForegroundColor()));
-        }
-        catch (MNullPropertyWebException exception) {
-            if (!directRefreshMode) {
-                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').color = null; }", this.getId(), this.getId()));
-            }
-        }
-    }
-
-    protected void refreshBackgroundColor(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        try {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').backgroundColor = '%s'; }", this.getId(), this.getId(), this.getFormattedBackgroundColor()));
-        }
-        catch (MNullPropertyWebException exception) {
-            if (!directRefreshMode) {
-                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').backgroundColor = null; }", this.getId(), this.getId()));
-            }
-        }
-    }
-
-    protected void refreshBorder(MWebDisplayWidget.Side borderSide, boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        if (null == borderSide) {
-            this.refreshBorder(MWebDisplayWidget.Side.TOP, directRefreshMode);
-            this.refreshBorder(MWebDisplayWidget.Side.RIGHT, directRefreshMode);
-            this.refreshBorder(MWebDisplayWidget.Side.BOTTOM, directRefreshMode);
-            this.refreshBorder(MWebDisplayWidget.Side.LEFT, directRefreshMode);
-        }
-        else {
-            String temporaryBorderSide = null;
-            try {
-                String formattedBorder = null;
-                if (MWebDisplayWidget.Side.TOP == borderSide) {
-                    temporaryBorderSide = "Top";
-                    formattedBorder = this.getFormattedTopBorder();
-                }
-                else if (MWebDisplayWidget.Side.RIGHT == borderSide) {
-                    temporaryBorderSide = "Right";
-                    formattedBorder = this.getFormattedRightBorder();
-                }
-                else if (MWebDisplayWidget.Side.BOTTOM == borderSide) {
-                    temporaryBorderSide = "Bottom";
-                    formattedBorder = this.getFormattedBottomBorder();
-                }
-                else if (MWebDisplayWidget.Side.LEFT == borderSide) {
-                    temporaryBorderSide = "Left";
-                    formattedBorder = this.getFormattedLeftBorder();
-                }
-                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').border%s = '%s'; }", this.getId(), this.getId(), temporaryBorderSide, formattedBorder));
-            }
-            catch (MNullPropertyWebException exception) {
-                if (!directRefreshMode) {
-                    this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').border%s = null; }", this.getId(), this.getId(), temporaryBorderSide));
-                }
-            }
-        }
-    }
-
-    protected void refreshFont(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        try {
-            String[] formattedFont = this.getFormattedFont();
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').font = '%s'; }", this.getId(), this.getId(), formattedFont[0]));
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textDecoration = '%s'; }", this.getId(), this.getId(), formattedFont[1]));
-        }
-        catch (MNullPropertyWebException exception) {
-            if (!directRefreshMode) {
-                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').font = null; }", this.getId(), this.getId()));
-                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textDecoration = null; }", this.getId(), this.getId()));
-            }
-        }
-    }
-
-    protected void refreshPadding(MWebDisplayWidget.Side paddingSide, boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        if (null == paddingSide) {
-            this.refreshPadding(MWebDisplayWidget.Side.TOP, directRefreshMode);
-            this.refreshPadding(MWebDisplayWidget.Side.RIGHT, directRefreshMode);
-            this.refreshPadding(MWebDisplayWidget.Side.BOTTOM, directRefreshMode);
-            this.refreshPadding(MWebDisplayWidget.Side.LEFT, directRefreshMode);
-        }
-        else {
-            String temporaryPaddingSide = null;
-            try {
-                String formattedPadding = null;
-                if (MWebDisplayWidget.Side.TOP == paddingSide) {
-                    temporaryPaddingSide = "Top";
-                    formattedPadding = this.getFormattedTopPadding();
-                }
-                else if (MWebDisplayWidget.Side.RIGHT == paddingSide) {
-                    temporaryPaddingSide = "Right";
-                    formattedPadding = this.getFormattedRightPadding();
-                }
-                else if (MWebDisplayWidget.Side.BOTTOM == paddingSide) {
-                    temporaryPaddingSide = "Bottom";
-                    formattedPadding = this.getFormattedBottomPadding();
-                }
-                else if (MWebDisplayWidget.Side.LEFT == paddingSide) {
-                    temporaryPaddingSide = "Left";
-                    formattedPadding = this.getFormattedLeftPadding();
-                }
-                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').padding%s = '%s'; }", this.getId(), this.getId(), temporaryPaddingSide, formattedPadding));
-            }
-            catch (MNullPropertyWebException exception) {
-                if (!directRefreshMode) {
-                    this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').padding%s = null; }", this.getId(), this.getId(), temporaryPaddingSide));
-                }
-            }
-        }
-    }
-
-    protected void refreshTextDirection(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        try {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').direction = '%s'; }", this.getId(), this.getId(), this.getFormattedTextDirection()));
-        }
-        catch (MNullPropertyWebException exception) {
-            if (!directRefreshMode) {
-                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').direction = null; }", this.getId(), this.getId()));
-            }
-        }
-    }
-
-    protected void refreshVisibleMode() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        if (this.getVisibleMode()) {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').visibility = 'visible'; }", this.getId(), this.getId()));
-        }
-        else {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').visibility = 'hidden'; }", this.getId(), this.getId()));
-        }
-    }
-
-    /* Messages */
-
-    public void onRefresh() {
-        try {
-            this.refresh();
-        }
-        catch (MNoBrowserPageWebException exception) {
-        }
-        catch (MNoViewWebException exception) {
-        }
-        catch (MNoWidgetIdWebException exception) {
-        }
-        catch (MResponseWebException exception) {
-        }
-        catch (MUniqueWidgetIdNotAvailableWebException exception) {
-        }
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebDownloader.java b/src/java/com/marcozanon/macaco/webui/MWebDownloader.java
deleted file mode 100644 (file)
index 1db3a6b..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.json.MInvalidValueJsonException;
-import com.marcozanon.macaco.json.MJsonObject;
-import com.marcozanon.macaco.json.MJsonString;
-import java.util.LinkedHashMap;
-
-public class MWebDownloader extends MWebWidget {
-
-    /* */
-
-    public MWebDownloader(MWebApplicationContext applicationContext) {
-        super(applicationContext);
-    }
-
-    /* Downloads */
-
-    public void forceDownload() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        MJsonObject downloadMessage = null;
-        try {
-            downloadMessage = new MJsonObject();
-            downloadMessage.setValue("widgetId", new MJsonString("\"" + this.getId() + "\""));
-            downloadMessage.setValue("event", new MJsonString("\"" + "onDownload" + "\""));
-            downloadMessage.setValue("parameters", new MJsonObject());
-        }
-        catch (MInvalidValueJsonException exception) { // cannot happen
-        }
-        //
-        MWebBrowserPage browserPage = this.getViewReference().getBrowserPageReference();
-        String destinationUrl = this.getApplicationContextReference().getRequestReference().getRequestURL().toString();
-        String parameters = "securityId=" + browserPage.getSecurityId() + "&message=" + downloadMessage.getFormattedValue();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("$('m_downloader').src = '%s?%s';", destinationUrl, parameters));
-    }
-
-    /* Messages */
-
-    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
-        super.processMessage(event, parameters);
-        //
-        if ("onDownload".equals(event)) {
-            this.onDownload();
-        }
-        else {
-            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
-        }
-    }
-
-    public void onDownload() {
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebException.java b/src/java/com/marcozanon/macaco/webui/MWebException.java
deleted file mode 100644 (file)
index 1d625a0..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.MException;
-
-public abstract class MWebException extends MException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MWebException() {
-        super();
-    }
-
-    public MWebException(String message) {
-        super(message);
-    }
-
-    public MWebException(Throwable error) {
-        super(error);
-    }
-
-    public MWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebExtendedTextBox.java b/src/java/com/marcozanon/macaco/webui/MWebExtendedTextBox.java
deleted file mode 100644 (file)
index 197b9f9..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import java.util.LinkedHashMap;
-
-public class MWebExtendedTextBox extends MWebTextBox {
-
-    /* */
-
-    public MWebExtendedTextBox(MWebApplicationContext applicationContext) {
-        super(applicationContext);
-    }
-
-    public MWebExtendedTextBox(MWebApplicationContext applicationContext, String text) {
-        this(applicationContext);
-        //
-        this.setText(text);
-    }
-
-    /* Refresh */
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        String onBlurFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onBlur', {'text': this.value});", this.getId());
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<textarea class=\"MWebExtendedTextBox %s\" style=\"display: inline-block;\" onblur=\"%s\" id=\"%s\" cols=\"1\" rows=\"1\"></textarea>'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onBlurFunction), this.getId()));
-        //
-        super.refresh();
-        //
-        this.refreshText();
-        this.refreshTextAlignment(true);
-        this.refreshEnabledMode();
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebFont.java b/src/java/com/marcozanon/macaco/webui/MWebFont.java
deleted file mode 100644 (file)
index b8455d7..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.MObject;
-
-public class MWebFont extends MObject {
-
-    public static enum Style {
-        ITALIC("italic"),
-        NORMAL("normal"),
-        OBLIQUE("oblique");
-        private String name = null;
-        private Style(String name) {
-            this.name = name;
-        }
-        public String toString() {
-            return this.name;
-        }
-    };
-
-    public static enum Variant {
-        NORMAL("normal"),
-        SMALL_CAPS("small-caps");
-        private String name = null;
-        private Variant(String name) {
-            this.name = name;
-        }
-        public String toString() {
-            return this.name;
-        }
-    };
-
-    public static enum Weight {
-        BOLD("bold"),
-        BOLDER("bolder"),
-        LIGHTER("lighter"),
-        NORMAL("normal");
-        private String name = null;
-        private Weight(String name) {
-            this.name = name;
-        }
-        public String toString() {
-            return this.name;
-        }
-    };
-
-    public static final String MONOSPACE_FAMILY = "monospace";
-    public static final String SANS_SERIF_FAMILY = "sans-serif";
-    public static final String SERIF_FAMILY = "serif";
-
-    public static enum Decoration {
-        BLINK("blink"),
-        LINE_THROUGH("line-through"),
-        NONE("none"),
-        OVERLINE("overline"),
-        UNDERLINE("underline");
-        private String name = null;
-        private Decoration(String name) {
-            this.name = name;
-        }
-        public String toString() {
-            return this.name;
-        }
-    };
-
-    protected MWebFont.Style style = null;
-    protected MWebFont.Variant variant = null;
-    protected MWebFont.Weight weight = null;
-    protected MWebMeasure size = null;
-    protected String family = null;
-    protected MWebFont.Decoration decoration = null;
-
-    /* */
-
-    public MWebFont(MWebFont.Style style, MWebFont.Variant variant, MWebFont.Weight weight, MWebMeasure size, String family, MWebFont.Decoration decoration) {
-        super();
-        //
-        if (null == style) {
-            throw new IllegalArgumentException("Invalid 'style': null.");
-        }
-        if (null == variant) {
-            throw new IllegalArgumentException("Invalid 'variant': null.");
-        }
-        if (null == weight) {
-            throw new IllegalArgumentException("Invalid 'weight': null.");
-        }
-        if (null == size) {
-            throw new IllegalArgumentException("Invalid 'size': null.");
-        }
-        if ((null == family) || ("".equals(family))) {
-            throw new IllegalArgumentException("Invalid 'family': null or empty.");
-        }
-        if (null == decoration) {
-            throw new IllegalArgumentException("Invalid 'decoration': null.");
-        }
-        //
-        this.style = style;
-        this.variant = variant;
-        this.weight = weight;
-        this.size = size;
-        this.family = family;
-        this.decoration = decoration;
-    }
-
-    public MWebFont clone() {
-        return new MWebFont(this.getStyle(), this.getVariant(), this.getWeight(), this.getSizeReference().clone(), this.getFamily(), this.getDecoration());
-    }
-
-    /* Font */
-
-    protected MWebFont.Style getStyle() {
-        return this.style;
-    }
-
-    protected MWebFont.Variant getVariant() {
-        return this.variant;
-    }
-
-    protected MWebFont.Weight getWeight() {
-        return this.weight;
-    }
-
-    protected MWebMeasure getSizeReference() {
-        return this.size;
-    }
-
-    protected String getFamily() {
-        return this.family;
-    }
-
-    protected MWebFont.Decoration getDecoration() {
-        return this.decoration;
-    }
-
-    public Object[] getValue() {
-        Object[] value = new Object[6];
-        value[0] = this.getStyle();
-        value[1] = this.getVariant();
-        value[2] = this.getWeight();
-        value[3] = this.getSizeReference().clone();
-        value[4] = this.getFamily();
-        value[5] = this.getDecoration();
-        return value;
-    }
-
-    public String[] getFormattedValue() {
-        String[] formattedValue = new String[2];
-        formattedValue[0] = this.getStyle().toString() + " " + this.getVariant().toString() + " " + this.getWeight().toString() + " " + this.getSizeReference().getFormattedValue() + " " + this.getFamily();
-        formattedValue[1] = this.getDecoration().toString();
-        return formattedValue;
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebGridLayout.java b/src/java/com/marcozanon/macaco/webui/MWebGridLayout.java
deleted file mode 100644 (file)
index 2744102..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import java.util.LinkedHashMap;
-
-public class MWebGridLayout extends MWebDirectWidget {
-
-    protected MWebGridLayoutCell[][] cells = null;
-
-    /* */
-
-    public MWebGridLayout(MWebApplicationContext applicationContext, int rowCount, int columnCount) {
-        super(applicationContext);
-        //
-        this.setWidth(new MWebMeasure(100, MWebMeasure.Unit.PERCENT)); // manual override
-        //
-        if (rowCount < 1) {
-            throw new IllegalArgumentException(String.format("Invalid 'rowCount': %s.", rowCount));
-        }
-        if (columnCount < 1) {
-            throw new IllegalArgumentException(String.format("Invalid 'columnCount': %s.", columnCount));
-        }
-        //
-        this.cells = new MWebGridLayoutCell[rowCount][columnCount];
-        for (int r = 0; r < rowCount; r++) {
-            for (int c = 0; c < columnCount; c++) {
-                this.cells[r][c] = new MWebGridLayoutCell(this.getApplicationContextReference(), this);
-            }
-        }
-    }
-
-    /* Cells */
-
-    public int getRowCount() {
-        if (null == this.getCellsReference()) {
-            return 0;
-        }
-        return this.getCellsReference().length;
-    }
-
-    public int getColumnCount() {
-        if (null == this.getCellsReference()) {
-            return 0;
-        }
-        return this.getCellsReference()[0].length;
-    }
-
-    protected MWebGridLayoutCell[][] getCellsReference() {
-        return this.cells;
-    }
-
-    public MWebGridLayoutCell getCellReference(int rowIndex, int columnIndex) {
-        if ((rowIndex < 0) || (rowIndex > (this.getCellsReference().length - 1))) {
-            throw new IllegalArgumentException(String.format("Invalid 'rowIndex': %s.", rowIndex));
-        }
-        if ((columnIndex < 0) || (columnIndex > (this.getCellsReference()[0].length - 1))) {
-            throw new IllegalArgumentException(String.format("Invalid 'columnIndex': %s.", columnIndex));
-        }
-        //
-        return this.getCellsReference()[rowIndex][columnIndex];
-    }
-
-    /* View */
-
-    protected void setView(MWebView view) throws MUniqueWidgetIdNotAvailableWebException {
-        super.setView(view);
-        //
-        for (int r = 0; r < this.getRowCount(); r++) {
-            for (int c = 0; c < this.getColumnCount(); c++) {
-                this.getCellReference(r, c).setView(view);
-            }
-        }
-    }
-
-    /* Display widgets */
-
-    protected MWebDisplayWidget getDisplayWidgetReferenceById(String id) throws MDisplayWidgetNotFoundWebException {
-        try {
-            return super.getDisplayWidgetReferenceById(id);
-        }
-        catch (MDisplayWidgetNotFoundWebException exception) {
-            for (int r = 0; r < this.getRowCount(); r++) {
-                for (int c = 0; c < this.getColumnCount(); c++) {
-                    try {
-                        return this.getCellReference(r, c).getDisplayWidgetReferenceById(id);
-                    }
-                    catch (MDisplayWidgetNotFoundWebException exception2) {
-                    }
-                }
-            }
-            throw new MDisplayWidgetNotFoundWebException(String.format("Invalid 'id': %s: display widget not available on this path.", id)); // no need to propagate exception
-        }
-    }
-
-    /* Refresh */
-
-    protected boolean isCellRefreshable(int rowIndex, int columnIndex) {
-        if ((rowIndex < 0) || (rowIndex > (this.getCellsReference().length - 1))) {
-            throw new IllegalArgumentException(String.format("Invalid 'rowIndex': %s.", rowIndex));
-        }
-        if ((columnIndex < 0) || (columnIndex > (this.getCellsReference()[0].length - 1))) {
-            throw new IllegalArgumentException(String.format("Invalid 'columnIndex': %s.", columnIndex));
-        }
-        //
-        int[][] cellsRefreshableMode = new int[rowIndex + 1][columnIndex + 1]; // to avoid recursion
-        for (int r = 0; r <= rowIndex; r++) {
-            for (int c = 0; c <= columnIndex; c++) {
-                if (0 > cellsRefreshableMode[r][c]) {
-                    continue;
-                }
-                cellsRefreshableMode[r][c] = 1;
-                int rs = this.getCellReference(r, c).getRowSpan();
-                int cs = this.getCellReference(r, c).getColumnSpan();
-                if ((rs > 1) || (cs > 1)) {
-                    for (int rsi = r + 1; rsi <= Math.min(rowIndex, r + rs - 1); rsi++) {
-                        for (int csi = c + 1; csi <= Math.min(columnIndex, c + cs - 1); csi++) {
-                            cellsRefreshableMode[rsi][csi] = -1;
-                        }
-                    }
-                }
-                if ((r == rowIndex) && (c == columnIndex)) {
-                    return true;
-                }
-                if ((0 < cellsRefreshableMode[r][c]) && ((r + this.getCellReference(r, c).getRowSpan() - 1) >= rowIndex) && ((c + this.getCellReference(r, c).getColumnSpan() - 1) >= columnIndex)) {
-                    return false;
-                }
-            }
-        }
-        //
-        return true; // necessary to avoid Java compilation errors
-    }
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        StringBuilder content = new StringBuilder("");
-        content.append(String.format("<table class=\"MWebGridLayoutTable %s\" style=\"display: inline-table;\" id=\"%s\">", customClasses, this.getId()));
-        for (int r = 0; r < this.getRowCount(); r++) {
-            content.append(String.format("<tr class=\"MWebGridLayoutRow %s\">", customClasses));
-            for (int c = 0; c < this.getColumnCount(); c++) {
-                String displayedMode = "";
-                if (!this.isCellRefreshable(r, c)) {
-                    displayedMode = "display: none;";
-                    this.getCellReference(r, c).setVisibleMode(false, false); 
-                }
-                content.append(String.format("<td class=\"MWebGridLayoutCell %s\" style=\"%s\" id=\"%s\" rowspan=\"%s\" colspan=\"%s\"></td>", customClasses, displayedMode, this.getCellReference(r, c).getId(), Math.min(this.getCellReference(r, c).getRowSpan(), this.getRowCount() - r), Math.min(this.getCellReference(r, c).getColumnSpan(), this.getColumnCount() - c)));
-            }
-            content.append("</tr>");
-        }
-        content.append("</table>");
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(content.toString())));
-        //
-        for (int r = 0; r < this.getRowCount(); r++) {
-            for (int c = 0; c < this.getColumnCount(); c++) {
-                this.getCellReference(r, c).onRefresh();
-            }
-        }
-        //
-        super.refresh();
-    }
-
-    /* Messages */
-
-    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
-        super.processMessage(event, parameters);
-        //
-        if ("onRefresh".equals(event)) {
-            this.onRefresh();
-        }
-        else {
-            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
-        }
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebGridLayoutCell.java b/src/java/com/marcozanon/macaco/webui/MWebGridLayoutCell.java
deleted file mode 100644 (file)
index 4d503fd..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import java.util.LinkedHashMap;
-
-public class MWebGridLayoutCell extends MWebCellWidget {
-
-    protected MWebDirectWidget content = null;
-
-    protected MWebGridLayout container = null;
-
-    protected int rowSpan = 1;
-    protected int columnSpan = 1;
-
-    /* */
-
-    public MWebGridLayoutCell(MWebApplicationContext applicationContext, MWebGridLayout container) {
-        super(applicationContext);
-        //
-        if (null == container) {
-            throw new IllegalArgumentException("Invalid 'container': null.");
-        }
-        //
-        this.container = container;
-    }
-
-    /* Content */
-
-    public void setContent(MWebDirectWidget directWidget) throws MUniqueWidgetIdNotAvailableWebException {
-        this.setContent(directWidget, true);
-    }
-
-    protected void setContent(MWebDirectWidget directWidget, boolean refreshMode) throws MUniqueWidgetIdNotAvailableWebException {
-        try {
-            this.getContentReference().setView(null);
-        }
-        catch (MNoCellContentWebException exception) {
-        }
-        catch (MUniqueWidgetIdNotAvailableWebException exception) { // cannot happen
-        }
-        //
-        this.content = directWidget;
-        //
-        MWebDirectWidget content = null;
-        try {
-            content = this.getContentReference();
-            content.setView(this.getViewReference());
-        }
-        catch (MNoCellContentWebException exception) {
-        }
-        catch (MNoViewWebException exception) {
-            content.setView(null);
-        }
-        //
-        if (refreshMode) {
-            try {
-                this.refreshContent();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public MWebDirectWidget getContentReference() throws MNoCellContentWebException {
-        if (null == this.content) {
-            throw new MNoCellContentWebException("Invalid content: null.");
-        }
-        //
-        return this.content;
-    }
-
-    /* View */
-
-    protected void setView(MWebView view) throws MUniqueWidgetIdNotAvailableWebException {
-        super.setView(view);
-        //
-        try {
-            this.getContentReference().setView(view);
-        }
-        catch (MNoCellContentWebException exception) {
-        }
-    }
-
-    /* Container */
-
-    public MWebGridLayout getContainerReference() {
-        return this.container;
-    }
-
-    /* Span */
-
-    public void setRowSpan(int rowSpan) {
-        if (rowSpan < 1) {
-            throw new IllegalArgumentException("Invalid 'rowSpan': must be > 1.");
-        }
-        //
-        this.rowSpan = rowSpan;
-        //
-        try {
-            this.getContainerReference().refresh();
-        }
-        catch (MNoBrowserPageWebException exception) {
-        }
-        catch (MNoViewWebException exception) {
-        }
-        catch (MNoWidgetIdWebException exception) {
-        }
-        catch (MResponseWebException exception) {
-        }
-        catch (MUniqueWidgetIdNotAvailableWebException exception) {
-        }
-    }
-
-    public int getRowSpan() {
-        return this.rowSpan;
-    }
-
-    public void setColumnSpan(int columnSpan) {
-        if (columnSpan < 1) {
-            throw new IllegalArgumentException("Invalid 'columnSpan': must be > 1.");
-        }
-        //
-        this.columnSpan = columnSpan;
-        //
-        try {
-            this.getContainerReference().refresh();
-        }
-        catch (MNoBrowserPageWebException exception) {
-        }
-        catch (MNoViewWebException exception) {
-        }
-        catch (MNoWidgetIdWebException exception) {
-        }
-        catch (MResponseWebException exception) {
-        }
-        catch (MUniqueWidgetIdNotAvailableWebException exception) {
-        }
-    }
-
-    public int getColumnSpan() {
-        return this.columnSpan;
-    }
-
-    /* Display widgets */
-
-    protected MWebDisplayWidget getDisplayWidgetReferenceById(String id) throws MDisplayWidgetNotFoundWebException {
-        try {
-            return super.getDisplayWidgetReferenceById(id);
-        }
-        catch (MDisplayWidgetNotFoundWebException exception) {
-            try {
-                return this.getContentReference().getDisplayWidgetReferenceById(id);
-            }
-            catch (MDisplayWidgetNotFoundWebException exception2) {
-                throw new MDisplayWidgetNotFoundWebException(String.format("Invalid 'id': %s: display widget not available on this path.", id)); // no need to propagate exception
-            }
-            catch (MNoCellContentWebException exception2) {
-                throw new MDisplayWidgetNotFoundWebException(String.format("Invalid 'id': %s: no cell content.", id)); // no need to propagate exception
-            }
-        }
-    }
-
-    /* Refresh */
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        this.refreshContent();
-        //
-        super.refresh();
-    }
-
-    protected void refreshContent() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        MWebDirectWidget content = null;
-        try {
-            content = this.getContentReference();
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '<div id=\"%s\"></div>'; }", this.getId(), this.getId(), content.getId()));
-            content.onRefresh();
-        }
-        catch (MNoCellContentWebException exception) {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = ''; }", this.getId(), this.getId()));
-        }
-    }
-
-    /* Messages */
-
-    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
-        super.processMessage(event, parameters);
-        //
-        if ("onRefresh".equals(event)) {
-            this.onRefresh();
-        }
-        else {
-            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
-        }
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebImage.java b/src/java/com/marcozanon/macaco/webui/MWebImage.java
deleted file mode 100644 (file)
index f7eb290..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import java.util.LinkedHashMap;
-
-public class MWebImage extends MWebDirectWidget {
-
-    protected String imageSource = null;
-    protected String alternativeText = "";
-
-    /* */
-
-    public MWebImage(MWebApplicationContext applicationContext) {
-        super(applicationContext);
-    }
-
-    public MWebImage(MWebApplicationContext applicationContext, String imageSource, String alternativeText) {
-        this(applicationContext);
-        //
-        this.setImageSource(imageSource);
-        this.setAlternativeText(alternativeText);
-    }
-
-    /* Image source */
-
-    public void setImageSource(String imageSource) {
-        this.setImageSource(imageSource, true);
-    }
-
-    protected void setImageSource(String imageSource, boolean refreshMode) {
-        this.imageSource = imageSource;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshImageSource();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public String getImageSource() {
-        return this.imageSource;
-    }
-
-    /* Alternative text */
-
-    public void setAlternativeText(String alternativeText) {
-        this.setAlternativeText(alternativeText, true);
-    }
-
-    protected void setAlternativeText(String alternativeText, boolean refreshMode) {
-        if (null == alternativeText) {
-            throw new IllegalArgumentException("Invalid 'alternativeText': null.");
-        }
-        //
-        this.alternativeText = alternativeText;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshAlternativeText();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public String getAlternativeText() {
-        return this.alternativeText;
-    }
-
-    /* Refresh */
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        String onClickFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onClick', {});", this.getId());
-        String onDoubleClickFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onDoubleClick', {});", this.getId());
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<img class=\"MWebImage %s\" style=\"display: inline-block;\" onclick=\"%s\" ondblclick=\"%s\" id=\"%s\" src=\"%s/null\" alt=\"\" />'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onClickFunction), MWebString.getJavascriptEscapedString(onDoubleClickFunction), this.getId(), this.getApplicationContextReference().getRequestReference().getRequestURL()));
-        //
-        super.refresh();
-        //
-        this.refreshImageSource();
-        this.refreshAlternativeText();
-    }
-
-    protected void refreshImageSource() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        if (null == this.getImageSource()) {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').src = '%s/null'; }", this.getId(), this.getId(), this.getApplicationContextReference().getRequestReference().getRequestURL()));
-        }
-        else {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').src = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(this.getImageSource())));
-        }
-    }
-
-    protected void refreshAlternativeText() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').alt = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(this.getAlternativeText())));
-    }
-
-    /* Messages */
-
-    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
-        super.processMessage(event, parameters);
-        //
-        if ("onClick".equals(event)) {
-            if (!this.getVisibleMode()) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
-            }
-            this.onClick();
-        }
-        else if ("onDoubleClick".equals(event)) {
-            if (!this.getVisibleMode()) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
-            }
-            this.onDoubleClick();
-        }
-        else if ("onRefresh".equals(event)) {
-            this.onRefresh();
-        }
-        else {
-            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
-        }
-    }
-
-    public void onClick() {
-    }
-
-    public void onDoubleClick() {
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebImageButton.java b/src/java/com/marcozanon/macaco/webui/MWebImageButton.java
deleted file mode 100644 (file)
index ba5df60..0000000
+++ /dev/null
@@ -1,326 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import java.util.LinkedHashMap;
-
-public class MWebImageButton extends MWebDirectWidget {
-
-    public static enum ImageAlignment {
-        TOP("top"),
-        RIGHT("right"),
-        BOTTOM("bottom"),
-        LEFT("left");
-        private String name = null;
-        private ImageAlignment(String name) {
-            this.name = name;
-        }
-        public String toString() {
-            return this.name;
-        }
-    };
-
-    protected String text = "";
-    protected String imageSource = null;
-    protected MWebImageButton.ImageAlignment imageAlignment = null;
-
-    protected boolean enabledMode = true;
-
-    /* */
-
-    public MWebImageButton(MWebApplicationContext applicationContext) {
-        super(applicationContext);
-    }
-
-    public MWebImageButton(MWebApplicationContext applicationContext, String text) {
-        this(applicationContext);
-        //
-        this.setText(text);
-    }
-
-    public MWebImageButton(MWebApplicationContext applicationContext, String text, String imageSource, MWebImageButton.ImageAlignment imageAlignment) {
-        this(applicationContext, text);
-        //
-        this.setImageSource(imageSource);
-        this.setImageAlignment(imageAlignment);
-    }
-
-    /* Focus */
-
-    public void setFocus() {
-        try {
-            this.refreshFocus();
-        }
-        catch (MNoBrowserPageWebException exception) {
-        }
-        catch (MNoViewWebException exception) {
-        }
-        catch (MNoWidgetIdWebException exception) {
-        }
-        catch (MResponseWebException exception) {
-        }
-    }
-
-    /* Text */
-
-    public void setText(String text) {
-        this.setText(text, true);
-    }
-
-    protected void setText(String text, boolean refreshMode) {
-        if (null == text) {
-            throw new IllegalArgumentException("Invalid 'text': null.");
-        }
-        //
-        this.text = text;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshText();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public String getText() {
-        return this.text;
-    }
-
-    /* Image source */
-
-    public void setImageSource(String imageSource) {
-        this.setImageSource(imageSource, true);
-    }
-
-    protected void setImageSource(String imageSource, boolean refreshMode) {
-        this.imageSource = imageSource;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshImageSource();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public String getImageSource() {
-        return this.imageSource;
-    }
-
-    /* Image alignment */
-
-    public void setImageAlignment(MWebImageButton.ImageAlignment imageAlignment) {
-        this.setImageAlignment(imageAlignment, true);
-    }
-
-    protected void setImageAlignment(MWebImageButton.ImageAlignment imageAlignment, boolean refreshMode) {
-        this.imageAlignment = imageAlignment;
-        //
-        if (refreshMode) {
-            try {
-                this.refresh(); // must refresh everything
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-            catch (MUniqueWidgetIdNotAvailableWebException exception) {
-            }
-        }
-    }
-
-    public MWebImageButton.ImageAlignment getImageAlignment() {
-        return this.imageAlignment;
-    }
-
-    public String getFormattedImageAlignment() throws MNullPropertyWebException {
-        if (null == this.getImageAlignment()) {
-            throw new MNullPropertyWebException("Invalid image alignment: property null.");
-        }
-        return this.getImageAlignment().toString();
-    }
-
-    /* Enabled mode */
-
-    public void setEnabledMode(boolean enabledMode) {
-        this.setEnabledMode(enabledMode, true);
-    }
-
-    protected void setEnabledMode(boolean enabledMode, boolean refreshMode) {
-        this.enabledMode = enabledMode;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshEnabledMode();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public boolean getEnabledMode() {
-        return this.enabledMode;
-    }
-
-    /* Refresh */
-
-    protected void refreshFocus() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').focus(); }", this.getId(), this.getId()));
-    }
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        StringBuilder imageContent = new StringBuilder(String.format("<td class=\"MWebImageButtonImageCell %s\"><img class=\"MWebImageButtonImage %s\" id=\"%s_image\" src=\"%s/null\" alt=\"\" /></td>", customClasses, customClasses, this.getId(), this.getApplicationContextReference().getRequestReference().getRequestURL()));
-        StringBuilder textContent = new StringBuilder(String.format("<td class=\"MWebImageButtonTextCell %s\" id=\"%s_textCell\"></td>", customClasses, this.getId()));
-        StringBuilder content = new StringBuilder("");
-        content.append(String.format("<table class=\"MWebImageButtonTable %s\">", customClasses));
-        MWebImageButton.ImageAlignment imageAlignment = this.getImageAlignment();
-        if (null == imageAlignment) {
-            content.append(String.format("<tr class=\"MWebImageButtonRow %s\">", customClasses));
-            content.append(textContent);
-            content.append("</tr>");
-        }
-        else if (MWebImageButton.ImageAlignment.TOP == imageAlignment) {
-            content.append(String.format("<tr class=\"MWebImageButtonRow %s\">", customClasses));
-            content.append(imageContent);
-            content.append("</tr>");
-            content.append(String.format("<tr class=\"MWebImageButtonRow %s\">", customClasses));
-            content.append(textContent);
-            content.append("</tr>");
-        }
-        else if (MWebImageButton.ImageAlignment.RIGHT == imageAlignment) {
-            content.append(String.format("<tr class=\"MWebImageButtonRow %s\">", customClasses));
-            content.append(textContent);
-            content.append(imageContent);
-            content.append("</tr>");
-        }
-        else if (MWebImageButton.ImageAlignment.BOTTOM == imageAlignment) {
-            content.append(String.format("<tr class=\"MWebImageButtonRow %s\">", customClasses));
-            content.append(textContent);
-            content.append("</tr>");
-            content.append(String.format("<tr class=\"MWebImageButtonRow %s\">", customClasses));
-            content.append(imageContent);
-            content.append("</tr>");
-        }
-        else if (MWebImageButton.ImageAlignment.LEFT == imageAlignment) {
-            content.append(String.format("<tr class=\"MWebImageButtonRow %s\">", customClasses));
-            content.append(imageContent);
-            content.append(textContent);
-            content.append("</tr>");
-        }
-        content.append("</table>");
-        String onClickFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onClick', {});", this.getId());
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<button class=\"MWebImageButton %s\" style=\"display: inline-block;\" onclick=\"%s\" id=\"%s\">%s</button>'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onClickFunction), this.getId(), MWebString.getJavascriptEscapedString(content.toString())));
-        //
-        super.refresh();
-        //
-        this.refreshText();
-        this.refreshImageSource();
-        this.refreshEnabledMode();
-    }
-
-    protected void refreshText() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s_textCell').innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(this.getText())));
-    }
-
-    protected void refreshImageSource() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        try {
-            this.getFormattedImageAlignment();
-            if (null == this.getImageSource()) {
-                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s_image').src = '%s/null'; }", this.getId(), this.getId(), this.getApplicationContextReference().getRequestReference().getRequestURL()));
-            }
-            else {
-                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s_image').src = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(this.getImageSource())));
-            }
-        }
-        catch (MNullPropertyWebException exception) {
-        }
-    }
-
-    protected void refreshEnabledMode() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').disabled = %s; }", this.getId(), this.getId(), !this.getEnabledMode()));
-    }
-
-    /* Messages */
-
-    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
-        super.processMessage(event, parameters);
-        //
-        if ("onClick".equals(event)) {
-            if ((!this.getVisibleMode()) || (!this.getEnabledMode())) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden or disabled.", event));
-            }
-            this.onClick();
-        }
-        else if ("onRefresh".equals(event)) {
-            this.onRefresh();
-        }
-        else {
-            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
-        }
-    }
-
-    public void onClick() {
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebLabel.java b/src/java/com/marcozanon/macaco/webui/MWebLabel.java
deleted file mode 100644 (file)
index 64bc32a..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import java.util.LinkedHashMap;
-
-public class MWebLabel extends MWebDirectWidget {
-
-    public static enum TextAlignment {
-        LEFT("left"),
-        CENTER("center"),
-        RIGHT("right"),
-        JUSTIFIED("justify");
-        private String name = null;
-        private TextAlignment(String name) {
-            this.name = name;
-        }
-        public String toString() {
-            return this.name;
-        }
-    };
-
-    protected String text = "";
-    protected MWebLabel.TextAlignment textAlignment = null;
-
-    /* */
-
-    public MWebLabel(MWebApplicationContext applicationContext) {
-        super(applicationContext);
-    }
-
-    public MWebLabel(MWebApplicationContext applicationContext, String text) {
-        this(applicationContext);
-        //
-        this.setText(text);
-    }
-
-    /* Text */
-
-    public void setText(String text) {
-        this.setText(text, true);
-    }
-
-    protected void setText(String text, boolean refreshMode) {
-        if (null == text) {
-            throw new IllegalArgumentException("Invalid 'text': null.");
-        }
-        //
-        this.text = text;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshText();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public String getText() {
-        return this.text;
-    }
-
-    /* Text alignment */
-
-    public void setTextAlignment(MWebLabel.TextAlignment textAlignment) {
-        this.setTextAlignment(textAlignment, true);
-    }
-
-    protected void setTextAlignment(MWebLabel.TextAlignment textAlignment, boolean refreshMode) {
-        this.textAlignment = textAlignment;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshTextAlignment(false);
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public MWebLabel.TextAlignment getTextAlignment() {
-        return this.textAlignment;
-    }
-
-    public String getFormattedTextAlignment() throws MNullPropertyWebException {
-        if (null == this.getTextAlignment()) {
-            throw new MNullPropertyWebException("Invalid text alignment: property null.");
-        }
-        return this.getTextAlignment().toString();
-    }
-
-    /* Refresh */
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        String onClickFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onClick', {});", this.getId());
-        String onDoubleClickFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onDoubleClick', {});", this.getId());
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<div class=\"MWebLabel %s\" style=\"display: inline-block;\" onclick=\"%s\" ondblclick=\"%s\" id=\"%s\"></div>'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onClickFunction), MWebString.getJavascriptEscapedString(onDoubleClickFunction), this.getId()));
-        //
-        super.refresh();
-        //
-        this.refreshText();
-        this.refreshTextAlignment(true);
-    }
-
-    protected void refreshText() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(MWebString.getXhtmlEscapedString(this.getText()))));
-    }
-
-    protected void refreshTextAlignment(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        try {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textAlign = '%s'; }", this.getId(), this.getId(), this.getFormattedTextAlignment()));
-        }
-        catch (MNullPropertyWebException exception) {
-            if (!directRefreshMode) {
-                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textAlign = null; }", this.getId(), this.getId()));
-            }
-        }
-    }
-
-    /* Messages */
-
-    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
-        super.processMessage(event, parameters);
-        //
-        if ("onClick".equals(event)) {
-            if (!this.getVisibleMode()) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
-            }
-            this.onClick();
-        }
-        else if ("onDoubleClick".equals(event)) {
-            if (!this.getVisibleMode()) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
-            }
-            this.onDoubleClick();
-        }
-        else if ("onRefresh".equals(event)) {
-            this.onRefresh();
-        }
-        else {
-            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
-        }
-    }
-
-    public void onClick() {
-    }
-
-    public void onDoubleClick() {
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebMeasure.java b/src/java/com/marcozanon/macaco/webui/MWebMeasure.java
deleted file mode 100644 (file)
index fb6dc0e..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.MObject;
-
-public class MWebMeasure extends MObject {
-
-    public static enum Unit {
-        CM("cm"),
-        EM("em"),
-        EX("ex"),
-        IN("in"),
-        MM("mm"),
-        PC("pc"),
-        PERCENT("%"),
-        PT("pt"),
-        PX("px");
-        private String name = null;
-        private Unit(String name) {
-            this.name = name;
-        }
-        public String toString() {
-            return this.name;
-        }
-    };
-
-    protected Number number = null;
-    protected MWebMeasure.Unit unit = null;
-
-    /* */
-
-    public MWebMeasure(Number number, MWebMeasure.Unit unit) {
-        super();
-        //
-        if (null == number) {
-            throw new IllegalArgumentException("Invalid 'number': null.");
-        }
-        if (null == unit) {
-            throw new IllegalArgumentException("Invalid 'unit': null.");
-        }
-        //
-        this.number = number;
-        this.unit = unit;
-    }
-
-    public MWebMeasure clone() {
-        return new MWebMeasure(this.getNumber(), this.getUnit());
-    }
-
-    /* Measure */
-
-    protected Number getNumber() {
-        return this.number;
-    }
-
-    protected MWebMeasure.Unit getUnit() {
-        return this.unit;
-    }
-
-    public Object[] getValue() {
-        Object[] value = new Object[2];
-        value[0] = this.getNumber();
-        value[1] = this.getUnit();
-        return value;
-    }
-
-    public String getFormattedValue() {
-        return this.getNumber() + this.getUnit().toString();
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebMessage.java b/src/java/com/marcozanon/macaco/webui/MWebMessage.java
deleted file mode 100644 (file)
index 32e88e0..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.MObject;
-import com.marcozanon.macaco.json.MInvalidValueJsonException;
-import com.marcozanon.macaco.json.MJsonObject;
-import com.marcozanon.macaco.json.MJsonString;
-import com.marcozanon.macaco.json.MValueNotFoundJsonException;
-import java.util.LinkedHashMap;
-
-public class MWebMessage extends MObject {
-
-    protected String widgetId = null;
-    protected String event = null;
-    protected LinkedHashMap<String, String> parameters = null;
-
-    /* */
-
-    public MWebMessage(String message) throws MMessagingWebException {
-        super();
-        //
-        if ((null == message) || "".equals(message)) {
-            throw new IllegalArgumentException("Invalid 'message': null or empty.");
-        }
-        //
-        MJsonObject jsonMessage = null;
-        try {
-            jsonMessage = new MJsonObject(message);
-        }
-        catch (MInvalidValueJsonException exception) {
-            throw new MMessagingWebException("Invalid 'message': not a Json object."); // no need to propagate exception
-        }
-        // parse widget id component
-        try {
-            this.widgetId = ((MJsonString)jsonMessage.getValue("widgetId")).getValue();
-        }
-        catch (ClassCastException exception) {
-            throw new MMessagingWebException("Invalid 'message': invalid widget id."); // no need to propagate exception
-        }
-        catch (MValueNotFoundJsonException exception) {
-            throw new MMessagingWebException("Invalid 'message': no widget id key."); // no need to propagate exception
-        }
-        // parse event component
-        try {
-            String temporaryEvent = ((MJsonString)jsonMessage.getValue("event")).getValue();
-            if ("".equals(temporaryEvent)) {
-                throw new MMessagingWebException("Invalid 'message': event empty.");
-            }
-            this.event = temporaryEvent;
-        }
-        catch (ClassCastException exception) {
-            throw new MMessagingWebException("Invalid 'message': invalid event."); // no need to propagate exception
-        }
-        catch (MValueNotFoundJsonException exception) {
-            throw new MMessagingWebException("Invalid 'message': no event key."); // no need to propagate exception
-        }
-        // parse parameters component
-        this.parameters = new LinkedHashMap<String, String>();
-        try {
-            MJsonObject temporaryParameters = (MJsonObject)jsonMessage.getValue("parameters");
-            for (String key: temporaryParameters.getKeys()) {
-                this.parameters.put(key, ((MJsonString)temporaryParameters.getValue(key)).getValue());
-            }
-        }
-        catch (ClassCastException exception) {
-            throw new MMessagingWebException("Invalid 'message': invalid parameters."); // no need to propagate exception
-        }
-        catch (MValueNotFoundJsonException exception) {
-            throw new MMessagingWebException("Invalid 'message': no parameters key."); // no need to propagate exception
-        }
-    }
-
-    public MWebMessage clone() {
-        try {
-            MJsonString tmpString = null;
-            MJsonObject tmpMessage = new MJsonObject("{}");
-            //
-            tmpString = new MJsonString("\"\"");
-            tmpString.setValue(this.getWidgetId());
-            tmpMessage.setValue("widgetId", tmpString);
-            //
-            tmpString = new MJsonString("\"\"");
-            tmpString.setValue(this.getEvent());
-            tmpMessage.setValue("event", tmpString);
-            //
-            MJsonObject tmpMessageParameters = new MJsonObject("{}");
-            for (String parameterKey: this.getParametersReference().keySet()) {
-                tmpString = new MJsonString("\"\"");
-                tmpString.setValue(this.getParameters().get(parameterKey));
-                tmpMessageParameters.setValue(parameterKey, tmpString);
-            }
-            tmpMessage.setValue("parameters", tmpMessageParameters);
-            //
-            return new MWebMessage(tmpMessage.getFormattedValue());
-        }
-        catch (MInvalidValueJsonException exception) { // cannot happen
-            return null; // necessary to avoid Java compilation errors
-        }
-        catch (MMessagingWebException exception) { // cannot happen
-            return null; // necessary to avoid Java compilation errors
-        }
-    }
-
-    /* Components */
-
-    public String getWidgetId() {
-        return this.widgetId;
-    }
-
-    public String getEvent() {
-        return this.event;
-    }
-
-    protected LinkedHashMap<String, String> getParametersReference() {
-        return this.parameters;
-    }
-
-    public LinkedHashMap<String, String> getParameters() {
-        LinkedHashMap<String, String> tmpParameters = new LinkedHashMap<String, String>();
-        for (String key: this.getParametersReference().keySet()) {
-            tmpParameters.put(key, this.getParametersReference().get(key));
-        }
-        return tmpParameters;
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebNumberBox.java b/src/java/com/marcozanon/macaco/webui/MWebNumberBox.java
deleted file mode 100644 (file)
index f7e4b3c..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.filtering.MConstraintFilteringException;
-import com.marcozanon.macaco.filtering.MFormatFilteringException;
-import com.marcozanon.macaco.filtering.MNumberFilter;
-
-public class MWebNumberBox extends MWebTextBox {
-
-    protected MNumberFilter numberFilter = null;
-
-    /* */
-
-    public MWebNumberBox(MWebApplicationContext applicationContext, MNumberFilter numberFilter) {
-        super(applicationContext);
-        //
-        if (null == numberFilter) {
-            throw new IllegalArgumentException("Invalid 'numberFilter': null.");
-        }
-        //
-        this.numberFilter = numberFilter;
-    }
-
-    public MWebNumberBox(MWebApplicationContext applicationContext, MNumberFilter numberFilter, String text) {
-        this(applicationContext, numberFilter);
-        //
-        this.setText(text);
-    }
-
-    /* Number filter */
-
-    protected MNumberFilter getNumberFilterReference() {
-        return this.numberFilter;
-    }
-
-    public MNumberFilter getNumberFilter() {
-        return this.getNumberFilterReference().clone();
-    }
-
-    /* Validation */
-
-    public void validate() throws MValidationWebException {
-        String text = this.getText();
-        try {
-            this.setText(this.getNumberFilterReference().getValidatedUserNumber(text, null));
-        }
-        catch (MConstraintFilteringException exception) {
-            throw new MValidationWebException(String.format("Invalid number: %s.", text), exception);
-        }
-        catch (MFormatFilteringException exception) {
-            throw new MValidationWebException(String.format("Invalid number: %s.", text), exception);
-        }
-    }
-
-    /* Refresh */
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        String onBlurFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onBlur', {'text': this.value});", this.getId());
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<input type=\"text\" class=\"MWebNumberBox %s\" style=\"display: inline-block;\" onblur=\"%s\" id=\"%s\" />'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onBlurFunction), this.getId()));
-        //
-        super.refresh();
-        //
-        this.refreshText();
-        this.refreshTextAlignment(true);
-        this.refreshEnabledMode();
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebPasswordBox.java b/src/java/com/marcozanon/macaco/webui/MWebPasswordBox.java
deleted file mode 100644 (file)
index 4f151da..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MWebPasswordBox extends MWebTextBox {
-
-    /* */
-
-    public MWebPasswordBox(MWebApplicationContext applicationContext) {
-        super(applicationContext);
-    }
-
-    public MWebPasswordBox(MWebApplicationContext applicationContext, String text) {
-        this(applicationContext);
-        //
-        this.setText(text);
-    }
-
-    /* Refresh */
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        String onBlurFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onBlur', {'text': this.value});", this.getId());
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<input type=\"password\" class=\"MWebPasswordBox %s\" style=\"display: inline-block;\" onblur=\"%s\" id=\"%s\" />'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onBlurFunction), this.getId()));
-        //
-        super.refresh();
-        //
-        this.refreshText();
-        this.refreshTextAlignment(true);
-        this.refreshEnabledMode();
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebRuntimeException.java b/src/java/com/marcozanon/macaco/webui/MWebRuntimeException.java
deleted file mode 100644 (file)
index dbf5e23..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.MRuntimeException;
-
-public abstract class MWebRuntimeException extends MRuntimeException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MWebRuntimeException() {
-        super();
-    }
-
-    public MWebRuntimeException(String message) {
-        super(message);
-    }
-
-    public MWebRuntimeException(Throwable error) {
-        super(error);
-    }
-
-    public MWebRuntimeException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebSimpleTextBox.java b/src/java/com/marcozanon/macaco/webui/MWebSimpleTextBox.java
deleted file mode 100644 (file)
index 64cb747..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MWebSimpleTextBox extends MWebTextBox {
-
-    /* */
-
-    public MWebSimpleTextBox(MWebApplicationContext applicationContext) {
-        super(applicationContext);
-    }
-
-    public MWebSimpleTextBox(MWebApplicationContext applicationContext, String text) {
-        this(applicationContext);
-        //
-        this.setText(text);
-    }
-
-    /* Refresh */
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        String onBlurFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onBlur', {'text': this.value});", this.getId());
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<input type=\"text\" class=\"MWebSimpleTextBox %s\" style=\"display: inline-block;\" onblur=\"%s\" id=\"%s\" />'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onBlurFunction), this.getId()));
-        //
-        super.refresh();
-        //
-        this.refreshText();
-        this.refreshTextAlignment(true);
-        this.refreshEnabledMode();
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebString.java b/src/java/com/marcozanon/macaco/webui/MWebString.java
deleted file mode 100644 (file)
index edc1fdb..0000000
+++ /dev/null
@@ -1,421 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.MInformation;
-import com.marcozanon.macaco.MObject;
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-import org.xml.sax.Attributes;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.DefaultHandler;
-
-public class MWebString extends MObject {
-
-    /* */
-
-    public MWebString() {
-        super();
-    }
-
-    /* Javascript escape */
-
-    public static String getJavascriptEscapedString(String x) {
-        if (null == x) {
-            return null;
-        }
-        //
-        String text = x;
-        //
-        text = text.replace("\\", "\\\\");
-        text = text.replace("'", "\\\'");
-        //
-        return text;
-    }
-
-    /* Xhtml escape and safety */
-
-    public static String getXhtmlEscapedString(String x) { // similar to PHP's htmlspecialchars()
-        if (null == x) {
-            return null;
-        }
-        //
-        String text = x;
-        //
-        text = text.replace("&", "&amp;");
-        text = text.replace("\"", "&quot;");
-        text = text.replace("'", "&apos;");
-        text = text.replace("<", "&lt;");
-        text = text.replace(">", "&gt;");
-        //
-        text = text.replace("\n", "<br />");
-        //
-        return text;
-    }
-
-    public static String getXhtmlNumericEntitiesString(String x) { // for compatibility with innerHTML
-        if (null == x) {
-            return null;
-        }
-        //
-        String text = x;
-        //
-        text = text.replace("&nbsp;", "&#160;");
-        text = text.replace("&iexcl;", "&#161;");
-        text = text.replace("&cent;", "&#162;");
-        text = text.replace("&pound;", "&#163;");
-        text = text.replace("&curren;", "&#164;");
-        text = text.replace("&yen;", "&#165;");
-        text = text.replace("&brvbar;", "&#166;");
-        text = text.replace("&sect;", "&#167;");
-        text = text.replace("&uml;", "&#168;");
-        text = text.replace("&copy;", "&#169;");
-        text = text.replace("&ordf;", "&#170;");
-        text = text.replace("&laquo;", "&#171;");
-        text = text.replace("&not;", "&#172;");
-        text = text.replace("&shy;", "&#173;");
-        text = text.replace("&reg;", "&#174;");
-        text = text.replace("&macr;", "&#175;");
-        text = text.replace("&deg;", "&#176;");
-        text = text.replace("&plusmn;", "&#177;");
-        text = text.replace("&sup2;", "&#178;");
-        text = text.replace("&sup3;", "&#179;");
-        text = text.replace("&acute;", "&#180;");
-        text = text.replace("&micro;", "&#181;");
-        text = text.replace("&para;", "&#182;");
-        text = text.replace("&middot;", "&#183;");
-        text = text.replace("&cedil;", "&#184;");
-        text = text.replace("&sup1;", "&#185;");
-        text = text.replace("&ordm;", "&#186;");
-        text = text.replace("&raquo;", "&#187;");
-        text = text.replace("&frac14;", "&#188;");
-        text = text.replace("&frac12;", "&#189;");
-        text = text.replace("&frac34;", "&#190;");
-        text = text.replace("&iquest;", "&#191;");
-        text = text.replace("&Agrave;", "&#192;");
-        text = text.replace("&Aacute;", "&#193;");
-        text = text.replace("&Acirc;", "&#194;");
-        text = text.replace("&Atilde;", "&#195;");
-        text = text.replace("&Auml;", "&#196;");
-        text = text.replace("&Aring;", "&#197;");
-        text = text.replace("&AElig;", "&#198;");
-        text = text.replace("&Ccedil;", "&#199;");
-        text = text.replace("&Egrave;", "&#200;");
-        text = text.replace("&Eacute;", "&#201;");
-        text = text.replace("&Ecirc;", "&#202;");
-        text = text.replace("&Euml;", "&#203;");
-        text = text.replace("&Igrave;", "&#204;");
-        text = text.replace("&Iacute;", "&#205;");
-        text = text.replace("&Icirc;", "&#206;");
-        text = text.replace("&Iuml;", "&#207;");
-        text = text.replace("&ETH;", "&#208;");
-        text = text.replace("&Ntilde;", "&#209;");
-        text = text.replace("&Ograve;", "&#210;");
-        text = text.replace("&Oacute;", "&#211;");
-        text = text.replace("&Ocirc;", "&#212;");
-        text = text.replace("&Otilde;", "&#213;");
-        text = text.replace("&Ouml;", "&#214;");
-        text = text.replace("&times;", "&#215;");
-        text = text.replace("&Oslash;", "&#216;");
-        text = text.replace("&Ugrave;", "&#217;");
-        text = text.replace("&Uacute;", "&#218;");
-        text = text.replace("&Ucirc;", "&#219;");
-        text = text.replace("&Uuml;", "&#220;");
-        text = text.replace("&Yacute;", "&#221;");
-        text = text.replace("&THORN;", "&#222;");
-        text = text.replace("&szlig;", "&#223;");
-        text = text.replace("&agrave;", "&#224;");
-        text = text.replace("&aacute;", "&#225;");
-        text = text.replace("&acirc;", "&#226;");
-        text = text.replace("&atilde;", "&#227;");
-        text = text.replace("&auml;", "&#228;");
-        text = text.replace("&aring;", "&#229;");
-        text = text.replace("&aelig;", "&#230;");
-        text = text.replace("&ccedil;", "&#231;");
-        text = text.replace("&egrave;", "&#232;");
-        text = text.replace("&eacute;", "&#233;");
-        text = text.replace("&ecirc;", "&#234;");
-        text = text.replace("&euml;", "&#235;");
-        text = text.replace("&igrave;", "&#236;");
-        text = text.replace("&iacute;", "&#237;");
-        text = text.replace("&icirc;", "&#238;");
-        text = text.replace("&iuml;", "&#239;");
-        text = text.replace("&eth;", "&#240;");
-        text = text.replace("&ntilde;", "&#241;");
-        text = text.replace("&ograve;", "&#242;");
-        text = text.replace("&oacute;", "&#243;");
-        text = text.replace("&ocirc;", "&#244;");
-        text = text.replace("&otilde;", "&#245;");
-        text = text.replace("&ouml;", "&#246;");
-        text = text.replace("&divide;", "&#247;");
-        text = text.replace("&oslash;", "&#248;");
-        text = text.replace("&ugrave;", "&#249;");
-        text = text.replace("&uacute;", "&#250;");
-        text = text.replace("&ucirc;", "&#251;");
-        text = text.replace("&uuml;", "&#252;");
-        text = text.replace("&yacute;", "&#253;");
-        text = text.replace("&thorn;", "&#254;");
-        text = text.replace("&yuml;", "&#255;");
-        text = text.replace("&OElig;", "&#338;");
-        text = text.replace("&oelig;", "&#339;");
-        text = text.replace("&Scaron;", "&#352;");
-        text = text.replace("&scaron;", "&#353;");
-        text = text.replace("&Yuml;", "&#376;");
-        text = text.replace("&fnof;", "&#402;");
-        text = text.replace("&circ;", "&#710;");
-        text = text.replace("&tilde;", "&#732;");
-        text = text.replace("&Alpha;", "&#913;");
-        text = text.replace("&Beta;", "&#914;");
-        text = text.replace("&Gamma;", "&#915;");
-        text = text.replace("&Delta;", "&#916;");
-        text = text.replace("&Epsilon;", "&#917;");
-        text = text.replace("&Zeta;", "&#918;");
-        text = text.replace("&Eta;", "&#919;");
-        text = text.replace("&Theta;", "&#920;");
-        text = text.replace("&Iota;", "&#921;");
-        text = text.replace("&Kappa;", "&#922;");
-        text = text.replace("&Lambda;", "&#923;");
-        text = text.replace("&Mu;", "&#924;");
-        text = text.replace("&Nu;", "&#925;");
-        text = text.replace("&Xi;", "&#926;");
-        text = text.replace("&Omicron;", "&#927;");
-        text = text.replace("&Pi;", "&#928;");
-        text = text.replace("&Rho;", "&#929;");
-        text = text.replace("&Sigma;", "&#931;");
-        text = text.replace("&Tau;", "&#932;");
-        text = text.replace("&Upsilon;", "&#933;");
-        text = text.replace("&Phi;", "&#934;");
-        text = text.replace("&Chi;", "&#935;");
-        text = text.replace("&Psi;", "&#936;");
-        text = text.replace("&Omega;", "&#937;");
-        text = text.replace("&alpha;", "&#945;");
-        text = text.replace("&beta;", "&#946;");
-        text = text.replace("&gamma;", "&#947;");
-        text = text.replace("&delta;", "&#948;");
-        text = text.replace("&epsilon;", "&#949;");
-        text = text.replace("&zeta;", "&#950;");
-        text = text.replace("&eta;", "&#951;");
-        text = text.replace("&theta;", "&#952;");
-        text = text.replace("&iota;", "&#953;");
-        text = text.replace("&kappa;", "&#954;");
-        text = text.replace("&lambda;", "&#955;");
-        text = text.replace("&mu;", "&#956;");
-        text = text.replace("&nu;", "&#957;");
-        text = text.replace("&xi;", "&#958;");
-        text = text.replace("&omicron;", "&#959;");
-        text = text.replace("&pi;", "&#960;");
-        text = text.replace("&rho;", "&#961;");
-        text = text.replace("&sigmaf;", "&#962;");
-        text = text.replace("&sigma;", "&#963;");
-        text = text.replace("&tau;", "&#964;");
-        text = text.replace("&upsilon;", "&#965;");
-        text = text.replace("&phi;", "&#966;");
-        text = text.replace("&chi;", "&#967;");
-        text = text.replace("&psi;", "&#968;");
-        text = text.replace("&omega;", "&#969;");
-        text = text.replace("&thetasym;", "&#977;");
-        text = text.replace("&upsih;", "&#978;");
-        text = text.replace("&piv;", "&#982;");
-        text = text.replace("&ensp;", "&#8194;");
-        text = text.replace("&emsp;", "&#8195;");
-        text = text.replace("&thinsp;", "&#8201;");
-        text = text.replace("&zwnj;", "&#8204;");
-        text = text.replace("&zwj;", "&#8205;");
-        text = text.replace("&lrm;", "&#8206;");
-        text = text.replace("&rlm;", "&#8207;");
-        text = text.replace("&ndash;", "&#8211;");
-        text = text.replace("&mdash;", "&#8212;");
-        text = text.replace("&lsquo;", "&#8216;");
-        text = text.replace("&rsquo;", "&#8217;");
-        text = text.replace("&sbquo;", "&#8218;");
-        text = text.replace("&ldquo;", "&#8220;");
-        text = text.replace("&rdquo;", "&#8221;");
-        text = text.replace("&bdquo;", "&#8222;");
-        text = text.replace("&dagger;", "&#8224;");
-        text = text.replace("&Dagger;", "&#8225;");
-        text = text.replace("&bull;", "&#8226;");
-        text = text.replace("&hellip;", "&#8230;");
-        text = text.replace("&permil;", "&#8240;");
-        text = text.replace("&prime;", "&#8242;");
-        text = text.replace("&Prime;", "&#8243;");
-        text = text.replace("&lsaquo;", "&#8249;");
-        text = text.replace("&rsaquo;", "&#8250;");
-        text = text.replace("&oline;", "&#8254;");
-        text = text.replace("&frasl;", "&#8260;");
-        text = text.replace("&euro;", "&#8364;");
-        text = text.replace("&image;", "&#8465;");
-        text = text.replace("&weierp;", "&#8472;");
-        text = text.replace("&real;", "&#8476;");
-        text = text.replace("&trade;", "&#8482;");
-        text = text.replace("&alefsym;", "&#8501;");
-        text = text.replace("&larr;", "&#8592;");
-        text = text.replace("&uarr;", "&#8593;");
-        text = text.replace("&rarr;", "&#8594;");
-        text = text.replace("&darr;", "&#8595;");
-        text = text.replace("&harr;", "&#8596;");
-        text = text.replace("&crarr;", "&#8629;");
-        text = text.replace("&lArr;", "&#8656;");
-        text = text.replace("&uArr;", "&#8657;");
-        text = text.replace("&rArr;", "&#8658;");
-        text = text.replace("&dArr;", "&#8659;");
-        text = text.replace("&hArr;", "&#8660;");
-        text = text.replace("&forall;", "&#8704;");
-        text = text.replace("&part;", "&#8706;");
-        text = text.replace("&exist;", "&#8707;");
-        text = text.replace("&empty;", "&#8709;");
-        text = text.replace("&nabla;", "&#8711;");
-        text = text.replace("&isin;", "&#8712;");
-        text = text.replace("&notin;", "&#8713;");
-        text = text.replace("&ni;", "&#8715;");
-        text = text.replace("&prod;", "&#8719;");
-        text = text.replace("&sum;", "&#8721;");
-        text = text.replace("&minus;", "&#8722;");
-        text = text.replace("&lowast;", "&#8727;");
-        text = text.replace("&radic;", "&#8730;");
-        text = text.replace("&prop;", "&#8733;");
-        text = text.replace("&infin;", "&#8734;");
-        text = text.replace("&ang;", "&#8736;");
-        text = text.replace("&and;", "&#8743;");
-        text = text.replace("&or;", "&#8744;");
-        text = text.replace("&cap;", "&#8745;");
-        text = text.replace("&cup;", "&#8746;");
-        text = text.replace("&int;", "&#8747;");
-        text = text.replace("&there4;", "&#8756;");
-        text = text.replace("&sim;", "&#8764;");
-        text = text.replace("&cong;", "&#8773;");
-        text = text.replace("&asymp;", "&#8776;");
-        text = text.replace("&ne;", "&#8800;");
-        text = text.replace("&equiv;", "&#8801;");
-        text = text.replace("&le;", "&#8804;");
-        text = text.replace("&ge;", "&#8805;");
-        text = text.replace("&sub;", "&#8834;");
-        text = text.replace("&sup;", "&#8835;");
-        text = text.replace("&nsub;", "&#8836;");
-        text = text.replace("&sube;", "&#8838;");
-        text = text.replace("&supe;", "&#8839;");
-        text = text.replace("&oplus;", "&#8853;");
-        text = text.replace("&otimes;", "&#8855;");
-        text = text.replace("&perp;", "&#8869;");
-        text = text.replace("&sdot;", "&#8901;");
-        text = text.replace("&lceil;", "&#8968;");
-        text = text.replace("&rceil;", "&#8969;");
-        text = text.replace("&lfloor;", "&#8970;");
-        text = text.replace("&rfloor;", "&#8971;");
-        text = text.replace("&lang;", "&#9001;");
-        text = text.replace("&rang;", "&#9002;");
-        text = text.replace("&loz;", "&#9674;");
-        text = text.replace("&spades;", "&#9824;");
-        text = text.replace("&clubs;", "&#9827;");
-        text = text.replace("&hearts;", "&#9829;");
-        text = text.replace("&diams;", "&#9830;");
-        //
-        return text;
-    }
-
-    public static String getXhtmlSafeString(String x) throws MXhtmlUnsafeStringWebException {
-        if (null == x) {
-            return null;
-        }
-        //
-        String text = x;
-        //
-        StringBuilder fakeXhtmlPageContent = new StringBuilder("");
-        fakeXhtmlPageContent.append(String.format("<?xml version=\"1.0\" encoding=\"%s\" ?>", MInformation.TEXT_ENCODING));
-        fakeXhtmlPageContent.append("<!DOCTYPE html SYSTEM \"fake-dtd\" >");
-        fakeXhtmlPageContent.append("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
-        fakeXhtmlPageContent.append("<head><title /></head>");
-        fakeXhtmlPageContent.append(String.format("<body>%s</body>", text));
-        fakeXhtmlPageContent.append("</html>");
-        // validate Xhtml (without dangerous tags and event attributes)
-        try {
-            SAXParserFactory factory = SAXParserFactory.newInstance();
-            factory.setValidating(true);
-            factory.setNamespaceAware(true);
-            SAXParser parser = factory.newSAXParser();
-            XMLReader reader = parser.getXMLReader();
-            reader.setEntityResolver(new EntityResolver() {
-
-                public InputSource resolveEntity(String publicId, String systemId) {
-                    return new InputSource(new BufferedInputStream(this.getClass().getClassLoader().getResourceAsStream("dtd/xhtml1-transitional-macaco-edit.dtd")));
-                }
-
-            });
-            reader.setContentHandler(new DefaultHandler() {
-
-                public void startElement(String namespaceUri, String strippedName, String tagName, Attributes attributes) throws SAXException {
-                    if ("script".equalsIgnoreCase(tagName)) {
-                        throw new SAXException(String.format("Tag not allowed: %s.", tagName));
-                    }
-                    for (int a = 0; a < attributes.getLength(); a++) {
-                        if (attributes.getLocalName(a).toLowerCase().startsWith("on")) {
-                            throw new SAXException(String.format("Attribute not allowed: %s.", attributes.getLocalName(a)));
-                        }
-                    }
-                }
-
-            });
-            reader.setErrorHandler(new ErrorHandler() {
-
-                public void error(SAXParseException exception) throws SAXException {
-                    throw new SAXException(exception);
-                }
-
-                public void fatalError(SAXParseException exception) throws SAXException {
-                    throw new SAXException(exception);
-                }
-
-                public void warning(SAXParseException exception) throws SAXException {
-                    throw new SAXException(exception);
-                }
-
-            });
-            //
-            reader.parse(new InputSource(new ByteArrayInputStream(fakeXhtmlPageContent.toString().getBytes(MInformation.TEXT_ENCODING))));
-        }
-        catch (ParserConfigurationException exception) { // cannot happen
-        }
-        catch (SAXException exception) {
-            throw new MXhtmlUnsafeStringWebException("Invalid 'x': unsafe tags or attributes inside.", exception);
-        }
-        catch (UnsupportedEncodingException exception) { // cannot happen
-        }
-        catch (IOException exception) { // cannot happen, put here not to bypass UnsupportedEncodingException
-        }
-        // also convert named entities to numeric entities
-        return MWebString.getXhtmlNumericEntitiesString(text);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebTable.java b/src/java/com/marcozanon/macaco/webui/MWebTable.java
deleted file mode 100644 (file)
index 2d24040..0000000
+++ /dev/null
@@ -1,755 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-
-public abstract class MWebTable extends MWebDirectWidget {
-
-    protected LinkedHashMap<String, MWebTableCell> columnHeaders = null;
-
-    protected String primaryKey = null;
-
-    protected String sortKey = null;
-    protected boolean ascendingSortMode = true;
-
-    protected int rowsPerPage = 10;
-    protected Integer selectedPage = null;
-
-    protected int rowCount = 0;
-    protected LinkedHashMap<String, LinkedHashMap<String, MWebTableCell>> rowSubset = new LinkedHashMap<String, LinkedHashMap<String, MWebTableCell>>();
-
-    protected boolean selectableRowMode = false;
-    protected LinkedHashSet<String> selectedRowKeys = new LinkedHashSet<String>();
-
-    /* */
-
-    public MWebTable(MWebApplicationContext applicationContext, LinkedHashMap<String, MWebTableCell> columnHeaders, String primaryKey) {
-        super(applicationContext);
-        //
-        if (null == columnHeaders) {
-            throw new IllegalArgumentException("Invalid 'columnHeaders': null.");
-        }
-        else {
-            for (String columnKey: columnHeaders.keySet()) {
-                if ((null == columnKey) || ("".equals(columnKey))) {
-                    throw new IllegalArgumentException("Invalid 'columnHeaders': column key null or empty.");
-                }
-                else if (null == columnHeaders.get(columnKey)) {
-                    throw new IllegalArgumentException("Invalid 'columnHeaders': table cell null.");
-                }
-            }
-        }
-        if ((null == primaryKey) || ("".equals(primaryKey))) {
-            throw new IllegalArgumentException("Invalid 'primaryKey': null or empty.");
-        }
-        //
-        this.columnHeaders = columnHeaders;
-        this.primaryKey = primaryKey;
-    }
-
-    /* Column headers */
-
-    protected LinkedHashMap<String, MWebTableCell> getColumnHeadersReference() {
-        return this.columnHeaders;
-    }
-
-    public LinkedHashMap<String, MWebTableCell> getColumnHeaders() {
-        LinkedHashMap<String, MWebTableCell> tmpColumnHeaders = new LinkedHashMap<String, MWebTableCell>();
-        for (String key: this.getColumnHeadersReference().keySet()) {
-            tmpColumnHeaders.put(key, this.getColumnHeadersReference().get(key).clone());
-        }
-        return tmpColumnHeaders;
-    }
-
-    public LinkedHashSet<String> getColumnHeaderKeys() {
-        LinkedHashSet<String> tmpColumnHeaderKeys = new LinkedHashSet<String>();
-        Iterator i = this.getColumnHeadersReference().keySet().iterator();
-        while (i.hasNext()) {
-            tmpColumnHeaderKeys.add((String)i.next());
-        }
-        return tmpColumnHeaderKeys;
-    }
-
-    /* Primary key */
-
-    public String getPrimaryKey() {
-        return this.primaryKey;
-    }
-
-    /* Sorting */
-
-    public void setSortKey(String sortKey, boolean ascendingSortMode) {
-        this.setSortKey(sortKey, ascendingSortMode, true);
-    }
-
-    protected void setSortKey(String sortKey, boolean ascendingSortMode, boolean refreshMode) {
-        if ("".equals(sortKey)) {
-            throw new IllegalArgumentException("Invalid 'sortKey': empty.");
-        }
-        //
-        if (null == sortKey) {
-            this.sortKey = null;
-            this.ascendingSortMode = true;
-        }
-        else {
-            this.sortKey = sortKey;
-            this.ascendingSortMode = ascendingSortMode;
-        }
-        //
-        if (refreshMode) {
-            try {
-                this.refresh(); // must refresh everything
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-            catch (MUniqueWidgetIdNotAvailableWebException exception) {
-            }
-        }
-    }
-
-    public String getSortKey() {
-        return this.sortKey;
-    }
-
-    public boolean getAscendingSortMode() {
-        return this.ascendingSortMode;
-    }
-
-    /* Page selection */
-
-    public void setRowsPerPage(int rowsPerPage) {
-        this.setRowsPerPage(rowsPerPage, true);
-    }
-
-    protected void setRowsPerPage(int rowsPerPage, boolean refreshMode) {
-        if (rowsPerPage < 1) {
-            throw new IllegalArgumentException(String.format("Invalid 'rowsPerPage': %s: must be positive.", rowsPerPage));
-        }
-        //
-        this.rowsPerPage = rowsPerPage;
-        //
-        if (refreshMode) {
-            try {
-                this.refresh(); // must refresh everything
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-            catch (MUniqueWidgetIdNotAvailableWebException exception) {
-            }
-        }
-    }
-
-    public int getRowsPerPage() {
-        return this.rowsPerPage;
-    }
-
-    public void setSelectedPage(Integer selectedPage) {
-        this.setSelectedPage(selectedPage, true);
-    }
-
-    protected void setSelectedPage(Integer selectedPage, boolean refreshMode) {
-        if ((0 == this.getRowCount()) && (null != selectedPage)) {
-            this.selectedPage = 1;
-            return;
-        }
-        else if ((null != selectedPage) && ((selectedPage < 1) || (selectedPage > (int)Math.ceil((float)this.getRowCount() / (float)this.getRowsPerPage())))) {
-            throw new IllegalArgumentException(String.format("Invalid 'selectedPage': %s: out of range.", selectedPage));
-        }
-        //
-        this.clearSelectedRowKeys();
-        //
-        this.selectedPage = selectedPage;
-        //
-        if (refreshMode) {
-            try {
-                this.refresh(); // must refresh everything
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-            catch (MUniqueWidgetIdNotAvailableWebException exception) {
-            }
-        }
-    }
-
-    public Integer getSelectedPage() {
-        return this.selectedPage;
-    }
-
-    protected void resetSelectedPage() {
-        Integer selectedPage = this.getSelectedPage();
-        if (null == selectedPage) {
-            return;
-        }
-        else if (0 == this.getRowCount()) {
-            this.setSelectedPage(null);
-        }
-        else if (selectedPage < 1) {
-            this.setSelectedPage(1);
-        }
-        else if (selectedPage > (int)Math.ceil((float)this.getRowCount() / (float)this.getRowsPerPage())) {
-            this.setSelectedPage((int)Math.ceil((float)this.getRowCount() / (float)this.getRowsPerPage()));
-        }
-    }
-
-    /* Rows */
-
-    public void loadRows(LinkedList<LinkedHashMap<String, String>> rows) throws MUniqueWidgetIdNotAvailableWebException {
-        this.loadRows(rows, true);
-    }
-
-    protected void loadRows(LinkedList<LinkedHashMap<String, String>> rows, boolean refreshMode) throws MUniqueWidgetIdNotAvailableWebException {
-        if (null == rows) {
-            throw new IllegalArgumentException("Invalid 'rows': null.");
-        }
-        else {
-            for (LinkedHashMap<String, String> row: rows) {
-                if (null == row) {
-                    throw new IllegalArgumentException("Invalid 'rows': row null.");
-                }
-                for (String columnKey: row.keySet()) {
-                    if ((null == columnKey) || ("".equals(columnKey))) {
-                        throw new IllegalArgumentException("Invalid 'rows': column key null or empty.");
-                    }
-                }
-            }
-        }
-        //
-        this.rowCount = rows.size();
-        this.resetSelectedPage();
-        //
-        int firstRow = 0;
-        int lastRow = this.getRowCount() - 1;
-        Integer selectedPage = this.getSelectedPage();
-        if (null != selectedPage) {
-            firstRow = (selectedPage - 1) * this.getRowsPerPage();
-            lastRow = Math.min((selectedPage * this.getRowsPerPage()) - 1, lastRow);
-        }
-        LinkedList<LinkedHashMap<String, String>> tmpRowSubset = new LinkedList<LinkedHashMap<String, String>>();
-        for (int r = firstRow; r < (lastRow + 1); r++) {
-            tmpRowSubset.add(rows.get(r));
-        }
-        LinkedHashMap<String, MWebTableCell> columnHeaders = this.getColumnHeadersReference();
-        LinkedHashMap<String, LinkedHashMap<String, MWebTableCell>> rowSubset = new LinkedHashMap<String, LinkedHashMap<String, MWebTableCell>>();
-        for (LinkedHashMap<String, String> tmpRow: tmpRowSubset) {
-            String primaryKeyValue = tmpRow.get(this.getPrimaryKey());
-            if (null == primaryKeyValue) {
-                throw new IllegalArgumentException("Invalid row: primary key value null.");
-            }
-            LinkedHashMap<String, MWebTableCell> row = new LinkedHashMap<String, MWebTableCell>();
-            for (String columnKey: columnHeaders.keySet()) {
-                String text = null;
-                if (null == tmpRow.get(columnKey)) {
-                    text = "";
-                }
-                else {
-                    text = tmpRow.get(columnKey);
-                }
-                row.put(columnKey, new MWebTableCell(this.getApplicationContextReference(), text, null, null));
-            }
-            rowSubset.put(primaryKeyValue, row);
-        }
-        //
-        for (LinkedHashMap<String, MWebTableCell> row: this.getRowSubsetReference().values()) {
-            for (MWebTableCell rowCell: row.values()) {
-                try {
-                    rowCell.setView(null);
-                }
-                catch (MUniqueWidgetIdNotAvailableWebException exception) { // cannot happen
-                }
-            }
-        }
-        //
-        this.rowSubset = rowSubset;
-        //
-        for (LinkedHashMap<String, MWebTableCell> row: this.getRowSubsetReference().values()) {
-            for (MWebTableCell rowCell: row.values()) {
-                try {
-                    rowCell.setView(this.getViewReference());
-                }
-                catch (MNoViewWebException exception) {
-                }
-            }
-        }
-        //
-        if (refreshMode) {
-            try {
-                this.refresh(); // must refresh everything
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public int getRowCount() {
-        return this.rowCount;
-    }
-
-    protected LinkedHashMap<String, LinkedHashMap<String, MWebTableCell>> getRowSubsetReference() {
-        return this.rowSubset;
-    }
-
-    public LinkedHashMap<String, LinkedHashMap<String, MWebTableCell>> getRowSubset() {
-        LinkedHashMap<String, LinkedHashMap<String, MWebTableCell>> tmpRowSubset = new LinkedHashMap<String, LinkedHashMap<String, MWebTableCell>>();
-        for (String rowKey: this.getRowSubsetReference().keySet()) {
-            LinkedHashMap<String, MWebTableCell> tmpRow = new LinkedHashMap<String, MWebTableCell>();
-            for (String columnKey: this.getRowSubsetReference().get(rowKey).keySet()) {
-                tmpRow.put(columnKey, this.getRowSubsetReference().get(rowKey).get(columnKey).clone());
-            }
-            tmpRowSubset.put(rowKey, tmpRow);
-        }
-        return tmpRowSubset;
-    }
-
-    public LinkedHashSet<String> getRowSubsetKeys() {
-        LinkedHashSet<String> tmpRowSubsetKeys = new LinkedHashSet<String>();
-        Iterator i = this.getRowSubsetReference().keySet().iterator();
-        while (i.hasNext()) {
-            tmpRowSubsetKeys.add((String)i.next());
-        }
-        return tmpRowSubsetKeys;
-    }
-
-    /* Row selection */
-
-    public void setSelectableRowMode(boolean selectableRowMode) {
-        this.setSelectableRowMode(selectableRowMode, true);
-    }
-
-    protected void setSelectableRowMode(boolean selectableRowMode, boolean refreshMode) {
-        if (!selectableRowMode) {
-            this.clearSelectedRowKeys();
-        }
-        this.selectableRowMode = selectableRowMode;
-        //
-        if (refreshMode) {
-            try {
-                this.refresh(); // must refresh everything
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-            catch (MUniqueWidgetIdNotAvailableWebException exception) {
-            }
-        }
-    }
-
-    public boolean getSelectableRowMode() {
-        return this.selectableRowMode;
-    }
-
-    protected LinkedHashSet<String> getSelectedRowKeysReference() {
-        return this.selectedRowKeys;
-    }
-
-    public LinkedHashSet<String> getSelectedRowKeys() {
-        LinkedHashSet<String> tmpSelectedRowKeys = new LinkedHashSet<String>();
-        Iterator i = this.getSelectedRowKeysReference().iterator();
-        while (i.hasNext()) {
-            tmpSelectedRowKeys.add((String)i.next());
-        }
-        return tmpSelectedRowKeys;
-    }
-
-    protected void clearSelectedRowKeys() {
-        this.getSelectedRowKeysReference().clear();
-    }
-
-    public void setRowSelectedMode(String primaryKeyValue, boolean selectedMode) {
-        this.setRowSelectedMode(primaryKeyValue, selectedMode, true);
-    }
-
-    protected void setRowSelectedMode(String primaryKeyValue, boolean selectedMode, boolean refreshMode) {
-        if ((null == primaryKeyValue) || ("".equals(primaryKeyValue))) {
-            throw new IllegalArgumentException("Invalid 'primaryKeyValue': null or empty.");
-        }
-        //
-        if (selectedMode) {
-            this.getSelectedRowKeysReference().add(primaryKeyValue);
-        }
-        else {
-            this.getSelectedRowKeysReference().remove(primaryKeyValue);
-        }
-        //
-        if (refreshMode) {
-            try {
-                this.refresh(); // must refresh everything
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-            catch (MUniqueWidgetIdNotAvailableWebException exception) {
-            }
-        }
-    }
-
-    public boolean getRowSelectedMode(String primaryKeyValue) {
-        if ((null == primaryKeyValue) || ("".equals(primaryKeyValue))) {
-            throw new IllegalArgumentException("Invalid 'primaryKeyValue': null or empty.");
-        }
-        //
-        return this.getSelectedRowKeys().contains(primaryKeyValue);
-    }
-
-    public boolean getRowSubsetSelectedMode() {
-        return this.getSelectedRowKeysReference().size() == this.getRowSubsetReference().size();
-    }
-
-    public void toggleRowSubsetSelectedMode() {
-        this.toggleRowSubsetSelectedMode(true);
-    }
-
-    protected void toggleRowSubsetSelectedMode(boolean refreshMode) {
-        if (this.getRowSubsetSelectedMode()) {
-            this.clearSelectedRowKeys();
-        }
-        else {
-            this.clearSelectedRowKeys();
-            for (String primaryKeyValue: this.getRowSubsetReference().keySet()) {
-                this.setRowSelectedMode(primaryKeyValue, true, false);
-            }
-        }
-        //
-        if (refreshMode) {
-            try {
-                this.refresh(); // must refresh everything
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-            catch (MUniqueWidgetIdNotAvailableWebException exception) {
-            }
-        }
-    }
-
-    /* View */
-
-    protected void setView(MWebView view) throws MUniqueWidgetIdNotAvailableWebException {
-        super.setView(view);
-        //
-        for (MWebTableCell cell: this.getColumnHeadersReference().values()) {
-            cell.setView(view);
-        }
-        //
-        for (LinkedHashMap<String, MWebTableCell> row: this.getRowSubsetReference().values()) {
-            for (MWebTableCell rowCell: row.values()) {
-                rowCell.setView(view);
-            }
-        }
-    }
-
-    /* Display widgets */
-
-    protected MWebDisplayWidget getDisplayWidgetReferenceById(String id) throws MDisplayWidgetNotFoundWebException {
-        try {
-            return super.getDisplayWidgetReferenceById(id);
-        }
-        catch (MDisplayWidgetNotFoundWebException exception) {
-            for (MWebTableCell columnHeadersCell: this.getColumnHeadersReference().values()) {
-                try {
-                    return columnHeadersCell.getDisplayWidgetReferenceById(id);
-                }
-                catch (MDisplayWidgetNotFoundWebException exception2) {
-                }
-            }
-            for (LinkedHashMap<String, MWebTableCell> row: this.getRowSubsetReference().values()) {
-                for (MWebTableCell rowCell: row.values()) {
-                    try {
-                        return rowCell.getDisplayWidgetReferenceById(id);
-                    }
-                    catch (MDisplayWidgetNotFoundWebException exception2) {
-                    }
-                }
-            }
-            throw new MDisplayWidgetNotFoundWebException(String.format("Invalid 'id': %s: display widget not available on this path.", id)); // no need to propagate exception
-        }
-    }
-
-    /* Refresh */
-
-    protected void customizeRowSubset() {
-    }
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        StringBuilder content = new StringBuilder("");
-        LinkedHashMap<String, MWebTableCell> columnHeaders = this.getColumnHeadersReference();
-        Integer selectedPage = this.getSelectedPage();
-        LinkedHashMap<String, LinkedHashMap<String, MWebTableCell>> rowSubset = this.getRowSubsetReference();
-        content.append(String.format("<table class=\"MWebTable %s\" style=\"display: inline-table;\" id=\"%s\">", customClasses, this.getId()));
-        //
-        content.append(String.format("<tr class=\"MWebTableColumnHeaderRow %s\">", customClasses));
-        if (this.getSelectableRowMode()) {
-            String onRowSubsetSelectedModeToggleFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onRowSubsetSelectedModeToggle', {});", this.getId());
-            content.append(String.format("<th class=\"MWebTableColumnHeaderRowSelectionCell %s\"><input type=\"checkbox\" class=\"MWebTableColumnHeaderRowSelector %s\" onclick=\"%s\" /></th>", customClasses, customClasses, onRowSubsetSelectedModeToggleFunction));
-        }
-        for (String columnKey: columnHeaders.keySet()) {
-            String onSortFunction = "";
-            if (!"".equals(columnHeaders.get(columnKey).getText())) {
-                onSortFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onSort', {'sortKey': '%s'});", this.getId(), MWebString.getJavascriptEscapedString(columnKey));
-            }
-            content.append(String.format("<th class=\"MWebTableColumnHeaderCell %s\" onclick=\"%s\" id=\"%s\"></th>", customClasses, MWebString.getXhtmlEscapedString(onSortFunction), columnHeaders.get(columnKey).getId()));
-        }
-        content.append("</tr>");
-        //
-        for (String primaryKeyValue: rowSubset.keySet()) {
-            content.append(String.format("<tr class=\"MWebTableRow %s\">", customClasses));
-            if (this.getSelectableRowMode()) {
-                String onRowSelectedModeToggleFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onRowSelectedModeToggle', {'primaryKeyValue': '%s'});", this.getId(), MWebString.getJavascriptEscapedString(primaryKeyValue));
-                String checkedMode = "";
-                if (this.getRowSelectedMode(primaryKeyValue)) {
-                    checkedMode = "checked=\"checked\"";
-                }
-                content.append(String.format("<th class=\"MWebTableRowSelectionCell %s\"><input type=\"checkbox\" class=\"MWebTableRowSelector %s\" onclick=\"%s\" %s /></th>", customClasses, customClasses, MWebString.getXhtmlEscapedString(onRowSelectedModeToggleFunction), checkedMode));
-            }
-            for (String columnKey: rowSubset.get(primaryKeyValue).keySet()) {
-                String onCellClickFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onCellClick', {'primaryKeyValue': '%s', 'columnKey': '%s'});", this.getId(), MWebString.getJavascriptEscapedString(primaryKeyValue), MWebString.getJavascriptEscapedString(columnKey));
-                content.append(String.format("<td class=\"MWebTableCell %s\" onclick=\"%s\" id=\"%s\"></td>", customClasses, MWebString.getXhtmlEscapedString(onCellClickFunction), rowSubset.get(primaryKeyValue).get(columnKey).getId()));
-            }
-            content.append("</tr>");
-        }
-        //
-        content.append(String.format("<tr class=\"MWebTablePageChangerRow %s\">", customClasses));
-        int columnSpan = columnHeaders.size();
-        if (this.getSelectableRowMode()) {
-            columnSpan++;
-        }
-        String onPageSelectionFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onPageSelection', {'selectedPage': this.value});", this.getId());
-        content.append(String.format("<td class=\"MWebTablePageChangerCell %s\" colspan=\"%s\"><select class=\"MWebTablePageChanger %s\" onchange=\"%s\">", customClasses, columnSpan, customClasses, onPageSelectionFunction));
-        String selectedMode = "";
-        if (null == selectedPage) {
-            selectedMode = "selected=\"selected\"";
-        }
-        content.append(String.format("<option value=\"\" %s>*</option>", selectedMode));
-        int rowCount = this.getRowCount();
-        int rowsPerPage = this.getRowsPerPage();
-        if (rowCount > 0) {
-            int p = 0;
-            int firstRow = 0;
-            int lastRow = 0;
-            for (p = 1; p <= (int)Math.ceil((float)rowCount / (float)rowsPerPage); p++) {
-                firstRow = (p - 1) * rowsPerPage;
-                lastRow = Math.min((p * rowsPerPage) - 1, rowCount - 1);
-                if ((null != selectedPage) && (selectedPage.intValue() == p)) {
-                    selectedMode = "selected=\"selected\"";
-                }
-                else {
-                    selectedMode = "";
-                }
-                content.append(String.format("<option value=\"%s\" %s>%s (%s - %s)</option>", p, selectedMode, p, (firstRow + 1), (lastRow + 1)));
-            }
-        }
-        content.append("</select></td>");
-        content.append("</tr>");
-        //
-        content.append("</table>");
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(content.toString())));
-        //
-        String sortKey = this.getSortKey();
-        for (String columnKey: columnHeaders.keySet()) {
-            MWebTableCell columnHeaderCell = columnHeaders.get(columnKey);
-            columnHeaderCell.onRefresh();
-            String sortIndicator = "";
-            if (columnKey.equals(sortKey)) {
-                if (true == this.getAscendingSortMode()) {
-                    sortIndicator = "+";
-                }
-                else {
-                    sortIndicator = "-";
-                }
-            }
-            else {
-                sortIndicator = "";
-            }
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '%s<br />' + $('%s').innerHTML; }", this.getId(), columnHeaderCell.getId(), sortIndicator, columnHeaderCell.getId()));
-        }
-        //
-        this.customizeRowSubset();
-        //
-        for (LinkedHashMap<String, MWebTableCell> row: rowSubset.values()) {
-            for (MWebTableCell rowCell: row.values()) {
-                rowCell.onRefresh();
-            }
-        }
-        //
-        super.refresh();
-    }
-
-    /* Messages */
-
-    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
-        super.processMessage(event, parameters);
-        //
-        if ("onCellClick".equals(event)) {
-            if (!this.getVisibleMode()) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
-            }
-            String primaryKeyValue = parameters.get("primaryKeyValue");
-            String columnKey = parameters.get("columnKey");
-            if (null == primaryKeyValue) {
-                throw new MUnexpectedMessageWebException("Invalid message: primary key value parameter not available.");
-            }
-            else if (!this.getRowSubsetKeys().contains(primaryKeyValue)) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: primary key value parameter not recognized.", primaryKeyValue));
-            }
-            if (null == columnKey) {
-                throw new MUnexpectedMessageWebException("Invalid message: column key parameter not available.");
-            }
-            else if (!this.getColumnHeaderKeys().contains(columnKey)) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: column key parameter not recognized.", columnKey));
-            }
-            this.onCellClick(primaryKeyValue, columnKey);
-        }
-        else if ("onPageSelection".equals(event)) {
-            if (!this.getVisibleMode()) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
-            }
-            String selectedPage = parameters.get("selectedPage");
-            if (null == selectedPage) {
-                throw new MUnexpectedMessageWebException("Invalid message: selected page parameter not available.");
-            }
-            else if ((!"".equals(selectedPage)) && ((Integer.parseInt(selectedPage) < 1) || (Integer.parseInt(selectedPage) > (int)Math.ceil((float)this.getRowCount() / (float)this.getRowsPerPage())))) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: selected page parameter out of range.", selectedPage));
-            }
-            this.onPageSelection(selectedPage);
-        }
-        else if ("onRefresh".equals(event)) {
-            this.onRefresh();
-        }
-        else if ("onRowSelectedModeToggle".equals(event)) {
-            if (!this.getVisibleMode()) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
-            }
-            String primaryKeyValue = parameters.get("primaryKeyValue");
-            if (null == primaryKeyValue) {
-                throw new MUnexpectedMessageWebException("Invalid message: primary key value parameter not available.");
-            }
-            else if (!this.getRowSubsetKeys().contains(primaryKeyValue)) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: primary key value parameter not recognized.", primaryKeyValue));
-            }
-            this.onRowSelectedModeToggle(primaryKeyValue);
-        }
-        else if ("onRowSubsetSelectedModeToggle".equals(event)) {
-            if (!this.getVisibleMode()) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
-            }
-            this.onRowSubsetSelectedModeToggle();
-        }
-        else if ("onSort".equals(event)) {
-            if (!this.getVisibleMode()) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
-            }
-            String sortKey = parameters.get("sortKey");
-            if (null == sortKey) {
-                throw new MUnexpectedMessageWebException("Invalid message: sort key parameter not available.");
-            }
-            else if (!this.getColumnHeaderKeys().contains(sortKey)) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: sort key parameter not recognized.", sortKey));
-            }
-            this.onSort(sortKey);
-        }
-        else {
-            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
-        }
-    }
-
-    public void onCellClick(String primaryKeyValue, String columnKey) {
-    }
-
-    public void onPageSelection(String selectedPage) {
-        if ("".equals(selectedPage)) {
-            this.setSelectedPage(null);
-        }
-        else {
-            this.setSelectedPage(new Integer(selectedPage));
-        }
-    }
-
-    public void onRowSelectedModeToggle(String primaryKeyValue) {
-        this.setRowSelectedMode(primaryKeyValue, !this.getRowSelectedMode(primaryKeyValue));
-    }
-
-    public void onRowSubsetSelectedModeToggle() {
-        this.toggleRowSubsetSelectedMode();
-    }
-
-    public void onSort(String sortKey) {
-        if (sortKey.equals(this.getSortKey())) {
-            this.setSortKey(sortKey, !this.getAscendingSortMode());
-        }
-        else {
-            this.setSortKey(sortKey, true);
-        }
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebTableCell.java b/src/java/com/marcozanon/macaco/webui/MWebTableCell.java
deleted file mode 100644 (file)
index 4fc5cb9..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import java.util.LinkedHashMap;
-
-public class MWebTableCell extends MWebCellWidget {
-
-    protected String text = "";
-    protected String imageSource = null;
-    protected String externalLinkPrefix = null;
-
-    /* */
-
-    public MWebTableCell(MWebApplicationContext applicationContext) {
-        super(applicationContext);
-    }
-
-    public MWebTableCell(MWebApplicationContext applicationContext, String text, String imageSource, String externalLinkPrefix) {
-        this(applicationContext);
-        //
-        this.setText(text);
-        this.setImageSource(imageSource);
-        this.setExternalLinkPrefix(externalLinkPrefix);
-    }
-
-    public MWebTableCell clone() {
-        MWebTableCell tableCell = new MWebTableCell(this.getApplicationContextReference(), this.getText(), this.getImageSource(), this.getExternalLinkPrefix());
-        this.cloneCellWidgetProperties(tableCell);
-        return tableCell;
-    }
-
-    /* Text */
-
-    public void setText(String text) {
-        this.setText(text, true);
-    }
-
-    protected void setText(String text, boolean refreshMode) {
-        if (null == text) {
-            throw new IllegalArgumentException("Invalid 'text': null.");
-        }
-        //
-        this.text = text;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshContent();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public String getText() {
-        return this.text;
-    }
-
-    /* Image source */
-
-    public void setImageSource(String imageSource) {
-        this.setImageSource(imageSource, true);
-    }
-
-    protected void setImageSource(String imageSource, boolean refreshMode) {
-        this.imageSource = imageSource;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshContent();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public String getImageSource() {
-        return this.imageSource;
-    }
-
-    /* External link prefix */
-
-    public void setExternalLinkPrefix(String externalLinkPrefix) {
-        this.setExternalLinkPrefix(externalLinkPrefix, true);
-    }
-
-    protected void setExternalLinkPrefix(String externalLinkPrefix, boolean refreshMode) {
-        if ("".equals(externalLinkPrefix)) {
-            throw new IllegalArgumentException("Invalid 'externalLinkPrefix': empty.");
-        }
-        //
-        this.externalLinkPrefix = externalLinkPrefix;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshContent();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public String getExternalLinkPrefix() {
-        return this.externalLinkPrefix;
-    }
-
-    /* Refresh */
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        this.refreshContent();
-        //
-        super.refresh();
-    }
-
-    protected void refreshContent() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        String content = null;
-        String text = this.getText();
-        String imageSource = this.getImageSource();
-        String externalLinkPrefix = this.getExternalLinkPrefix();
-        if (null == imageSource) {
-            content = MWebString.getXhtmlEscapedString(text);
-        }
-        else {
-            content = String.format("<img src=\"%s\" alt=\"%s\" />", MWebString.getXhtmlEscapedString(imageSource), MWebString.getXhtmlEscapedString(text));
-        }
-        if (null != externalLinkPrefix) {
-            content = String.format("<a href=\"%s\">%s</a>", MWebString.getXhtmlEscapedString(externalLinkPrefix + text), content);
-        }
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(content)));
-    }
-
-    /* Messages */
-
-    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
-        super.processMessage(event, parameters);
-        //
-        if ("onRefresh".equals(event)) {
-            this.onRefresh();
-        }
-        else {
-            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
-        }
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebTextBox.java b/src/java/com/marcozanon/macaco/webui/MWebTextBox.java
deleted file mode 100644 (file)
index 113505e..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import java.util.LinkedHashMap;
-
-public abstract class MWebTextBox extends MWebDirectWidget {
-
-    public static enum TextAlignment {
-        LEFT("left"),
-        CENTER("center"),
-        RIGHT("right");
-        private String name = null;
-        private TextAlignment(String name) {
-            this.name = name;
-        }
-        public String toString() {
-            return this.name;
-        }
-    };
-
-    protected String text = "";
-    protected MWebTextBox.TextAlignment textAlignment = null;
-
-    protected boolean enabledMode = true;
-
-    /* */
-
-    public MWebTextBox(MWebApplicationContext applicationContext) {
-        super(applicationContext);
-    }
-
-    /* Focus */
-
-    public void setFocus() {
-        try {
-            this.refreshFocus();
-        }
-        catch (MNoBrowserPageWebException exception) {
-        }
-        catch (MNoViewWebException exception) {
-        }
-        catch (MNoWidgetIdWebException exception) {
-        }
-        catch (MResponseWebException exception) {
-        }
-    }
-
-    /* Text */
-
-    public void setText(String text) {
-        this.setText(text, true);
-    }
-
-    protected void setText(String text, boolean refreshMode) {
-        if (null == text) {
-            throw new IllegalArgumentException("Invalid 'text': null.");
-        }
-        //
-        this.text = text;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshText();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public String getText() {
-        return this.text;
-    }
-
-    /* Text alignment */
-
-    public void setTextAlignment(MWebTextBox.TextAlignment textAlignment) {
-        this.setTextAlignment(textAlignment, true);
-    }
-
-    protected void setTextAlignment(MWebTextBox.TextAlignment textAlignment, boolean refreshMode) {
-        this.textAlignment = textAlignment;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshTextAlignment(false);
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public MWebTextBox.TextAlignment getTextAlignment() {
-        return this.textAlignment;
-    }
-
-    public String getFormattedTextAlignment() throws MNullPropertyWebException {
-        if (null == this.getTextAlignment()) {
-            throw new MNullPropertyWebException("Invalid text alignment: property null.");
-        }
-        return this.getTextAlignment().toString();
-    }
-
-    /* Enabled mode */
-
-    public void setEnabledMode(boolean enabledMode) {
-        this.setEnabledMode(enabledMode, true);
-    }
-
-    protected void setEnabledMode(boolean enabledMode, boolean refreshMode) {
-        this.enabledMode = enabledMode;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshEnabledMode();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public boolean getEnabledMode() {
-        return this.enabledMode;
-    }
-
-    /* Refresh */
-
-    protected void refreshFocus() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').focus(); }", this.getId(), this.getId()));
-    }
-
-    protected void refreshText() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').value = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(this.getText())));
-    }
-
-    protected void refreshTextAlignment(boolean directRefreshMode) throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        try {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textAlign = '%s'; }", this.getId(), this.getId(), this.getFormattedTextAlignment()));
-        }
-        catch (MNullPropertyWebException exception) {
-            if (!directRefreshMode) {
-                this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $S('%s').textAlign = null; }", this.getId(), this.getId()));
-            }
-        }
-    }
-
-    protected void refreshEnabledMode() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').disabled = %s; }", this.getId(), this.getId(), !this.getEnabledMode()));
-    }
-
-    /* Messages */
-
-    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
-        super.processMessage(event, parameters);
-        //
-        if ("onBlur".equals(event)) {
-            if ((!this.getVisibleMode()) || (!this.getEnabledMode())) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden or disabled.", event));
-            }
-            String text = parameters.get("text");
-            if (null == text) {
-                throw new MUnexpectedMessageWebException("Invalid message: text parameter not available.");
-            }
-            this.onBlur(text);
-        }
-        else if ("onRefresh".equals(event)) {
-            this.onRefresh();
-        }
-        else {
-            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
-        }
-    }
-
-    public void onBlur(String text) {
-        this.setText(text, false);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebTimeBox.java b/src/java/com/marcozanon/macaco/webui/MWebTimeBox.java
deleted file mode 100644 (file)
index 365b5c1..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.filtering.MConstraintFilteringException;
-import com.marcozanon.macaco.filtering.MFormatFilteringException;
-import com.marcozanon.macaco.filtering.MTimeFilter;
-
-public class MWebTimeBox extends MWebTextBox {
-
-    protected MTimeFilter timeFilter = null;
-
-    /* */
-
-    public MWebTimeBox(MWebApplicationContext applicationContext, MTimeFilter timeFilter) {
-        super(applicationContext);
-        //
-        if (null == timeFilter) {
-            throw new IllegalArgumentException("Invalid 'timeFilter': null.");
-        }
-        //
-        this.timeFilter = timeFilter;
-    }
-
-    public MWebTimeBox(MWebApplicationContext applicationContext, MTimeFilter timeFilter, String text) {
-        this(applicationContext, timeFilter);
-        //
-        this.setText(text);
-    }
-
-    /* Time filter */
-
-    protected MTimeFilter getTimeFilterReference() {
-        return this.timeFilter;
-    }
-
-    public MTimeFilter getTimeFilter() {
-        return this.getTimeFilterReference().clone();
-    }
-
-    /* Validation */
-
-    public void validate() throws MValidationWebException {
-        String text = this.getText();
-        try {
-            this.setText(this.getTimeFilterReference().getValidatedUserTime(text, null));
-        }
-        catch (MConstraintFilteringException exception) {
-            throw new MValidationWebException(String.format("Invalid time: %s.", text), exception);
-        }
-        catch (MFormatFilteringException exception) {
-            throw new MValidationWebException(String.format("Invalid time: %s.", text), exception);
-        }
-    }
-
-    /* Refresh */
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        String onBlurFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onBlur', {'text': this.value});", this.getId());
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<input type=\"text\" class=\"MWebTimeBox %s\" style=\"display: inline-block;\" onblur=\"%s\" id=\"%s\" />'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onBlurFunction), this.getId()));
-        //
-        super.refresh();
-        //
-        this.refreshText();
-        this.refreshTextAlignment(true);
-        this.refreshEnabledMode();
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebUploader.java b/src/java/com/marcozanon/macaco/webui/MWebUploader.java
deleted file mode 100644 (file)
index 60c6576..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.LinkedHashMap;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.Part;
-
-public class MWebUploader extends MWebDirectWidget {
-
-    protected boolean enabledMode = true;
-
-    /* */
-
-    public MWebUploader(MWebApplicationContext applicationContext) {
-        super(applicationContext);
-    }
-
-    /* Focus */
-
-    public void setFocus() {
-        try {
-            this.refreshFocus();
-        }
-        catch (MNoBrowserPageWebException exception) {
-        }
-        catch (MNoViewWebException exception) {
-        }
-        catch (MNoWidgetIdWebException exception) {
-        }
-        catch (MResponseWebException exception) {
-        }
-    }
-
-    /* Enabled mode */
-
-    public void setEnabledMode(boolean enabledMode) {
-        this.setEnabledMode(enabledMode, true);
-    }
-
-    protected void setEnabledMode(boolean enabledMode, boolean refreshMode) {
-        this.enabledMode = enabledMode;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshEnabledMode();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public boolean getEnabledMode() {
-        return this.enabledMode;
-    }
-
-    /* Content disposition */
-
-    protected String getFileName(Part part) { // taken and adapted from http://java-x.blogspot.com/2010/08/file-upload-with-servlet-30.html
-        if (null == part) {
-            throw new IllegalArgumentException("Invalid 'part': null.");
-        }
-        //
-        for (String cd: part.getHeader("content-disposition").split(";")) {
-            if (cd.trim().startsWith("filename")) {
-                return cd.substring(cd.indexOf("=") + 1).trim().replace("\"", "");
-            }
-        }
-        return null;
-    }
-
-    /* Refresh */
-
-    protected void refreshFocus() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s_file').focus(); }", this.getId(), this.getId()));
-    }
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        String onUploadFunction = String.format("javascript: m_messageInterface.fireUploadFakeMessage('%s');", this.getId());
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<form class=\"MWebUploader %s\" id=\"%s\" action=\"#\" enctype=\"multipart/form-data\" method=\"post\" target=\"m_uploader\"><input type=\"file\" class=\"MWebUploaderFile %s\" style=\"display: inline-block;\" onchange=\"%s\" id=\"%s_file\" name=\"%s_file\" /></form>'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onUploadFunction), this.getId(), this.getId()));
-        //
-        super.refresh();
-        //
-        this.refreshEnabledMode();
-    }
-
-    protected void refreshEnabledMode() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s_file').disabled = %s; }", this.getId(), this.getId(), !this.getEnabledMode()));
-    }
-
-    /* Messages */
-
-    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
-        super.processMessage(event, parameters);
-        //
-        if ("onRefresh".equals(event)) {
-            this.onRefresh();
-        }
-        else if ("onUpload".equals(event)) {
-            if ((!this.getVisibleMode()) || (!this.getEnabledMode())) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden or disabled.", event));
-            }
-            HttpServletRequest request = this.getApplicationContextReference().getRequestReference();
-            Collection<Part> parts = null;
-            try {
-                parts = request.getParts();
-            }
-            catch (IllegalStateException exception) {
-                throw new MUnexpectedMessageWebException("Invalid message: size exceeded."); // no need to propagate exception
-               }
-            catch (IOException exception) {
-                throw new MUnexpectedMessageWebException("Invalid message: I/O error."); // no need to propagate exception
-               }
-            catch (ServletException exception) {
-                throw new MUnexpectedMessageWebException("Invalid message: not a multipart/form-data request."); // no need to propagate exception
-               }
-            if (1 != parts.size()) {
-                throw new MUnexpectedMessageWebException("Invalid message: there must be exactly one part.");
-            }
-            this.onUpload(parts.iterator().next());
-        }
-        else {
-            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
-        }
-    }
-
-    public void onUpload(Part part) {
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebVerticalMenu.java b/src/java/com/marcozanon/macaco/webui/MWebVerticalMenu.java
deleted file mode 100644 (file)
index c8e4b0c..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-
-public class MWebVerticalMenu extends MWebDirectWidget {
-
-    protected String title = null;
-
-    protected boolean accordionMode = true;
-
-    protected LinkedHashMap<String, MWebVerticalMenuItem> items = new LinkedHashMap<String, MWebVerticalMenuItem>();
-    protected String selectedItemKey = null;
-
-    /* */
-
-    public MWebVerticalMenu(MWebApplicationContext applicationContext, String title) {
-        super(applicationContext);
-        //
-        this.title = title;
-    }
-
-    public MWebVerticalMenu(MWebApplicationContext applicationContext, String title, LinkedHashMap<String, MWebVerticalMenuItem> items, String selectedItemKey) {
-        this(applicationContext, title);
-        //
-        this.setItems(items, selectedItemKey);
-    }
-
-    /* Title */
-
-    public String getTitle() {
-        return this.title;
-    }
-
-    /* Accordion mode */
-
-    public void setAccordionMode(boolean accordionMode) {
-        this.setAccordionMode(accordionMode, true);
-    }
-
-    protected void setAccordionMode(boolean accordionMode, boolean refreshMode) {
-        this.accordionMode = accordionMode;
-        //
-        if (refreshMode) {
-            try {
-                this.refresh(); // must refresh everything
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-            catch (MUniqueWidgetIdNotAvailableWebException exception) {
-            }
-        }
-    }
-
-    public boolean getAccordionMode() {
-        return this.accordionMode;
-    }
-
-    /* Items */
-
-    public void setItems(LinkedHashMap<String, MWebVerticalMenuItem> items, String selectedItemKey) {
-        this.setItems(items, selectedItemKey, true);
-    }
-
-    protected void setItems(LinkedHashMap<String, MWebVerticalMenuItem> items, String selectedItemKey, boolean refreshMode) {
-        if (null == items) {
-            throw new IllegalArgumentException("Invalid 'items': null.");
-        }
-        else {
-            for (String k: items.keySet()) {
-                if ((null == k) || ("".equals(k))) {
-                    throw new IllegalArgumentException("Invalid 'items': item key null or empty.");
-                }
-                else if (null == items.get(k)) {
-                    throw new IllegalArgumentException("Invalid 'items': item null.");
-                }
-            }
-        }
-        //
-        this.items = items;
-        //
-        if (refreshMode) {
-            try {
-                this.refresh(); // must refresh everything
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-            catch (MUniqueWidgetIdNotAvailableWebException exception) {
-            }
-        }
-        //
-        this.setSelectedItem(selectedItemKey, refreshMode);
-    }
-
-    protected LinkedHashMap<String, MWebVerticalMenuItem> getItemsReference() {
-        return this.items;
-    }
-
-    public LinkedHashMap<String, MWebVerticalMenuItem> getItems() {
-        LinkedHashMap<String, MWebVerticalMenuItem> tmpItems = new LinkedHashMap<String, MWebVerticalMenuItem>();
-        for (String key: this.getItemsReference().keySet()) {
-            tmpItems.put(key, this.getItemsReference().get(key).clone());
-        }
-        return tmpItems;
-    }
-
-    public LinkedHashSet<String> getItemKeys() {
-        LinkedHashSet<String> tmpItemKeys = new LinkedHashSet<String>();
-        for (String itemKey: this.getItemsReference().keySet()) {
-            tmpItemKeys.add(itemKey);
-        }
-        return tmpItemKeys;
-    }
-
-    public void setSelectedItem(String selectedItemKey) {
-        this.setSelectedItem(selectedItemKey, true);
-    }
-
-    protected void setSelectedItem(String selectedItemKey, boolean refreshMode) {
-        if ("".equals(selectedItemKey)) {
-            throw new IllegalArgumentException("Invalid 'selectedItemKey': empty.");
-        }
-        else if ((null != selectedItemKey) && (!this.getItemsReference().containsKey(selectedItemKey))) {
-            throw new IllegalArgumentException(String.format("Invalid 'selectedItemKey': %s: not available.", selectedItemKey));
-        }
-        //
-        this.selectedItemKey = selectedItemKey;
-        //
-        if (refreshMode) {
-            try {
-                this.refresh(); // must refresh everything
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-            catch (MUniqueWidgetIdNotAvailableWebException exception) {
-            }
-        }
-    }
-
-    public String getSelectedItemKey() {
-        return this.selectedItemKey;
-    }
-
-    /* Refresh */
-
-    protected String getItemContent(String parentItemKey) throws MNoWidgetIdWebException { // code partly taken from http://www.codecodex.com/wiki/Count_the_number_of_occurrences_of_a_specific_character_in_a_string
-        if ("".equals(parentItemKey)) {
-            throw new IllegalArgumentException("Invalid 'parentItemKey': empty.");
-        }
-        //
-        if (null == parentItemKey) {
-            parentItemKey = ""; // rewritten for better readability
-        }
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        int parentItemLevel = parentItemKey.replaceAll("[^.]", "").length();
-        StringBuilder itemContent = new StringBuilder("");
-        if ((0 == parentItemLevel) && (null != this.getTitle())) {
-            itemContent.append(String.format("<tr class=\"MWebVerticalMenuTitleRow %s\">", customClasses));
-            itemContent.append(String.format("<td class=\"MWebVerticalMenuTitleCell %s\" colspan=\"2\">%s</td>", customClasses, MWebString.getXhtmlEscapedString(this.getTitle())));
-            itemContent.append("</tr>");
-        }
-        String lastItemKey = "";
-        for (String itemKey: this.getItemsReference().keySet()) {
-            lastItemKey = itemKey;
-            if (!itemKey.startsWith(parentItemKey)) {
-                continue;
-            }
-            if (itemKey.replaceAll("[^.]", "").length() != (parentItemLevel + 1)) {
-                continue;
-            }
-            itemContent.append(String.format("<tr class=\"MWebVerticalMenuRow %s\">", customClasses));
-            String text = this.getItemsReference().get(itemKey).getText();
-            if (!"".equals(text)) {
-                String imageSource = this.getItemsReference().get(itemKey).getImageSource();
-                if (null == imageSource) {
-                    imageSource = String.format("%s/null", this.getApplicationContextReference().getRequestReference().getRequestURL());
-                }
-                String imageClass = "MWebVerticalMenuImageCell";
-                String textClass = "MWebVerticalMenuTextCell";
-                if (itemKey.equals(this.getSelectedItemKey())) {
-                    imageClass = "MWebVerticalMenuSelectedImageCell";
-                    textClass = "MWebVerticalMenuSelectedTextCell";
-                }
-                String onItemSelectionFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onItemSelection', {'selectedItemKey': '%s'});", this.getId(), MWebString.getJavascriptEscapedString(itemKey));
-                itemContent.append(String.format("<td class=\"%s %s\" onclick=\"%s\" id=\"%s\"><img class=\"MWebVerticalMenuImage %s\" src=\"%s\" alt=\"\" /></td>", imageClass, customClasses, MWebString.getXhtmlEscapedString(onItemSelectionFunction), this.getId() + MWebString.getXhtmlEscapedString(itemKey) + "-imageCell", customClasses, MWebString.getXhtmlEscapedString(imageSource)));
-                itemContent.append(String.format("<td class=\"%s %s\" onclick=\"%s\" id=\"%s\">%s</td>", textClass, customClasses, MWebString.getXhtmlEscapedString(onItemSelectionFunction), this.getId() + MWebString.getXhtmlEscapedString(itemKey) + "-textCell", MWebString.getXhtmlEscapedString(text)));
-            }
-            else {
-                itemContent.append(String.format("<td class=\"MWebVerticalMenuSeparatorCell %s\" id=\"%s\" colspan=\"2\"></td>", customClasses, this.getId() + MWebString.getXhtmlEscapedString(itemKey) + "-separatorCell"));
-            }
-            itemContent.append("</tr>");
-            //
-            if ((!this.getAccordionMode()) || (this.getAccordionMode() && (null != this.getSelectedItemKey()) && (this.getSelectedItemKey().startsWith(itemKey)))) {
-                String childItemContent = this.getItemContent(itemKey);
-                if (!"".equals(childItemContent.toString())) {
-                    itemContent.append(String.format("<tr class=\"MWebVerticalMenuRow %s\">", customClasses));
-                    itemContent.append(String.format("<td class=\"MWebVerticalMenuImageCell\" />", customClasses));
-                    itemContent.append(String.format("<td class=\"MWebVerticalMenuChildTableCell %s\" id=\"%s\">%s</td>", customClasses, this.getId() + MWebString.getXhtmlEscapedString(itemKey) + "-childCell", childItemContent));
-                    itemContent.append("</tr>");
-                }
-            }
-        }
-        //
-        StringBuilder content = new StringBuilder("");
-        if (!"".equals(itemContent.toString())) {
-            if ("".equals(parentItemKey)) {
-                content.append(String.format("<table class=\"MWebVerticalMenuTable %s\" style=\"display: inline-table;\" id=\"%s\">", customClasses, this.getId()));
-            }
-            else {
-                content.append(String.format("<table class=\"MWebVerticalMenuChildTable %s\" style=\"display: inline-table; width: 100%%;\" id=\"%s\">", customClasses, this.getId() + MWebString.getXhtmlEscapedString(lastItemKey) + "-childTable"));
-            }
-            content.append(itemContent);
-            content.append("</table>");
-        }
-        return content.toString();
-    }
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        String content = this.getItemContent(null);
-        if ("".equals(content)) {
-            content = String.format("<div id=\"%s\"></div>", this.getId());
-        }
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(content)));
-        //
-        super.refresh();
-    }
-
-    /* Messages */
-
-    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
-        super.processMessage(event, parameters);
-        //
-        if ("onItemSelection".equals(event)) {
-            if (!this.getVisibleMode()) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden.", event));
-            }
-            String selectedItemKey = parameters.get("selectedItemKey");
-            if (null == selectedItemKey) {
-                throw new MUnexpectedMessageWebException("Invalid message: selected item key parameter not available.");
-            }
-            else if (!this.getItemsReference().keySet().contains(selectedItemKey)) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: selected item key parameter not recognized.", selectedItemKey));
-            }
-            this.onItemSelection(selectedItemKey);
-        }
-        else if ("onRefresh".equals(event)) {
-            this.onRefresh();
-        }
-        else {
-            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
-        }
-    }
-
-    public void onItemSelection(String selectedItemKey) {
-        this.setSelectedItem(selectedItemKey);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebVerticalMenuItem.java b/src/java/com/marcozanon/macaco/webui/MWebVerticalMenuItem.java
deleted file mode 100644 (file)
index a028a46..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.MObject;
-
-public class MWebVerticalMenuItem extends MObject {
-
-    protected MWebApplicationContext applicationContext = null;
-
-    protected String text = "";
-    protected String imageSource = null;
-
-    /* */
-
-    public MWebVerticalMenuItem(MWebApplicationContext applicationContext) {
-        super();
-        //
-        if (null == applicationContext) {
-            throw new IllegalArgumentException("Invalid 'applicationContext': null.");
-        }
-        //
-        this.applicationContext = applicationContext;
-    }
-
-    public MWebVerticalMenuItem(MWebApplicationContext applicationContext, String text, String imageSource) {
-        this(applicationContext);
-        //
-        if (null == text) {
-            throw new IllegalArgumentException("Invalid 'text': null.");
-        }
-        //
-        this.text = text;
-        this.imageSource = imageSource;
-    }
-
-    public MWebVerticalMenuItem clone() {
-        return new MWebVerticalMenuItem(this.getApplicationContextReference(), this.getText(), this.getImageSource());
-    }
-
-    /* Application context */
-
-    public MWebApplicationContext getApplicationContextReference() {
-        return this.applicationContext;
-    }
-
-    /* Text */
-
-    public String getText() {
-        return this.text;
-    }
-
-    /* Image source */
-
-    public String getImageSource() {
-        return this.imageSource;
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebView.java b/src/java/com/marcozanon/macaco/webui/MWebView.java
deleted file mode 100644 (file)
index 90deb2f..0000000
+++ /dev/null
@@ -1,443 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.MObject;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-
-public class MWebView extends MObject implements Runnable {
-
-    protected MWebApplicationContext applicationContext = null;
-
-    protected MWebBrowserPage browserPage = null;
-
-    protected String breadcrumb = null;
-    protected String title = "";
-
-    protected LinkedList<MWebDownloader> downloaders = new LinkedList<MWebDownloader>();
-    protected MWebDirectWidget content = null;
-
-    protected LinkedHashSet<Long> uniqueWidgetIds = new LinkedHashSet<Long>();
-    protected long uniqueWidgetIdsPointer = 0;
-
-    /* */
-
-    public MWebView(MWebApplicationContext applicationContext, String breadcrumb) {
-        super();
-        //
-        if (null == applicationContext) {
-            throw new IllegalArgumentException("Invalid 'applicationContext': null.");
-        }
-        if ((null == breadcrumb) || ("".equals(breadcrumb))) {
-            throw new IllegalArgumentException("Invalid 'breadcrumb': null or empty.");
-        }
-        //
-        this.applicationContext = applicationContext;
-        this.breadcrumb = breadcrumb;
-    }
-
-    public void run() {
-        while (true) {
-            try {
-                this.processMessage(this.getBrowserPageReference().getProcessableMessage());
-            }
-            catch (MViewThreadStoppingWebRuntimeException exception) {
-                break;
-            }
-            catch (Exception exception) { // any other exception, put here not to bypass MViewThreadStoppingWebRuntimeException
-                try {
-                    this.getBrowserPageReference().setLastViewThreadException(exception);
-                }
-                catch (MNoBrowserPageWebException exception2) {
-                }
-            }
-            //
-            try {
-                synchronized (Thread.currentThread()) {
-                    Thread.currentThread().wait();
-                }
-            }
-            catch (InterruptedException exception) {
-            }
-        }
-    }
-
-    public String openView(MWebView view) throws MNoBrowserPageWebException {
-        this.getBrowserPageReference().loadViewThread(view);
-        try {
-            synchronized (Thread.currentThread()) {
-                Thread.currentThread().wait();
-            }
-        }
-        catch (InterruptedException exception) {
-        }
-        //
-        if (this.getBrowserPageReference().getStoppingViewThreadCount() > 0) {
-            this.getBrowserPageReference().decrementStoppingViewThreadCount();
-            throw new MViewThreadStoppingWebRuntimeException("View thread stopping...");
-        }
-        //
-        try {
-            this.refresh();
-        }
-        catch (MNoBrowserPageWebException exception) {
-        }
-        catch (MNoWidgetIdWebException exception) {
-        }
-        catch (MResponseWebException exception) {
-        }
-        //
-        return this.getBrowserPageReference().getLastViewThreadReturnValue();
-    }
-
-    public void close(String returnValue) throws MNoBrowserPageWebException, MViewNotUnloadableWebException {
-        this.getBrowserPageReference().unloadViewThreads(returnValue, 1, null);
-        throw new MViewThreadStoppingWebRuntimeException("View thread stopping...");
-    }
-
-    public void close(int n) throws MNoBrowserPageWebException, MViewNotUnloadableWebException {
-        this.getBrowserPageReference().unloadViewThreads(null, n, null);
-        throw new MViewThreadStoppingWebRuntimeException("View thread stopping...");
-    }
-
-    public void closeAll(MWebView replacingView) throws MNoBrowserPageWebException, MViewNotUnloadableWebException {
-        this.getBrowserPageReference().unloadViewThreads(null, this.getBrowserPageReference().getViewThreadCount(), replacingView);
-        throw new MViewThreadStoppingWebRuntimeException("View thread stopping...");
-    }
-
-    /* Application context */
-
-    public MWebApplicationContext getApplicationContextReference() {
-        return this.applicationContext;
-    }
-
-    /* Browser page */
-
-    protected void setBrowserPage(MWebBrowserPage browserPage) {
-        this.browserPage = browserPage;
-    }
-
-    public MWebBrowserPage getBrowserPageReference() throws MNoBrowserPageWebException {
-        if (null == this.browserPage) {
-            throw new MNoBrowserPageWebException("Invalid browser page: reference null.");
-        }
-        //
-        return this.browserPage;
-    }
-
-    /* Breadcrumb */
-
-    public String getBreadcrumb() {
-        return this.breadcrumb;
-    }
-
-    /* Title */
-
-    public void setTitle(String title) {
-        this.setTitle(title, true);
-    }
-
-    protected void setTitle(String title, boolean refreshMode) {
-        if (null == title) {
-            throw new IllegalArgumentException("Invalid 'title': null.");
-        }
-        //
-        this.title = title;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshTitle();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public String getTitle() {
-        return this.title;
-    }
-
-    /* Downloaders */
-
-    public void addDownloader(MWebDownloader downloader) throws MUniqueWidgetIdNotAvailableWebException {
-        if (null == downloader) {
-            throw new IllegalArgumentException("Invalid 'downloader': null.");
-        }
-        //
-        downloader.setView(this);
-        this.getDownloadersReference().add(downloader);
-    }
-
-    public void setDownloader(int index, MWebDownloader downloader) throws MUniqueWidgetIdNotAvailableWebException {
-        if ((index < 0) || (index > (this.getDownloadersReference().size() - 1))) {
-            throw new IllegalArgumentException(String.format("Invalid 'index': %s: out of range.", index));
-        }
-        if (null == downloader) {
-            throw new IllegalArgumentException("Invalid 'downloader': null.");
-        }
-        //
-        downloader.setView(this);
-        this.getDownloadersReference().set(index, downloader);
-    }
-
-    protected LinkedList<MWebDownloader> getDownloadersReference() {
-        return this.downloaders;
-    }
-
-    public MWebDownloader getDownloaderReference(int index) {
-        if ((index < 0) || (index > (this.getDownloadersReference().size() - 1))) {
-            throw new IllegalArgumentException(String.format("Invalid 'index': %s: out of range.", index));
-        }
-        //
-        return this.getDownloadersReference().get(index);
-    }
-
-    public MWebDownloader getDownloaderReferenceById(String id) throws MDownloaderNotFoundWebException {
-        if ((null == id) || ("".equals(id))) {
-            throw new IllegalArgumentException("Invalid 'id': null or empty.");
-        }
-        //
-        for (MWebDownloader downloader: this.getDownloadersReference()) {
-            try {
-                if (downloader.getId().equals(id)) {
-                    return downloader;
-                }
-            }
-            catch (MNoWidgetIdWebException exception) { // cannot happen
-            }
-        }
-        throw new MDownloaderNotFoundWebException(String.format("Invalid 'id': %s.", id));
-    }
-
-    public int countDownloaders() {
-        return this.getDownloadersReference().size();
-    }
-
-    public void removeDownloader(int index) {
-        if ((index < 0) || (index > (this.getDownloadersReference().size() - 1))) {
-            throw new IllegalArgumentException(String.format("Invalid 'index': %s: out of range.", index));
-        }
-        //
-        try {
-            this.getDownloaderReference(index).setView(null);
-        }
-        catch (MUniqueWidgetIdNotAvailableWebException exception) { // cannot happen
-        }
-        this.getDownloadersReference().remove(index);
-    }
-
-    public void clearDownloaders() {
-        this.getDownloadersReference().clear();
-    }
-
-    /* Content */
-
-    public void setContent(MWebDirectWidget directWidget) throws MUniqueWidgetIdNotAvailableWebException {
-        this.setContent(directWidget, true);
-    }
-
-    protected void setContent(MWebDirectWidget directWidget, boolean refreshMode) throws MUniqueWidgetIdNotAvailableWebException {
-        try {
-            this.getContentReference().setView(null);
-        }
-        catch (MNoViewContentWebException exception) {
-        }
-        catch (MUniqueWidgetIdNotAvailableWebException exception) { // cannot happen
-        }
-        //
-        this.content = directWidget;
-        //
-        try {
-            this.getContentReference().setView(this);
-        }
-        catch (MNoViewContentWebException exception) {
-        }
-        //
-        if (refreshMode) {
-            try {
-                this.refreshContent();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public MWebDirectWidget getContentReference() throws MNoViewContentWebException {
-        if (null == this.content) {
-            throw new MNoViewContentWebException("Invalid content: reference null.");
-        }
-        //
-        return this.content;
-    }
-
-    /* Display widgets */
-
-    protected MWebDisplayWidget getDisplayWidgetReferenceById(String id) throws MDisplayWidgetNotFoundWebException {
-        try {
-            return this.getContentReference().getDisplayWidgetReferenceById(id);
-        }
-        catch (MDisplayWidgetNotFoundWebException exception) {
-            throw new MDisplayWidgetNotFoundWebException(String.format("Invalid 'id': %s: display widget not available on this path.", id)); // no need to propagate exception
-        }
-        catch (MNoViewContentWebException exception) {
-            throw new MDisplayWidgetNotFoundWebException(String.format("Invalid 'id': %s: no view content.", id)); // no need to propagate exception
-        }
-    }
-
-    /* Unique widget ids */
-
-    protected LinkedHashSet<Long> getUniqueWidgetIdsReference() {
-        return this.uniqueWidgetIds;
-    }
-
-    public long getUniqueWidgetId() throws MUniqueWidgetIdNotAvailableWebException {
-        long p = this.uniqueWidgetIdsPointer;
-        //
-        while (true) {
-            if (Long.MAX_VALUE == this.uniqueWidgetIdsPointer) {
-                this.uniqueWidgetIdsPointer = 0;
-            }
-            else {
-                this.uniqueWidgetIdsPointer++;
-            }
-            if (p == this.uniqueWidgetIdsPointer) {
-                throw new MUniqueWidgetIdNotAvailableWebException("Unique widget id not available: too many widgets registered.");
-            }
-            else if (!this.getUniqueWidgetIdsReference().contains(new Long(this.uniqueWidgetIdsPointer))) {
-                this.getUniqueWidgetIdsReference().add(new Long(this.uniqueWidgetIdsPointer));
-                return this.uniqueWidgetIdsPointer;
-            }
-        }
-    }
-
-    public void freeUniqueWidgetId(long uniqueWidgetId) {
-        if (uniqueWidgetId <= 0) {
-            throw new IllegalArgumentException("Invalid 'uniqueWidgetId': must be positive.");
-        }
-        //
-        this.getUniqueWidgetIdsReference().remove(new Long(uniqueWidgetId));
-    }
-
-    /* Refresh */
-
-    public void checkPresence() throws MNoBrowserPageWebException {
-        this.getBrowserPageReference();
-    }
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent("$disableWysiwygBoxEditors();");
-        //
-        this.refreshContent();
-        //
-        this.refreshTitle();
-    }
-
-    protected void refreshContent() throws MNoBrowserPageWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        try {
-            MWebDisplayWidget content = this.getContentReference();
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("$('m_view').innerHTML = '<div id=\"%s\"></div>';", content.getId()));
-            content.onRefresh();
-        }
-        catch (MNoViewContentWebException exception) {
-            this.getApplicationContextReference().addPlainTextResponseContent("$('m_view').innerHTML = '';");
-        }
-    }
-
-    protected void refreshTitle() throws MNoBrowserPageWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("document.title = '%s';", MWebString.getJavascriptEscapedString(this.getTitle())));
-    }
-
-    /* Messages */
-
-    protected void onMessagePreprocessing() {
-    }
-
-    protected void processMessage(MWebMessage message) throws MUnexpectedMessageWebException {
-        if (null == message) {
-            throw new IllegalArgumentException("Invalid 'message': null.");
-        }
-        //
-        this.onMessagePreprocessing();
-        // parse message and forward it to view or to appropriate widgets
-        String widgetId = message.getWidgetId();
-        String event = message.getEvent();
-        LinkedHashMap<String, String> parameters = message.getParameters();
-        if ("".equals(widgetId)) { // no widget id = view
-            if ("onRefresh".equals(event)) {
-                this.onRefresh();
-            }
-            else {
-                throw new MUnexpectedMessageWebException(String.format("Invalid 'message': %s: event not recognized.", event));
-            }
-        }
-        else {
-            try { // first search through downloaders...
-                this.getDownloaderReferenceById(widgetId).processMessage(event, parameters);
-            }
-            catch (MDownloaderNotFoundWebException exception) {
-                try { // ...then through display widgets
-                    this.getDisplayWidgetReferenceById(widgetId).processMessage(event, parameters);
-                }
-                catch (MDisplayWidgetNotFoundWebException exception2) {
-                    throw new MUnexpectedMessageWebException(String.format("Invalid 'message': %s: widget not found.", widgetId)); // no need to propagate exception
-                }
-                catch (MUnexpectedMessageWebException exception2) {
-                    throw new MUnexpectedMessageWebException("Invalid 'message': not suitable.", exception2);
-                }
-            }
-            catch (MUnexpectedMessageWebException exception) {
-                throw new MUnexpectedMessageWebException("Invalid 'message': not suitable.", exception);
-            }
-        }
-    }
-
-    public void onRefresh() {
-        try {
-            this.refresh();
-        }
-        catch (MNoBrowserPageWebException exception) {
-        }
-        catch (MNoWidgetIdWebException exception) {
-        }
-        catch (MResponseWebException exception) {
-        }
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebWidget.java b/src/java/com/marcozanon/macaco/webui/MWebWidget.java
deleted file mode 100644 (file)
index 817c880..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import com.marcozanon.macaco.MObject;
-import java.util.LinkedHashMap;
-
-public abstract class MWebWidget extends MObject {
-
-    protected MWebApplicationContext applicationContext = null;
-
-    protected MWebView view = null;
-
-    protected String id = null;
-
-    /* */
-
-    public MWebWidget(MWebApplicationContext applicationContext) {
-        super();
-        //
-        if (null == applicationContext) {
-            throw new IllegalArgumentException("Invalid 'applicationContext': null.");
-        }
-        //
-        this.applicationContext = applicationContext;
-    }
-
-    /* Application context */
-
-    public MWebApplicationContext getApplicationContextReference() {
-        return this.applicationContext;
-    }
-
-    /* View */
-
-    protected void setView(MWebView view) throws MUniqueWidgetIdNotAvailableWebException {
-        try {
-            this.getViewReference().freeUniqueWidgetId((new Long(this.getId().substring("m_widget".length()))).longValue());
-        }
-        catch (MNoViewWebException exception) {
-        }
-        catch (MNoWidgetIdWebException exception) {
-        }
-        //
-        this.view = view;
-        //
-        if (null == view) {
-            this.id = null;
-        }
-        else {
-            this.id = (new Long(view.getUniqueWidgetId())).toString();
-        }
-    }
-
-    public MWebView getViewReference() throws MNoViewWebException {
-        if (null == this.view) {
-            throw new MNoViewWebException("Invalid view: reference null.");
-        }
-        //
-        return this.view;
-    }
-
-    /* Id */
-
-    public String getId() throws MNoWidgetIdWebException {
-        if (null == this.id) {
-            throw new MNoWidgetIdWebException("Invalid id: reference null.");
-        }
-        //
-        return "m_widget" + this.id;
-    }
-
-    /* Messages */
-
-    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
-        if ((null == event) || ("".equals(event))) {
-            throw new IllegalArgumentException("Invalid 'event': null or empty.");
-        }
-        if (null == parameters) {
-            throw new IllegalArgumentException("Invalid 'parameters': null.");
-        }
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebWysiwygBox.java b/src/java/com/marcozanon/macaco/webui/MWebWysiwygBox.java
deleted file mode 100644 (file)
index 593ff6d..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-import java.util.LinkedHashMap;
-
-public class MWebWysiwygBox extends MWebDirectWidget {
-
-    protected String text = "";
-
-    protected boolean enabledMode = true;
-    protected boolean displayedMode = false; // for internal use only
-
-    /* */
-
-    public MWebWysiwygBox(MWebApplicationContext applicationContext) {
-        super(applicationContext);
-    }
-
-    public MWebWysiwygBox(MWebApplicationContext applicationContext, String text) {
-        this(applicationContext);
-        //
-        this.setText(text);
-    }
-
-    /* Focus */
-
-    public void setFocus() {
-        try {
-            this.refreshFocus();
-        }
-        catch (MNoBrowserPageWebException exception) {
-        }
-        catch (MNoViewWebException exception) {
-        }
-        catch (MNoWidgetIdWebException exception) {
-        }
-        catch (MResponseWebException exception) {
-        }
-    }
-
-    /* Text */
-
-    public void setText(String text) {
-        this.setText(text, true);
-    }
-
-    protected void setText(String text, boolean refreshMode) {
-        if (null == text) {
-            throw new IllegalArgumentException("Invalid 'text': null.");
-        }
-        //
-        try {
-            this.text = MWebString.getXhtmlSafeString(text);
-        }
-        catch (MXhtmlUnsafeStringWebException exception) {
-            throw new IllegalArgumentException(String.format("Invalid 'text': %s: unsafe Xhtml tags or attributes inside.", text)); // no need to propagate exception
-        }
-        //
-        if (refreshMode) {
-            try {
-                this.refreshText();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public String getText() {
-        return this.text;
-    }
-
-    /* Enabled mode */
-
-    public void setEnabledMode(boolean enabledMode) {
-        this.setEnabledMode(enabledMode, true);
-    }
-
-    protected void setEnabledMode(boolean enabledMode, boolean refreshMode) {
-        this.enabledMode = enabledMode;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshEnabledMode();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public boolean getEnabledMode() {
-        return this.enabledMode;
-    }
-
-    /* Refresh */
-
-    protected void refreshFocus() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        if (this.getEnabledMode()) {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $focusWysiwygBoxEditor('%s'); }", this.getId(), this.getId()));
-        }
-    }
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        this.displayedMode = false;
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        customClasses = customClasses + " " + this.getId();
-        StringBuilder content = new StringBuilder("");
-        content.append(String.format("<div class=\"MWebWysiwygBox %s\" style=\"display: inline-block;\" id=\"%s\" cols=\"1\" rows=\"1\"></div>", customClasses, this.getId()));
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(content.toString())));
-        //
-        super.refresh();
-        //
-        this.refreshEnabledMode();
-        this.refreshText();
-    }
-
-    protected void refreshEnabledMode() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        if (this.getEnabledMode()) {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $enableWysiwygBoxEditor('%s', '%s'); }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(this.getText())));
-            this.displayedMode = true;
-        }
-        else {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $disableWysiwygBoxEditor('%s'); }", this.getId(), this.getId()));
-            this.displayedMode = false;
-        }
-    }
-
-    protected void refreshText() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        if (this.getEnabledMode() && this.displayedMode) {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $fillWysiwygBoxEditor('%s', '%s'); }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(this.getText())));
-        }
-        else {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(this.getText())));
-        }
-    }
-
-    /* Messages */
-
-    protected void processMessage(String event, LinkedHashMap<String, String> parameters) throws MUnexpectedMessageWebException {
-        super.processMessage(event, parameters);
-        //
-        if ("onBlur".equals(event)) {
-            if ((!this.getVisibleMode()) || (!this.getEnabledMode())) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not fireable while hidden or disabled.", event));
-            }
-            String text = parameters.get("text");
-            if (null == text) {
-                throw new MUnexpectedMessageWebException("Invalid message: text parameter not available.");
-            }
-            try {
-                String y = MWebString.getXhtmlSafeString(text);
-            }
-            catch (MXhtmlUnsafeStringWebException exception) {
-                throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: unsafe Xhtml tags or attributes inside.", text)); // no need to propagate exception
-            }
-            this.onBlur(text);
-        }
-        else if ("onRefresh".equals(event)) {
-            this.onRefresh();
-        }
-        else {
-            throw new MUnexpectedMessageWebException(String.format("Invalid message: %s: event not recognized.", event));
-        }
-    }
-
-    public void onBlur(String text) {
-        this.setText(text, false);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MWebXhtmlLabel.java b/src/java/com/marcozanon/macaco/webui/MWebXhtmlLabel.java
deleted file mode 100644 (file)
index 53c03ac..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MWebXhtmlLabel extends MWebLabel {
-
-    /* */
-
-    public MWebXhtmlLabel(MWebApplicationContext applicationContext) {
-        super(applicationContext);
-    }
-
-    public MWebXhtmlLabel(MWebApplicationContext applicationContext, String text) {
-        this(applicationContext);
-        //
-        this.setText(text);
-    }
-
-    /* Refresh */
-
-    protected void refresh() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException, MUniqueWidgetIdNotAvailableWebException {
-        this.checkPresence();
-        //
-        String customClasses = MWebString.getXhtmlEscapedString(this.getCustomClasses());
-        if (null == customClasses) {
-            customClasses = "";
-        }
-        String onClickFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onClick', {});", this.getId());
-        String onDoubleClickFunction = String.format("javascript: m_messageInterface.fireMessage('%s', 'onDoubleClick', {});", this.getId());
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').parentNode.innerHTML = '<div class=\"MWebXhtmlLabel %s\" style=\"display: inline-block;\" onclick=\"%s\" ondblclick=\"%s\" id=\"%s\"></div>'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(customClasses), MWebString.getJavascriptEscapedString(onClickFunction), MWebString.getJavascriptEscapedString(onDoubleClickFunction), this.getId()));
-        //
-        super.refresh();
-        //
-        this.refreshText();
-    }
-
-    protected void refreshText() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '%s'; }", this.getId(), this.getId(), MWebString.getJavascriptEscapedString(MWebString.getXhtmlNumericEntitiesString(this.getText()))));
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/webui/MXhtmlUnsafeStringWebException.java b/src/java/com/marcozanon/macaco/webui/MXhtmlUnsafeStringWebException.java
deleted file mode 100644 (file)
index b420021..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon
- * 
- * Released under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.marcozanon.macaco.webui;
-
-public class MXhtmlUnsafeStringWebException extends MSecurityWebException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MXhtmlUnsafeStringWebException() {
-        super();
-    }
-
-    public MXhtmlUnsafeStringWebException(String message) {
-        super(message);
-    }
-
-    public MXhtmlUnsafeStringWebException(Throwable error) {
-        super(error);
-    }
-
-    public MXhtmlUnsafeStringWebException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}