Moved packages 'web.ui' and 'configuration' under 'attic'.
authorMarco Zanon <info@marcozanon.com>
Fri, 13 Apr 2012 20:52:24 +0000 (20:52 +0000)
committerMarco Zanon <info@marcozanon.com>
Fri, 13 Apr 2012 20:52:24 +0000 (20:52 +0000)
132 files changed:
src/java/com/marcozanon/macaco/attic/configuration/MConfiguration.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/configuration/MConfigurationException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/configuration/MFileParsingConfigurationException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/configuration/MValueNotFoundConfigurationException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MApplicationServletWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MBrowserPageRequestPreprocessingWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MDisplayWidgetNotFoundWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MDownloaderNotFoundWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MInvalidRemoteIpAddressWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MInvalidRequestWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MInvalidResourceWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MInvalidSecurityIdWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MMessagingWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MNoBrowserPageWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MNoCellContentWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MNoLogFilterWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MNoProcessableMessageWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MNoViewContentWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MNoViewWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MNoWidgetIdWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MNullPropertyWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MResponseWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MSecurityWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MSetupWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MUnexpectedMessageWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MUniqueWidgetIdNotAvailableWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MValidationWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MViewNotUnloadableWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MViewThreadStoppingWebRuntimeException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebApplicationContext.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebApplicationServlet.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebBorder.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebBreadcrumbs.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebBrowserPage.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebCellWidget.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebCheckBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebColor.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebComboBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebDateBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebDirectWidget.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebDisplayWidget.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebDownloader.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebExtendedTextBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebFont.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebGridLayout.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebGridLayoutCell.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebImage.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebImageButton.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebLabel.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebMeasure.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebMessage.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebNumberBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebPasswordBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebRuntimeException.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebSimpleTextBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebTable.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebTableCell.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebTextBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebUploader.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebVerticalMenu.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebVerticalMenuItem.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebView.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebWidget.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebWysiwygBox.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/attic/web/ui/MWebXhtmlLabel.java [new file with mode: 0644]
src/java/com/marcozanon/macaco/configuration/MConfiguration.java [deleted file]
src/java/com/marcozanon/macaco/configuration/MConfigurationException.java [deleted file]
src/java/com/marcozanon/macaco/configuration/MFileParsingConfigurationException.java [deleted file]
src/java/com/marcozanon/macaco/configuration/MValueNotFoundConfigurationException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MApplicationServletWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MBrowserPageRequestPreprocessingWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MDisplayWidgetNotFoundWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MDownloaderNotFoundWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MInvalidRemoteIpAddressWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MInvalidRequestWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MInvalidResourceWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MInvalidSecurityIdWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MMessagingWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MNoBrowserPageWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MNoCellContentWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MNoLogFilterWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MNoProcessableMessageWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MNoViewContentWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MNoViewWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MNoWidgetIdWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MNullPropertyWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MResponseWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MSecurityWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MSetupWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MUnexpectedMessageWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MUniqueWidgetIdNotAvailableWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MValidationWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MViewNotUnloadableWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MViewThreadStoppingWebRuntimeException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebApplicationContext.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebApplicationServlet.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebBorder.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebBreadcrumbs.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebBrowserPage.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebCellWidget.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebCheckBox.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebColor.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebComboBox.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebDateBox.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebDirectWidget.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebDisplayWidget.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebDownloader.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebExtendedTextBox.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebFont.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebGridLayout.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebGridLayoutCell.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebImage.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebImageButton.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebLabel.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebMeasure.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebMessage.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebNumberBox.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebPasswordBox.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebRuntimeException.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebSimpleTextBox.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebTable.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebTableCell.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebTextBox.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebUploader.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebVerticalMenu.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebVerticalMenuItem.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebView.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebWidget.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebWysiwygBox.java [deleted file]
src/java/com/marcozanon/macaco/web/ui/MWebXhtmlLabel.java [deleted file]

diff --git a/src/java/com/marcozanon/macaco/attic/configuration/MConfiguration.java b/src/java/com/marcozanon/macaco/attic/configuration/MConfiguration.java
new file mode 100644 (file)
index 0000000..dfd4e65
--- /dev/null
@@ -0,0 +1,108 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.configuration;
+
+import com.marcozanon.macaco.MInformation;
+import com.marcozanon.macaco.MObject;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.io.UnsupportedEncodingException;
+import java.util.LinkedHashMap;
+
+public class MConfiguration extends MObject {
+
+    protected LinkedHashMap<String, String> parameters = new LinkedHashMap<String, String>();
+
+    /* */
+
+    public MConfiguration(String file) throws MFileParsingConfigurationException {
+        super();
+        //
+        this.parseFile(file);
+    }
+
+    /* Parameters */
+
+    protected LinkedHashMap<String, String> getParametersReference() {
+        return this.parameters;
+    }
+
+    /* Strings management */
+
+    public void parseFile(String file) throws MFileParsingConfigurationException {
+        if ((null == file) || ("".equals(file))) {
+            throw new IllegalArgumentException("Invalid 'file': null or empty.");
+        }
+        //
+        LineNumberReader buffer = null;
+        try {
+            buffer = new LineNumberReader(new InputStreamReader(new FileInputStream(file), MInformation.TEXT_ENCODING));
+        }
+        catch (FileNotFoundException exception) {
+            throw new MFileParsingConfigurationException("Could not open file.", exception);
+        }
+        catch (UnsupportedEncodingException exception) { // cannot happen
+        }
+        String line = null;
+        synchronized (this.getParametersReference()) {
+            while (true) {
+                try {
+                    line = buffer.readLine();
+                }
+                catch (IOException exception) {
+                    throw new MFileParsingConfigurationException("Could not read file.", exception);
+                }
+                if (null == line) {
+                    break;
+                }
+                line = line.trim();
+                if ((line.startsWith("#")) || (line.startsWith(";")) || ("".equals(line))) {
+                    continue;
+                }
+                else {
+                    int a = line.indexOf("=");
+                    if (-1 == a) {
+                        throw new MFileParsingConfigurationException(String.format("Invalid line: %s: string malformed.", buffer.getLineNumber()));
+                    }
+                    String key = line.substring(0, a).trim();
+                    String value = line.substring(a + 1).trim();
+                    if (this.getParametersReference().containsKey(key)) {
+                        throw new MFileParsingConfigurationException(String.format("Invalid line: %s: duplicated key: %s.", buffer.getLineNumber(), key));
+                    }
+                    this.getParametersReference().put(key, value);
+                }
+            }
+        }
+        try {
+            buffer.close();
+        }
+        catch (IOException exception) {
+            throw new MFileParsingConfigurationException("Could not close file.", exception);
+        }
+    }
+
+    public void clear() {
+        synchronized (this.getParametersReference()) {
+            this.getParametersReference().clear();
+        }
+    }
+
+    public String getValue(String key) throws MValueNotFoundConfigurationException {
+        if ((null == key) || ("".equals(key))) {
+            throw new IllegalArgumentException("Invalid 'key': null or empty.");
+        }
+        //
+        if (!this.getParametersReference().containsKey(key)) {
+            throw new MValueNotFoundConfigurationException(String.format("Invalid 'key': %s: not available.", key));
+        }
+        return this.getParametersReference().get(key);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/attic/configuration/MConfigurationException.java b/src/java/com/marcozanon/macaco/attic/configuration/MConfigurationException.java
new file mode 100644 (file)
index 0000000..9b7da18
--- /dev/null
@@ -0,0 +1,33 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.configuration;
+
+import com.marcozanon.macaco.MException;
+
+public abstract class MConfigurationException extends MException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MConfigurationException() {
+        super();
+    }
+
+    public MConfigurationException(String message) {
+        super(message);
+    }
+
+    public MConfigurationException(Throwable error) {
+        super(error);
+    }
+
+    public MConfigurationException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/attic/configuration/MFileParsingConfigurationException.java b/src/java/com/marcozanon/macaco/attic/configuration/MFileParsingConfigurationException.java
new file mode 100644 (file)
index 0000000..645d027
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.configuration;
+
+public class MFileParsingConfigurationException extends MConfigurationException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MFileParsingConfigurationException() {
+        super();
+    }
+
+    public MFileParsingConfigurationException(String message) {
+        super(message);
+    }
+
+    public MFileParsingConfigurationException(Throwable error) {
+        super(error);
+    }
+
+    public MFileParsingConfigurationException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/attic/configuration/MValueNotFoundConfigurationException.java b/src/java/com/marcozanon/macaco/attic/configuration/MValueNotFoundConfigurationException.java
new file mode 100644 (file)
index 0000000..4e65816
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.configuration;
+
+public class MValueNotFoundConfigurationException extends MConfigurationException {
+
+    private static final long serialVersionUID = 0L;
+
+    /* */
+
+    public MValueNotFoundConfigurationException() {
+        super();
+    }
+
+    public MValueNotFoundConfigurationException(String message) {
+        super(message);
+    }
+
+    public MValueNotFoundConfigurationException(Throwable error) {
+        super(error);
+    }
+
+    public MValueNotFoundConfigurationException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/attic/web/ui/MApplicationServletWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MApplicationServletWebException.java
new file mode 100644 (file)
index 0000000..db068c7
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MBrowserPageRequestPreprocessingWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MBrowserPageRequestPreprocessingWebException.java
new file mode 100644 (file)
index 0000000..fb47668
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MDisplayWidgetNotFoundWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MDisplayWidgetNotFoundWebException.java
new file mode 100644 (file)
index 0000000..96ea8a7
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MDownloaderNotFoundWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MDownloaderNotFoundWebException.java
new file mode 100644 (file)
index 0000000..98e192a
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MInvalidRemoteIpAddressWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MInvalidRemoteIpAddressWebException.java
new file mode 100644 (file)
index 0000000..640ec01
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MInvalidRequestWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MInvalidRequestWebException.java
new file mode 100644 (file)
index 0000000..586e8d5
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MInvalidResourceWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MInvalidResourceWebException.java
new file mode 100644 (file)
index 0000000..d82a7b5
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MInvalidSecurityIdWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MInvalidSecurityIdWebException.java
new file mode 100644 (file)
index 0000000..7d5fcaf
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MMessagingWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MMessagingWebException.java
new file mode 100644 (file)
index 0000000..f57b220
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MNoBrowserPageWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MNoBrowserPageWebException.java
new file mode 100644 (file)
index 0000000..1394933
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MNoCellContentWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MNoCellContentWebException.java
new file mode 100644 (file)
index 0000000..ba90d7a
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MNoLogFilterWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MNoLogFilterWebException.java
new file mode 100644 (file)
index 0000000..c41646d
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MNoProcessableMessageWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MNoProcessableMessageWebException.java
new file mode 100644 (file)
index 0000000..2d36091
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MNoViewContentWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MNoViewContentWebException.java
new file mode 100644 (file)
index 0000000..3cc6a8f
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MNoViewWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MNoViewWebException.java
new file mode 100644 (file)
index 0000000..b8f869a
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MNoWidgetIdWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MNoWidgetIdWebException.java
new file mode 100644 (file)
index 0000000..78c786a
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MNullPropertyWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MNullPropertyWebException.java
new file mode 100644 (file)
index 0000000..73428f8
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MResponseWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MResponseWebException.java
new file mode 100644 (file)
index 0000000..95507c1
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MSecurityWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MSecurityWebException.java
new file mode 100644 (file)
index 0000000..8ffdc88
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MSetupWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MSetupWebException.java
new file mode 100644 (file)
index 0000000..9659cec
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MUnexpectedMessageWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MUnexpectedMessageWebException.java
new file mode 100644 (file)
index 0000000..e8cc682
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MUniqueWidgetIdNotAvailableWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MUniqueWidgetIdNotAvailableWebException.java
new file mode 100644 (file)
index 0000000..38bc01b
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MValidationWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MValidationWebException.java
new file mode 100644 (file)
index 0000000..fbbee2c
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MViewNotUnloadableWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MViewNotUnloadableWebException.java
new file mode 100644 (file)
index 0000000..4f995ae
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MViewThreadStoppingWebRuntimeException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MViewThreadStoppingWebRuntimeException.java
new file mode 100644 (file)
index 0000000..3bfd8ea
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MWebApplicationContext.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebApplicationContext.java
new file mode 100644 (file)
index 0000000..0d8879e
--- /dev/null
@@ -0,0 +1,248 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.MInformation;
+import com.marcozanon.macaco.MObject;
+import com.marcozanon.macaco.text.MText;
+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, MText.getJavascriptEscapedString(MText.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, MText.getJavascriptEscapedString(MText.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/attic/web/ui/MWebApplicationServlet.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebApplicationServlet.java
new file mode 100644 (file)
index 0000000..22c2789
--- /dev/null
@@ -0,0 +1,359 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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) {
+            try {
+                MJsonObject returnValue = null;
+                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);
+                responseContent = returnValue.getJsonValue().getBytes(MInformation.TEXT_ENCODING);
+            }
+            catch (MInvalidValueJsonException exception) { // cannot happen
+            }
+        }
+        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) {
+                    try {
+                        MJsonObject returnValue = null;
+                        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);
+                        responseContent = returnValue.getJsonValue().getBytes(MInformation.TEXT_ENCODING);
+                    }
+                    catch (MInvalidValueJsonException exception) { // should not happen
+                    }
+                }
+                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/attic/web/ui/MWebBorder.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebBorder.java
new file mode 100644 (file)
index 0000000..e97556b
--- /dev/null
@@ -0,0 +1,85 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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 getCssValue() {
+        return this.getWidthReference().getCssValue() + " " + this.getStyle().toString() + " " + this.getColorReference().getCssValue();
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/attic/web/ui/MWebBreadcrumbs.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebBreadcrumbs.java
new file mode 100644 (file)
index 0000000..ac2f1b8
--- /dev/null
@@ -0,0 +1,133 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.text.MText;
+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 = MText.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(), MText.getJavascriptEscapedString(customClasses), this.getId()));
+        //
+        super.refresh();
+        //
+        StringBuilder content = new StringBuilder("");
+        content.append(String.format("<span class=\"MWebBreadcrumbPrefix %s\">%s</span>", customClasses, MText.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, MText.getXhtmlEscapedString(viewBreadcrumbs.get(t))));
+            }
+            else {
+                content.append(String.format("<span class=\"MWebBreadcrumbLastItem %s\">%s</span>", customClasses, MText.getXhtmlEscapedString(viewBreadcrumbs.get(t))));
+            }
+        }
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '%s'; }", this.getId(), this.getId(), MText.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/attic/web/ui/MWebBrowserPage.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebBrowserPage.java
new file mode 100644 (file)
index 0000000..783a72c
--- /dev/null
@@ -0,0 +1,422 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.MInformation;
+import com.marcozanon.macaco.MObject;
+import com.marcozanon.macaco.text.MText;
+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 Object 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(Object lastViewThreadReturnValue) {
+        this.lastViewThreadReturnValue = lastViewThreadReturnValue;
+    }
+
+    protected Object getLastViewThreadReturnValueReference() {
+        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(Object 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';", MText.getJavascriptEscapedString(url)));
+    }
+
+    /* Refresh */
+
+    protected void refresh() throws MResponseWebException {
+        this.resetSecurityId();
+        //
+        String cssSource = MText.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\" />", MText.getXhtmlEscapedString(this.getAuthor())) + NL);
+        content.append(String.format("        <meta name=\"generator\" content=\"%s\" />", MText.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, MText.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, MText.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/attic/web/ui/MWebCellWidget.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebCellWidget.java
new file mode 100644 (file)
index 0000000..9d4f703
--- /dev/null
@@ -0,0 +1,160 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MWebCheckBox.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebCheckBox.java
new file mode 100644 (file)
index 0000000..b57722c
--- /dev/null
@@ -0,0 +1,172 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.text.MText;
+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) {
+        if (null == checkedMode) {
+            throw new IllegalArgumentException("Invalid 'checkedMode': null.");
+        }
+        //
+        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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.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/attic/web/ui/MWebColor.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebColor.java
new file mode 100644 (file)
index 0000000..aa886ff
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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 getCssValue() {
+        return "#" + String.format("%6H", this.getValue()).replace(" ", "0");
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/attic/web/ui/MWebComboBox.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebComboBox.java
new file mode 100644 (file)
index 0000000..1e8a527
--- /dev/null
@@ -0,0 +1,342 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.text.MText;
+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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onBlurFunction), MText.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(), MText.getJavascriptEscapedString(this.getItemsReference().get(itemKey)), MText.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/attic/web/ui/MWebDateBox.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebDateBox.java
new file mode 100644 (file)
index 0000000..d904d8e
--- /dev/null
@@ -0,0 +1,111 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.conversion.MDateConverter;
+import com.marcozanon.macaco.conversion.MFormatConversionException;
+import com.marcozanon.macaco.text.MText;
+import java.util.Date;
+
+public class MWebDateBox extends MWebTextBox {
+
+    protected MDateConverter dateConverter = null;
+
+    /* */
+
+    public MWebDateBox(MWebApplicationContext applicationContext, MDateConverter dateConverter) {
+        super(applicationContext);
+        //
+        if (null == dateConverter) {
+            throw new IllegalArgumentException("Invalid 'dateConverter': null.");
+        }
+        //
+        this.dateConverter = dateConverter;
+    }
+
+    public MWebDateBox(MWebApplicationContext applicationContext, MDateConverter dateConverter, String text) {
+        this(applicationContext, dateConverter);
+        //
+        this.setText(text);
+    }
+
+    public MWebDateBox(MWebApplicationContext applicationContext, MDateConverter dateConverter, Date date) {
+        this(applicationContext, dateConverter);
+        //
+        this.setDate(date);
+    }
+
+    /* Date converter */
+
+    protected MDateConverter getDateConverterReference() {
+        return this.dateConverter;
+    }
+
+    public MDateConverter getDateConverter() {
+        return this.getDateConverterReference().clone();
+    }
+
+    /* Date conversion */
+
+    public void setDate(Date date) {
+        if (null == date) {
+            this.setText("");
+        }
+        else {
+            try {
+                this.setText(this.getDateConverterReference().getStringFromDate(date));
+            }
+            catch (MFormatConversionException exception) { // cannot happen
+            }
+        }
+    }
+
+    public Date getDate() throws MFormatConversionException {
+        Date date = null;
+        String text = this.getText();
+        if (!"".equals(text)) {
+            return this.getDateConverterReference().getDateFromString(text);
+        }
+        return date;
+    }
+
+    /* Validation */
+
+    public void validate() throws MValidationWebException {
+        String text = this.getText();
+        if (!"".equals(text)) {
+            try {
+                MDateConverter dateConverter = this.getDateConverterReference();
+                this.setText(dateConverter.getStringFromDate(dateConverter.getDateFromString(text)));
+            }
+            catch (MFormatConversionException 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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onBlurFunction), this.getId()));
+        //
+        super.refresh();
+        //
+        this.refreshText();
+        this.refreshTextAlignment(true);
+        this.refreshMaximumLength();
+        this.refreshEnabledMode();
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/attic/web/ui/MWebDirectWidget.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebDirectWidget.java
new file mode 100644 (file)
index 0000000..bdc36af
--- /dev/null
@@ -0,0 +1,17 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+public abstract class MWebDirectWidget extends MWebDisplayWidget {
+
+    /* */
+
+    public MWebDirectWidget(MWebApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/attic/web/ui/MWebDisplayWidget.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebDisplayWidget.java
new file mode 100644 (file)
index 0000000..f0c12ed
--- /dev/null
@@ -0,0 +1,927 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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().getCssValue();
+    }
+
+    /* 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().getCssValue();
+    }
+
+    /* 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().getCssValue();
+    }
+
+    /* 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().getCssValue();
+    }
+
+    /* 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().getCssValue();
+    }
+
+    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().getCssValue();
+    }
+
+    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().getCssValue();
+    }
+
+    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().getCssValue();
+    }
+
+    /* 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().getCssValue();
+    }
+
+    /* 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().getCssValue();
+    }
+
+    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().getCssValue();
+    }
+
+    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().getCssValue();
+    }
+
+    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().getCssValue();
+    }
+
+    /* 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/attic/web/ui/MWebDownloader.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebDownloader.java
new file mode 100644 (file)
index 0000000..b651ecb
--- /dev/null
@@ -0,0 +1,58 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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.getJsonValue();
+        //
+        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/attic/web/ui/MWebException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebException.java
new file mode 100644 (file)
index 0000000..c01f894
--- /dev/null
@@ -0,0 +1,33 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MWebExtendedTextBox.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebExtendedTextBox.java
new file mode 100644 (file)
index 0000000..7dc41f8
--- /dev/null
@@ -0,0 +1,46 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.text.MText;
+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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onBlurFunction), this.getId()));
+        //
+        super.refresh();
+        //
+        this.refreshText();
+        this.refreshTextAlignment(true);
+        this.refreshMaximumLength();
+        this.refreshEnabledMode();
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/attic/web/ui/MWebFont.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebFont.java
new file mode 100644 (file)
index 0000000..9d3407c
--- /dev/null
@@ -0,0 +1,158 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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[] getCssValue() {
+        String[] formattedValue = new String[2];
+        formattedValue[0] = this.getStyle().toString() + " " + this.getVariant().toString() + " " + this.getWeight().toString() + " " + this.getSizeReference().getCssValue() + " " + this.getFamily();
+        formattedValue[1] = this.getDecoration().toString();
+        return formattedValue;
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/attic/web/ui/MWebGridLayout.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebGridLayout.java
new file mode 100644 (file)
index 0000000..dc34193
--- /dev/null
@@ -0,0 +1,185 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.text.MText;
+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 = MText.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(), MText.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/attic/web/ui/MWebGridLayoutCell.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebGridLayoutCell.java
new file mode 100644 (file)
index 0000000..b4b69b1
--- /dev/null
@@ -0,0 +1,211 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MWebImage.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebImage.java
new file mode 100644 (file)
index 0000000..3dd2196
--- /dev/null
@@ -0,0 +1,157 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.text.MText;
+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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onClickFunction), MText.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(), MText.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(), MText.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/attic/web/ui/MWebImageButton.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebImageButton.java
new file mode 100644 (file)
index 0000000..e18124e
--- /dev/null
@@ -0,0 +1,308 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.text.MText;
+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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onClickFunction), this.getId(), MText.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(), MText.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(), MText.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/attic/web/ui/MWebLabel.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebLabel.java
new file mode 100644 (file)
index 0000000..51b900a
--- /dev/null
@@ -0,0 +1,179 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.text.MText;
+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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onClickFunction), MText.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(), MText.getJavascriptEscapedString(MText.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/attic/web/ui/MWebMeasure.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebMeasure.java
new file mode 100644 (file)
index 0000000..8a94e00
--- /dev/null
@@ -0,0 +1,76 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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 getCssValue() {
+        return this.getNumber() + this.getUnit().toString();
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/attic/web/ui/MWebMessage.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebMessage.java
new file mode 100644 (file)
index 0000000..a43182a
--- /dev/null
@@ -0,0 +1,130 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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 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
+        if (!jsonMessage.containsKey("widgetId")) {
+            throw new MMessagingWebException("Invalid 'message': no widget id key.");
+        }
+        try {
+            this.widgetId = ((MJsonString)jsonMessage.getValue("widgetId")).getValue();
+        }
+        catch (ClassCastException exception) {
+            throw new MMessagingWebException("Invalid 'message': invalid widget id."); // no need to propagate exception
+        }
+        // parse event component
+        if (!jsonMessage.containsKey("event")) {
+            throw new MMessagingWebException("Invalid 'message': no event key.");
+        }
+        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
+        }
+        // parse parameters component
+        if (!jsonMessage.containsKey("parameters")) {
+            throw new MMessagingWebException("Invalid 'message': no parameters key.");
+        }
+        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
+        }
+    }
+
+    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.getParametersReference().get(parameterKey));
+                tmpMessageParameters.setValue(parameterKey, tmpString);
+            }
+            tmpMessage.setValue("parameters", tmpMessageParameters);
+            //
+            return new MWebMessage(tmpMessage.getJsonValue());
+        }
+        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/attic/web/ui/MWebNumberBox.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebNumberBox.java
new file mode 100644 (file)
index 0000000..534b917
--- /dev/null
@@ -0,0 +1,111 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.conversion.MFormatConversionException;
+import com.marcozanon.macaco.conversion.MNumberConverter;
+import com.marcozanon.macaco.text.MText;
+import java.math.BigDecimal;
+
+public class MWebNumberBox extends MWebTextBox {
+
+    protected MNumberConverter numberConverter = null;
+
+    /* */
+
+    public MWebNumberBox(MWebApplicationContext applicationContext, MNumberConverter numberConverter) {
+        super(applicationContext);
+        //
+        if (null == numberConverter) {
+            throw new IllegalArgumentException("Invalid 'numberConverter': null.");
+        }
+        //
+        this.numberConverter = numberConverter;
+    }
+
+    public MWebNumberBox(MWebApplicationContext applicationContext, MNumberConverter numberConverter, String text) {
+        this(applicationContext, numberConverter);
+        //
+        this.setText(text);
+    }
+
+    public MWebNumberBox(MWebApplicationContext applicationContext, MNumberConverter numberConverter, BigDecimal number) {
+        this(applicationContext, numberConverter);
+        //
+        this.setNumber(number);
+    }
+
+    /* Number converter */
+
+    protected MNumberConverter getNumberConverterReference() {
+        return this.numberConverter;
+    }
+
+    public MNumberConverter getNumberConverter() {
+        return this.getNumberConverterReference().clone();
+    }
+
+    /* Number conversion */
+
+    public void setNumber(BigDecimal number) {
+        if (null == number) {
+            this.setText("");
+        }
+        else {
+            try {
+                this.setText(this.getNumberConverterReference().getStringFromNumber(number));
+            }
+            catch (MFormatConversionException exception) { // cannot happen
+            }
+        }
+    }
+
+    public BigDecimal getNumber() throws MFormatConversionException {
+        BigDecimal number = null;
+        String text = this.getText();
+        if (!"".equals(text)) {
+            return this.getNumberConverterReference().getNumberFromString(text);
+        }
+        return number;
+    }
+
+    /* Validation */
+
+    public void validate() throws MValidationWebException {
+        String text = this.getText();
+        if (!"".equals(text)) {
+            try {
+                MNumberConverter numberConverter = this.getNumberConverterReference();
+                this.setText(numberConverter.getStringFromNumber(numberConverter.getNumberFromString(text)));
+            }
+            catch (MFormatConversionException 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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onBlurFunction), this.getId()));
+        //
+        super.refresh();
+        //
+        this.refreshText();
+        this.refreshTextAlignment(true);
+        this.refreshMaximumLength();
+        this.refreshEnabledMode();
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/attic/web/ui/MWebPasswordBox.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebPasswordBox.java
new file mode 100644 (file)
index 0000000..4b4276f
--- /dev/null
@@ -0,0 +1,45 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.text.MText;
+
+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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onBlurFunction), this.getId()));
+        //
+        super.refresh();
+        //
+        this.refreshText();
+        this.refreshTextAlignment(true);
+        this.refreshMaximumLength();
+        this.refreshEnabledMode();
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/attic/web/ui/MWebRuntimeException.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebRuntimeException.java
new file mode 100644 (file)
index 0000000..53397c3
--- /dev/null
@@ -0,0 +1,33 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MWebSimpleTextBox.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebSimpleTextBox.java
new file mode 100644 (file)
index 0000000..6d04076
--- /dev/null
@@ -0,0 +1,45 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.text.MText;
+
+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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onBlurFunction), this.getId()));
+        //
+        super.refresh();
+        //
+        this.refreshText();
+        this.refreshTextAlignment(true);
+        this.refreshMaximumLength();
+        this.refreshEnabledMode();
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/attic/web/ui/MWebTable.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebTable.java
new file mode 100644 (file)
index 0000000..f5eaed8
--- /dev/null
@@ -0,0 +1,737 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.text.MText;
+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 = MText.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(), MText.getJavascriptEscapedString(columnKey));
+            }
+            content.append(String.format("<th class=\"MWebTableColumnHeaderCell %s\" onclick=\"%s\" id=\"%s\"></th>", customClasses, MText.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(), MText.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, MText.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(), MText.getJavascriptEscapedString(primaryKeyValue), MText.getJavascriptEscapedString(columnKey));
+                content.append(String.format("<td class=\"MWebTableCell %s\" onclick=\"%s\" id=\"%s\"></td>", customClasses, MText.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(), MText.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/attic/web/ui/MWebTableCell.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebTableCell.java
new file mode 100644 (file)
index 0000000..b628c8a
--- /dev/null
@@ -0,0 +1,172 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.text.MText;
+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 = MText.getXhtmlEscapedString(text);
+        }
+        else {
+            content = String.format("<img src=\"%s\" alt=\"%s\" />", MText.getXhtmlEscapedString(imageSource), MText.getXhtmlEscapedString(text));
+        }
+        if (null != externalLinkPrefix) {
+            content = String.format("<a href=\"%s\">%s</a>", MText.getXhtmlEscapedString(externalLinkPrefix + text), content);
+        }
+        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '%s'; }", this.getId(), this.getId(), MText.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/attic/web/ui/MWebTextBox.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebTextBox.java
new file mode 100644 (file)
index 0000000..339cb03
--- /dev/null
@@ -0,0 +1,260 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.text.MText;
+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 Integer maximumLength = 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();
+    }
+
+    /* Maximum length */
+
+    public void setMaximumLength(Integer maximumLength) {
+        this.setMaximumLength(maximumLength, true);
+    }
+
+    protected void setMaximumLength(Integer maximumLength, boolean refreshMode) {
+        if ((null != maximumLength) && (0 > maximumLength)) {
+            throw new IllegalArgumentException("Invalid 'maximumLength': negative number.");
+        }
+        //
+        this.maximumLength = maximumLength;
+        //
+        if (refreshMode) {
+            try {
+                this.refreshMaximumLength();
+            }
+            catch (MNoBrowserPageWebException exception) {
+            }
+            catch (MNoViewWebException exception) {
+            }
+            catch (MNoWidgetIdWebException exception) {
+            }
+            catch (MResponseWebException exception) {
+            }
+        }
+    }
+
+    public Integer getMaximumLength() {
+        return this.maximumLength;
+    }
+
+    public String getFormattedMaximumLength() throws MNullPropertyWebException {
+        if (null == this.getMaximumLength()) {
+            throw new MNullPropertyWebException("Invalid maximum length: property null.");
+        }
+        return this.getMaximumLength().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(), MText.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 refreshMaximumLength() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
+        this.checkPresence();
+        //
+        try {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').maxLength = '%s'; }", this.getId(), this.getId(), this.getFormattedMaximumLength()));
+        }
+        catch (MNullPropertyWebException exception) {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').maxLength = 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/attic/web/ui/MWebUploader.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebUploader.java
new file mode 100644 (file)
index 0000000..86fdb93
--- /dev/null
@@ -0,0 +1,154 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.text.MText;
+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 = MText.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(), MText.getJavascriptEscapedString(customClasses), this.getId(), MText.getJavascriptEscapedString(customClasses), MText.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/attic/web/ui/MWebVerticalMenu.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebVerticalMenu.java
new file mode 100644 (file)
index 0000000..a83abb7
--- /dev/null
@@ -0,0 +1,289 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.text.MText;
+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 = MText.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, MText.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(), MText.getJavascriptEscapedString(itemKey));
+                itemContent.append(String.format("<td class=\"%s %s\" onclick=\"%s\" id=\"%s\"><img class=\"MWebVerticalMenuImage %s\" src=\"%s\" alt=\"\" /></td>", imageClass, customClasses, MText.getXhtmlEscapedString(onItemSelectionFunction), this.getId() + MText.getXhtmlEscapedString(itemKey) + "-imageCell", customClasses, MText.getXhtmlEscapedString(imageSource)));
+                itemContent.append(String.format("<td class=\"%s %s\" onclick=\"%s\" id=\"%s\">%s</td>", textClass, customClasses, MText.getXhtmlEscapedString(onItemSelectionFunction), this.getId() + MText.getXhtmlEscapedString(itemKey) + "-textCell", MText.getXhtmlEscapedString(text)));
+            }
+            else {
+                itemContent.append(String.format("<td class=\"MWebVerticalMenuSeparatorCell %s\" id=\"%s\" colspan=\"2\"></td>", customClasses, this.getId() + MText.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() + MText.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() + MText.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(), MText.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/attic/web/ui/MWebVerticalMenuItem.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebVerticalMenuItem.java
new file mode 100644 (file)
index 0000000..c0e95f0
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MWebView.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebView.java
new file mode 100644 (file)
index 0000000..76c7d4f
--- /dev/null
@@ -0,0 +1,425 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.MObject;
+import com.marcozanon.macaco.text.MText;
+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 Object 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().getLastViewThreadReturnValueReference();
+    }
+
+    public void close(Object 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 getDownloaderCount() {
+        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';", MText.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/attic/web/ui/MWebWidget.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebWidget.java
new file mode 100644 (file)
index 0000000..80f5933
--- /dev/null
@@ -0,0 +1,88 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.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/attic/web/ui/MWebWysiwygBox.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebWysiwygBox.java
new file mode 100644 (file)
index 0000000..a4d3bba
--- /dev/null
@@ -0,0 +1,200 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.text.MText;
+import com.marcozanon.macaco.text.MXhtmlUnsafeStringTextException;
+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 = MText.getXhtmlSafeString(text);
+        }
+        catch (MXhtmlUnsafeStringTextException 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 = MText.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(), MText.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(), MText.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(), MText.getJavascriptEscapedString(this.getText())));
+        }
+        else {
+            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '%s'; }", this.getId(), this.getId(), MText.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 = MText.getXhtmlSafeString(text);
+            }
+            catch (MXhtmlUnsafeStringTextException 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/attic/web/ui/MWebXhtmlLabel.java b/src/java/com/marcozanon/macaco/attic/web/ui/MWebXhtmlLabel.java
new file mode 100644 (file)
index 0000000..10eda05
--- /dev/null
@@ -0,0 +1,49 @@
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.attic.web.ui;
+
+import com.marcozanon.macaco.text.MText;
+
+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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onClickFunction), MText.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(), MText.getJavascriptEscapedString(MText.getXhtmlNumericEntitiesString(this.getText()))));
+    }
+
+}
diff --git a/src/java/com/marcozanon/macaco/configuration/MConfiguration.java b/src/java/com/marcozanon/macaco/configuration/MConfiguration.java
deleted file mode 100644 (file)
index 7c875f2..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.configuration;
-
-import com.marcozanon.macaco.MInformation;
-import com.marcozanon.macaco.MObject;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStreamReader;
-import java.io.IOException;
-import java.io.LineNumberReader;
-import java.io.UnsupportedEncodingException;
-import java.util.LinkedHashMap;
-
-public class MConfiguration extends MObject {
-
-    protected LinkedHashMap<String, String> parameters = new LinkedHashMap<String, String>();
-
-    /* */
-
-    public MConfiguration(String file) throws MFileParsingConfigurationException {
-        super();
-        //
-        this.parseFile(file);
-    }
-
-    /* Parameters */
-
-    protected LinkedHashMap<String, String> getParametersReference() {
-        return this.parameters;
-    }
-
-    /* Strings management */
-
-    public void parseFile(String file) throws MFileParsingConfigurationException {
-        if ((null == file) || ("".equals(file))) {
-            throw new IllegalArgumentException("Invalid 'file': null or empty.");
-        }
-        //
-        LineNumberReader buffer = null;
-        try {
-            buffer = new LineNumberReader(new InputStreamReader(new FileInputStream(file), MInformation.TEXT_ENCODING));
-        }
-        catch (FileNotFoundException exception) {
-            throw new MFileParsingConfigurationException("Could not open file.", exception);
-        }
-        catch (UnsupportedEncodingException exception) { // cannot happen
-        }
-        String line = null;
-        synchronized (this.getParametersReference()) {
-            while (true) {
-                try {
-                    line = buffer.readLine();
-                }
-                catch (IOException exception) {
-                    throw new MFileParsingConfigurationException("Could not read file.", exception);
-                }
-                if (null == line) {
-                    break;
-                }
-                line = line.trim();
-                if ((line.startsWith("#")) || (line.startsWith(";")) || ("".equals(line))) {
-                    continue;
-                }
-                else {
-                    int a = line.indexOf("=");
-                    if (-1 == a) {
-                        throw new MFileParsingConfigurationException(String.format("Invalid line: %s: string malformed.", buffer.getLineNumber()));
-                    }
-                    String key = line.substring(0, a).trim();
-                    String value = line.substring(a + 1).trim();
-                    if (this.getParametersReference().containsKey(key)) {
-                        throw new MFileParsingConfigurationException(String.format("Invalid line: %s: duplicated key: %s.", buffer.getLineNumber(), key));
-                    }
-                    this.getParametersReference().put(key, value);
-                }
-            }
-        }
-        try {
-            buffer.close();
-        }
-        catch (IOException exception) {
-            throw new MFileParsingConfigurationException("Could not close file.", exception);
-        }
-    }
-
-    public void clear() {
-        synchronized (this.getParametersReference()) {
-            this.getParametersReference().clear();
-        }
-    }
-
-    public String getValue(String key) throws MValueNotFoundConfigurationException {
-        if ((null == key) || ("".equals(key))) {
-            throw new IllegalArgumentException("Invalid 'key': null or empty.");
-        }
-        //
-        if (!this.getParametersReference().containsKey(key)) {
-            throw new MValueNotFoundConfigurationException(String.format("Invalid 'key': %s: not available.", key));
-        }
-        return this.getParametersReference().get(key);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/configuration/MConfigurationException.java b/src/java/com/marcozanon/macaco/configuration/MConfigurationException.java
deleted file mode 100644 (file)
index b5fea50..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.configuration;
-
-import com.marcozanon.macaco.MException;
-
-public abstract class MConfigurationException extends MException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MConfigurationException() {
-        super();
-    }
-
-    public MConfigurationException(String message) {
-        super(message);
-    }
-
-    public MConfigurationException(Throwable error) {
-        super(error);
-    }
-
-    public MConfigurationException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/configuration/MFileParsingConfigurationException.java b/src/java/com/marcozanon/macaco/configuration/MFileParsingConfigurationException.java
deleted file mode 100644 (file)
index da41f22..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.configuration;
-
-public class MFileParsingConfigurationException extends MConfigurationException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MFileParsingConfigurationException() {
-        super();
-    }
-
-    public MFileParsingConfigurationException(String message) {
-        super(message);
-    }
-
-    public MFileParsingConfigurationException(Throwable error) {
-        super(error);
-    }
-
-    public MFileParsingConfigurationException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/configuration/MValueNotFoundConfigurationException.java b/src/java/com/marcozanon/macaco/configuration/MValueNotFoundConfigurationException.java
deleted file mode 100644 (file)
index 93707bc..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.configuration;
-
-public class MValueNotFoundConfigurationException extends MConfigurationException {
-
-    private static final long serialVersionUID = 0L;
-
-    /* */
-
-    public MValueNotFoundConfigurationException() {
-        super();
-    }
-
-    public MValueNotFoundConfigurationException(String message) {
-        super(message);
-    }
-
-    public MValueNotFoundConfigurationException(Throwable error) {
-        super(error);
-    }
-
-    public MValueNotFoundConfigurationException(String message, Throwable error) {
-        super(message, error);
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MApplicationServletWebException.java b/src/java/com/marcozanon/macaco/web/ui/MApplicationServletWebException.java
deleted file mode 100644 (file)
index 7918140..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index a26485f..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 7918ceb..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 720b9af..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 8d28b66..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 1e3d3ca..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index f964fe7..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 3bf0eed..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index e0a410b..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 500afbf..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 939d4da..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index a0f4b19..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 61c9e11..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index eec7cb8..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index a1b96e0..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index bd4b8f3..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index b75ce7a..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index db74d80..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 6b18710..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 9ee9c1e..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 9382bdf..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index eeeed24..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 6d60460..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 30f95de..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index c5275e9..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 7889949..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.MInformation;
-import com.marcozanon.macaco.MObject;
-import com.marcozanon.macaco.text.MText;
-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, MText.getJavascriptEscapedString(MText.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, MText.getJavascriptEscapedString(MText.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
deleted file mode 100644 (file)
index 5b27f15..0000000
+++ /dev/null
@@ -1,359 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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) {
-            try {
-                MJsonObject returnValue = null;
-                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);
-                responseContent = returnValue.getJsonValue().getBytes(MInformation.TEXT_ENCODING);
-            }
-            catch (MInvalidValueJsonException exception) { // cannot happen
-            }
-        }
-        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) {
-                    try {
-                        MJsonObject returnValue = null;
-                        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);
-                        responseContent = returnValue.getJsonValue().getBytes(MInformation.TEXT_ENCODING);
-                    }
-                    catch (MInvalidValueJsonException exception) { // should not happen
-                    }
-                }
-                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
deleted file mode 100644 (file)
index c063496..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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 getCssValue() {
-        return this.getWidthReference().getCssValue() + " " + this.getStyle().toString() + " " + this.getColorReference().getCssValue();
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebBreadcrumbs.java b/src/java/com/marcozanon/macaco/web/ui/MWebBreadcrumbs.java
deleted file mode 100644 (file)
index f00949f..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.text.MText;
-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 = MText.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(), MText.getJavascriptEscapedString(customClasses), this.getId()));
-        //
-        super.refresh();
-        //
-        StringBuilder content = new StringBuilder("");
-        content.append(String.format("<span class=\"MWebBreadcrumbPrefix %s\">%s</span>", customClasses, MText.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, MText.getXhtmlEscapedString(viewBreadcrumbs.get(t))));
-            }
-            else {
-                content.append(String.format("<span class=\"MWebBreadcrumbLastItem %s\">%s</span>", customClasses, MText.getXhtmlEscapedString(viewBreadcrumbs.get(t))));
-            }
-        }
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '%s'; }", this.getId(), this.getId(), MText.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
deleted file mode 100644 (file)
index 59368e4..0000000
+++ /dev/null
@@ -1,422 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.MInformation;
-import com.marcozanon.macaco.MObject;
-import com.marcozanon.macaco.text.MText;
-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 Object 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(Object lastViewThreadReturnValue) {
-        this.lastViewThreadReturnValue = lastViewThreadReturnValue;
-    }
-
-    protected Object getLastViewThreadReturnValueReference() {
-        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(Object 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';", MText.getJavascriptEscapedString(url)));
-    }
-
-    /* Refresh */
-
-    protected void refresh() throws MResponseWebException {
-        this.resetSecurityId();
-        //
-        String cssSource = MText.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\" />", MText.getXhtmlEscapedString(this.getAuthor())) + NL);
-        content.append(String.format("        <meta name=\"generator\" content=\"%s\" />", MText.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, MText.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, MText.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
deleted file mode 100644 (file)
index 2df7704..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 5a7f744..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.text.MText;
-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) {
-        if (null == checkedMode) {
-            throw new IllegalArgumentException("Invalid 'checkedMode': null.");
-        }
-        //
-        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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.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
deleted file mode 100644 (file)
index e621adc..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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 getCssValue() {
-        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
deleted file mode 100644 (file)
index 92add70..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.text.MText;
-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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onBlurFunction), MText.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(), MText.getJavascriptEscapedString(this.getItemsReference().get(itemKey)), MText.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
deleted file mode 100644 (file)
index a8a3454..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.conversion.MDateConverter;
-import com.marcozanon.macaco.conversion.MFormatConversionException;
-import com.marcozanon.macaco.text.MText;
-import java.util.Date;
-
-public class MWebDateBox extends MWebTextBox {
-
-    protected MDateConverter dateConverter = null;
-
-    /* */
-
-    public MWebDateBox(MWebApplicationContext applicationContext, MDateConverter dateConverter) {
-        super(applicationContext);
-        //
-        if (null == dateConverter) {
-            throw new IllegalArgumentException("Invalid 'dateConverter': null.");
-        }
-        //
-        this.dateConverter = dateConverter;
-    }
-
-    public MWebDateBox(MWebApplicationContext applicationContext, MDateConverter dateConverter, String text) {
-        this(applicationContext, dateConverter);
-        //
-        this.setText(text);
-    }
-
-    public MWebDateBox(MWebApplicationContext applicationContext, MDateConverter dateConverter, Date date) {
-        this(applicationContext, dateConverter);
-        //
-        this.setDate(date);
-    }
-
-    /* Date converter */
-
-    protected MDateConverter getDateConverterReference() {
-        return this.dateConverter;
-    }
-
-    public MDateConverter getDateConverter() {
-        return this.getDateConverterReference().clone();
-    }
-
-    /* Date conversion */
-
-    public void setDate(Date date) {
-        if (null == date) {
-            this.setText("");
-        }
-        else {
-            try {
-                this.setText(this.getDateConverterReference().getStringFromDate(date));
-            }
-            catch (MFormatConversionException exception) { // cannot happen
-            }
-        }
-    }
-
-    public Date getDate() throws MFormatConversionException {
-        Date date = null;
-        String text = this.getText();
-        if (!"".equals(text)) {
-            return this.getDateConverterReference().getDateFromString(text);
-        }
-        return date;
-    }
-
-    /* Validation */
-
-    public void validate() throws MValidationWebException {
-        String text = this.getText();
-        if (!"".equals(text)) {
-            try {
-                MDateConverter dateConverter = this.getDateConverterReference();
-                this.setText(dateConverter.getStringFromDate(dateConverter.getDateFromString(text)));
-            }
-            catch (MFormatConversionException 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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onBlurFunction), this.getId()));
-        //
-        super.refresh();
-        //
-        this.refreshText();
-        this.refreshTextAlignment(true);
-        this.refreshMaximumLength();
-        this.refreshEnabledMode();
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebDirectWidget.java b/src/java/com/marcozanon/macaco/web/ui/MWebDirectWidget.java
deleted file mode 100644 (file)
index 7d8c057..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 54bb9d8..0000000
+++ /dev/null
@@ -1,927 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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().getCssValue();
-    }
-
-    /* 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().getCssValue();
-    }
-
-    /* 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().getCssValue();
-    }
-
-    /* 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().getCssValue();
-    }
-
-    /* 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().getCssValue();
-    }
-
-    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().getCssValue();
-    }
-
-    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().getCssValue();
-    }
-
-    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().getCssValue();
-    }
-
-    /* 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().getCssValue();
-    }
-
-    /* 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().getCssValue();
-    }
-
-    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().getCssValue();
-    }
-
-    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().getCssValue();
-    }
-
-    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().getCssValue();
-    }
-
-    /* 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
deleted file mode 100644 (file)
index a163088..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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.getJsonValue();
-        //
-        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
deleted file mode 100644 (file)
index 3daaf06..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 7e5dd97..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.text.MText;
-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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onBlurFunction), this.getId()));
-        //
-        super.refresh();
-        //
-        this.refreshText();
-        this.refreshTextAlignment(true);
-        this.refreshMaximumLength();
-        this.refreshEnabledMode();
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebFont.java b/src/java/com/marcozanon/macaco/web/ui/MWebFont.java
deleted file mode 100644 (file)
index dd6f1c1..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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[] getCssValue() {
-        String[] formattedValue = new String[2];
-        formattedValue[0] = this.getStyle().toString() + " " + this.getVariant().toString() + " " + this.getWeight().toString() + " " + this.getSizeReference().getCssValue() + " " + 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
deleted file mode 100644 (file)
index 5b8bfee..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.text.MText;
-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 = MText.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(), MText.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
deleted file mode 100644 (file)
index 2b556b6..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 6688ddf..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.text.MText;
-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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onClickFunction), MText.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(), MText.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(), MText.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
deleted file mode 100644 (file)
index e01c168..0000000
+++ /dev/null
@@ -1,308 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.text.MText;
-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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onClickFunction), this.getId(), MText.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(), MText.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(), MText.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
deleted file mode 100644 (file)
index f589ce8..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.text.MText;
-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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onClickFunction), MText.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(), MText.getJavascriptEscapedString(MText.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
deleted file mode 100644 (file)
index 6d56825..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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 getCssValue() {
-        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
deleted file mode 100644 (file)
index 5e3a768..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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 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
-        if (!jsonMessage.containsKey("widgetId")) {
-            throw new MMessagingWebException("Invalid 'message': no widget id key.");
-        }
-        try {
-            this.widgetId = ((MJsonString)jsonMessage.getValue("widgetId")).getValue();
-        }
-        catch (ClassCastException exception) {
-            throw new MMessagingWebException("Invalid 'message': invalid widget id."); // no need to propagate exception
-        }
-        // parse event component
-        if (!jsonMessage.containsKey("event")) {
-            throw new MMessagingWebException("Invalid 'message': no event key.");
-        }
-        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
-        }
-        // parse parameters component
-        if (!jsonMessage.containsKey("parameters")) {
-            throw new MMessagingWebException("Invalid 'message': no parameters key.");
-        }
-        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
-        }
-    }
-
-    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.getParametersReference().get(parameterKey));
-                tmpMessageParameters.setValue(parameterKey, tmpString);
-            }
-            tmpMessage.setValue("parameters", tmpMessageParameters);
-            //
-            return new MWebMessage(tmpMessage.getJsonValue());
-        }
-        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
deleted file mode 100644 (file)
index 8cdabc1..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.conversion.MFormatConversionException;
-import com.marcozanon.macaco.conversion.MNumberConverter;
-import com.marcozanon.macaco.text.MText;
-import java.math.BigDecimal;
-
-public class MWebNumberBox extends MWebTextBox {
-
-    protected MNumberConverter numberConverter = null;
-
-    /* */
-
-    public MWebNumberBox(MWebApplicationContext applicationContext, MNumberConverter numberConverter) {
-        super(applicationContext);
-        //
-        if (null == numberConverter) {
-            throw new IllegalArgumentException("Invalid 'numberConverter': null.");
-        }
-        //
-        this.numberConverter = numberConverter;
-    }
-
-    public MWebNumberBox(MWebApplicationContext applicationContext, MNumberConverter numberConverter, String text) {
-        this(applicationContext, numberConverter);
-        //
-        this.setText(text);
-    }
-
-    public MWebNumberBox(MWebApplicationContext applicationContext, MNumberConverter numberConverter, BigDecimal number) {
-        this(applicationContext, numberConverter);
-        //
-        this.setNumber(number);
-    }
-
-    /* Number converter */
-
-    protected MNumberConverter getNumberConverterReference() {
-        return this.numberConverter;
-    }
-
-    public MNumberConverter getNumberConverter() {
-        return this.getNumberConverterReference().clone();
-    }
-
-    /* Number conversion */
-
-    public void setNumber(BigDecimal number) {
-        if (null == number) {
-            this.setText("");
-        }
-        else {
-            try {
-                this.setText(this.getNumberConverterReference().getStringFromNumber(number));
-            }
-            catch (MFormatConversionException exception) { // cannot happen
-            }
-        }
-    }
-
-    public BigDecimal getNumber() throws MFormatConversionException {
-        BigDecimal number = null;
-        String text = this.getText();
-        if (!"".equals(text)) {
-            return this.getNumberConverterReference().getNumberFromString(text);
-        }
-        return number;
-    }
-
-    /* Validation */
-
-    public void validate() throws MValidationWebException {
-        String text = this.getText();
-        if (!"".equals(text)) {
-            try {
-                MNumberConverter numberConverter = this.getNumberConverterReference();
-                this.setText(numberConverter.getStringFromNumber(numberConverter.getNumberFromString(text)));
-            }
-            catch (MFormatConversionException 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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onBlurFunction), this.getId()));
-        //
-        super.refresh();
-        //
-        this.refreshText();
-        this.refreshTextAlignment(true);
-        this.refreshMaximumLength();
-        this.refreshEnabledMode();
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebPasswordBox.java b/src/java/com/marcozanon/macaco/web/ui/MWebPasswordBox.java
deleted file mode 100644 (file)
index 91a857c..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.text.MText;
-
-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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onBlurFunction), this.getId()));
-        //
-        super.refresh();
-        //
-        this.refreshText();
-        this.refreshTextAlignment(true);
-        this.refreshMaximumLength();
-        this.refreshEnabledMode();
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebRuntimeException.java b/src/java/com/marcozanon/macaco/web/ui/MWebRuntimeException.java
deleted file mode 100644 (file)
index 7b3b5a9..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index 63eba85..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.text.MText;
-
-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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onBlurFunction), this.getId()));
-        //
-        super.refresh();
-        //
-        this.refreshText();
-        this.refreshTextAlignment(true);
-        this.refreshMaximumLength();
-        this.refreshEnabledMode();
-    }
-
-}
diff --git a/src/java/com/marcozanon/macaco/web/ui/MWebTable.java b/src/java/com/marcozanon/macaco/web/ui/MWebTable.java
deleted file mode 100644 (file)
index 97cc74a..0000000
+++ /dev/null
@@ -1,737 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.text.MText;
-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 = MText.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(), MText.getJavascriptEscapedString(columnKey));
-            }
-            content.append(String.format("<th class=\"MWebTableColumnHeaderCell %s\" onclick=\"%s\" id=\"%s\"></th>", customClasses, MText.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(), MText.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, MText.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(), MText.getJavascriptEscapedString(primaryKeyValue), MText.getJavascriptEscapedString(columnKey));
-                content.append(String.format("<td class=\"MWebTableCell %s\" onclick=\"%s\" id=\"%s\"></td>", customClasses, MText.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(), MText.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
deleted file mode 100644 (file)
index 32263ca..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.text.MText;
-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 = MText.getXhtmlEscapedString(text);
-        }
-        else {
-            content = String.format("<img src=\"%s\" alt=\"%s\" />", MText.getXhtmlEscapedString(imageSource), MText.getXhtmlEscapedString(text));
-        }
-        if (null != externalLinkPrefix) {
-            content = String.format("<a href=\"%s\">%s</a>", MText.getXhtmlEscapedString(externalLinkPrefix + text), content);
-        }
-        this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '%s'; }", this.getId(), this.getId(), MText.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
deleted file mode 100644 (file)
index 6b7de1f..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.text.MText;
-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 Integer maximumLength = 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();
-    }
-
-    /* Maximum length */
-
-    public void setMaximumLength(Integer maximumLength) {
-        this.setMaximumLength(maximumLength, true);
-    }
-
-    protected void setMaximumLength(Integer maximumLength, boolean refreshMode) {
-        if ((null != maximumLength) && (0 > maximumLength)) {
-            throw new IllegalArgumentException("Invalid 'maximumLength': negative number.");
-        }
-        //
-        this.maximumLength = maximumLength;
-        //
-        if (refreshMode) {
-            try {
-                this.refreshMaximumLength();
-            }
-            catch (MNoBrowserPageWebException exception) {
-            }
-            catch (MNoViewWebException exception) {
-            }
-            catch (MNoWidgetIdWebException exception) {
-            }
-            catch (MResponseWebException exception) {
-            }
-        }
-    }
-
-    public Integer getMaximumLength() {
-        return this.maximumLength;
-    }
-
-    public String getFormattedMaximumLength() throws MNullPropertyWebException {
-        if (null == this.getMaximumLength()) {
-            throw new MNullPropertyWebException("Invalid maximum length: property null.");
-        }
-        return this.getMaximumLength().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(), MText.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 refreshMaximumLength() throws MNoBrowserPageWebException, MNoViewWebException, MNoWidgetIdWebException, MResponseWebException {
-        this.checkPresence();
-        //
-        try {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').maxLength = '%s'; }", this.getId(), this.getId(), this.getFormattedMaximumLength()));
-        }
-        catch (MNullPropertyWebException exception) {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').maxLength = 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/MWebUploader.java b/src/java/com/marcozanon/macaco/web/ui/MWebUploader.java
deleted file mode 100644 (file)
index cf48316..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.text.MText;
-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 = MText.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(), MText.getJavascriptEscapedString(customClasses), this.getId(), MText.getJavascriptEscapedString(customClasses), MText.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
deleted file mode 100644 (file)
index 6ae1f4f..0000000
+++ /dev/null
@@ -1,289 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.text.MText;
-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 = MText.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, MText.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(), MText.getJavascriptEscapedString(itemKey));
-                itemContent.append(String.format("<td class=\"%s %s\" onclick=\"%s\" id=\"%s\"><img class=\"MWebVerticalMenuImage %s\" src=\"%s\" alt=\"\" /></td>", imageClass, customClasses, MText.getXhtmlEscapedString(onItemSelectionFunction), this.getId() + MText.getXhtmlEscapedString(itemKey) + "-imageCell", customClasses, MText.getXhtmlEscapedString(imageSource)));
-                itemContent.append(String.format("<td class=\"%s %s\" onclick=\"%s\" id=\"%s\">%s</td>", textClass, customClasses, MText.getXhtmlEscapedString(onItemSelectionFunction), this.getId() + MText.getXhtmlEscapedString(itemKey) + "-textCell", MText.getXhtmlEscapedString(text)));
-            }
-            else {
-                itemContent.append(String.format("<td class=\"MWebVerticalMenuSeparatorCell %s\" id=\"%s\" colspan=\"2\"></td>", customClasses, this.getId() + MText.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() + MText.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() + MText.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(), MText.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
deleted file mode 100644 (file)
index 1dee092..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index d5321e3..0000000
+++ /dev/null
@@ -1,425 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.MObject;
-import com.marcozanon.macaco.text.MText;
-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 Object 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().getLastViewThreadReturnValueReference();
-    }
-
-    public void close(Object 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 getDownloaderCount() {
-        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';", MText.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
deleted file mode 100644 (file)
index 335aa3c..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-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
deleted file mode 100644 (file)
index e026693..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.text.MText;
-import com.marcozanon.macaco.text.MXhtmlUnsafeStringTextException;
-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 = MText.getXhtmlSafeString(text);
-        }
-        catch (MXhtmlUnsafeStringTextException 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 = MText.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(), MText.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(), MText.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(), MText.getJavascriptEscapedString(this.getText())));
-        }
-        else {
-            this.getApplicationContextReference().addPlainTextResponseContent(String.format("if ($('%s')) { $('%s').innerHTML = '%s'; }", this.getId(), this.getId(), MText.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 = MText.getXhtmlSafeString(text);
-            }
-            catch (MXhtmlUnsafeStringTextException 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
deleted file mode 100644 (file)
index b22c35a..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * Macaco
- * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.web.ui;
-
-import com.marcozanon.macaco.text.MText;
-
-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 = MText.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(), MText.getJavascriptEscapedString(customClasses), MText.getJavascriptEscapedString(onClickFunction), MText.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(), MText.getJavascriptEscapedString(MText.getXhtmlNumericEntitiesString(this.getText()))));
-    }
-
-}