Updated Branches:
  refs/heads/sandbox/optional [created] 676bd3863

initial Optional impl


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/676bd386
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/676bd386
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/676bd386

Branch: refs/heads/sandbox/optional
Commit: 676bd3863c5781703102b524d440d0145bb76a2a
Parents: d007c13
Author: Igor Vaynberg <[email protected]>
Authored: Mon Jan 30 22:48:57 2012 -0800
Committer: Igor Vaynberg <[email protected]>
Committed: Mon Jan 30 22:48:57 2012 -0800

----------------------------------------------------------------------
 .../wicket/ajax/markup/html/AjaxFallbackLink.java  |   17 +-
 .../org/apache/wicket/markup/html/form/Check.java  |    2 +-
 .../wicket/markup/html/form/FormComponent.java     |    5 +-
 .../org/apache/wicket/markup/html/form/Radio.java  |    3 +-
 .../apache/wicket/markup/html/tree/BaseTree.java   |    9 +-
 .../java/org/apache/wicket/MockPanelWithLink.java  |   10 +-
 .../wicket/ajax/AjaxHeaderContributionPage.java    |   13 +-
 .../wicket/ajax/AjaxHeaderContributionPage2.java   |   19 +-
 .../org/apache/wicket/ajax/DomReadyOrderPage.java  |    5 +-
 .../util/tester/apps_5/AjaxLinkClickTest.java      |    9 +-
 .../apache/wicket/util/tester/apps_6/LinkPage.java |    5 +-
 .../java/org/apache/wicket/util/lang/Optional.java |  256 +++++++++++++++
 12 files changed, 311 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/676bd386/wicket-core/src/main/java/org/apache/wicket/ajax/markup/html/AjaxFallbackLink.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/ajax/markup/html/AjaxFallbackLink.java
 
b/wicket-core/src/main/java/org/apache/wicket/ajax/markup/html/AjaxFallbackLink.java
index fe78ecb..d1af957 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/ajax/markup/html/AjaxFallbackLink.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/ajax/markup/html/AjaxFallbackLink.java
@@ -24,6 +24,7 @@ import 
org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.html.link.Link;
 import org.apache.wicket.model.IModel;
+import org.apache.wicket.util.lang.Optional;
 
 /**
  * An ajax link that will degrade to a normal request if ajax is not available 
or javascript is
@@ -139,16 +140,22 @@ public abstract class AjaxFallbackLink<T> extends Link<T> 
implements IAjaxLink
        @Override
        public final void onClick()
        {
-               onClick(null);
+               onClick((AjaxRequestTarget)null);
+       }
+
+       @Override
+       public void onClick(final AjaxRequestTarget target)
+       {
+               onClick(Optional.of(target));
        }
 
        /**
         * Callback for the onClick event. If ajax failed and this event was 
generated via a normal link
-        * the target argument will be null
+        * the target optional will contain a null
         * 
         * @param target
-        *            ajax target if this linked was invoked using ajax, null 
otherwise
+        *            ajax request target
         */
-       @Override
-       public abstract void onClick(final AjaxRequestTarget target);
+       public abstract void onClick(final Optional<AjaxRequestTarget> target);
+
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/676bd386/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Check.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Check.java 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Check.java
index 85dfb8c..3746cab 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Check.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Check.java
@@ -176,7 +176,7 @@ public class Check<T> extends LabeledWebMarkupContainer
 
                if (group.hasRawInput())
                {
-                       final String raw = group.getRawInput();
+                       final String raw = group.getRawInput().get(null);
                        if (!Strings.isEmpty(raw))
                        {
                                final String[] values = 
raw.split(FormComponent.VALUE_SEPARATOR);

http://git-wip-us.apache.org/repos/asf/wicket/blob/676bd386/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
index ec7b2f9..96aa942 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java
@@ -42,6 +42,7 @@ import org.apache.wicket.model.Model;
 import org.apache.wicket.util.convert.ConversionException;
 import org.apache.wicket.util.convert.IConverter;
 import org.apache.wicket.util.lang.Args;
+import org.apache.wicket.util.lang.Optional;
 import org.apache.wicket.util.lang.WicketObjects;
 import org.apache.wicket.util.string.StringList;
 import org.apache.wicket.util.string.StringValue;
@@ -781,9 +782,9 @@ public abstract class FormComponent<T> extends 
LabeledWebMarkupContainer
         * 
         * @return The raw form input that is stored for this formcomponent
         */
-       public final String getRawInput()
+       public final Optional<String> getRawInput()
        {
-               return NO_RAW_INPUT.equals(rawInput) ? null : rawInput;
+               return NO_RAW_INPUT.equals(rawInput) ? Optional.<String> 
ofNull() : Optional.of(rawInput);
        }
 
        /**

http://git-wip-us.apache.org/repos/asf/wicket/blob/676bd386/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Radio.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Radio.java 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Radio.java
index e4d0cab..7ec502d 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Radio.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Radio.java
@@ -169,8 +169,7 @@ public class Radio<T> extends LabeledWebMarkupContainer
                // checked attribute, first check if there was a raw input on 
the group.
                if (group.hasRawInput())
                {
-                       String rawInput = group.getRawInput();
-                       if (rawInput != null && rawInput.equals(value))
+                       if (group.getRawInput().isValueEqualTo(value))
                        {
                                tag.put("checked", "checked");
                        }

http://git-wip-us.apache.org/repos/asf/wicket/blob/676bd386/wicket-core/src/main/java/org/apache/wicket/markup/html/tree/BaseTree.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/tree/BaseTree.java 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/tree/BaseTree.java
index 4c6dd29..63f3643 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/tree/BaseTree.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/tree/BaseTree.java
@@ -35,6 +35,7 @@ import org.apache.wicket.model.IModel;
 import org.apache.wicket.request.Response;
 import org.apache.wicket.request.resource.PackageResourceReference;
 import org.apache.wicket.request.resource.ResourceReference;
+import org.apache.wicket.util.lang.Optional;
 import org.apache.wicket.util.string.Strings;
 
 /**
@@ -415,13 +416,11 @@ public abstract class BaseTree extends AbstractTree
                        {
                                private static final long serialVersionUID = 1L;
 
-                               /**
-                                * @see 
org.apache.wicket.ajax.markup.html.AjaxFallbackLink#onClick(org.apache.wicket.ajax.AjaxRequestTarget)
-                                */
                                @Override
-                               public void onClick(AjaxRequestTarget target)
+                               public void onClick(Optional<AjaxRequestTarget> 
target)
                                {
-                                       callback.onClick(target);
+                                       // FIXME OPTIONAL should not use 
getUnsafe()
+                                       callback.onClick(target.getUnsafe());
                                }
                        };
                }

http://git-wip-us.apache.org/repos/asf/wicket/blob/676bd386/wicket-core/src/test/java/org/apache/wicket/MockPanelWithLink.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/MockPanelWithLink.java 
b/wicket-core/src/test/java/org/apache/wicket/MockPanelWithLink.java
index ce20aca..1a3d69a 100644
--- a/wicket-core/src/test/java/org/apache/wicket/MockPanelWithLink.java
+++ b/wicket-core/src/test/java/org/apache/wicket/MockPanelWithLink.java
@@ -21,6 +21,7 @@ import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
 import org.apache.wicket.markup.IMarkupCacheKeyProvider;
 import org.apache.wicket.markup.IMarkupResourceStreamProvider;
 import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.util.lang.Optional;
 import org.apache.wicket.util.resource.IResourceStream;
 import org.apache.wicket.util.resource.StringResourceStream;
 
@@ -46,9 +47,9 @@ public abstract class MockPanelWithLink extends Panel
                add(new AjaxFallbackLink<Void>("link")
                {
                        @Override
-                       public void onClick(AjaxRequestTarget target)
+                       public void onClick(Optional<AjaxRequestTarget> target)
                        {
-                               MockPanelWithLink.this.onLinkClick(target);
+                               
MockPanelWithLink.this.onLinkClick(target.getUnsafe());
                        }
                });
        }
@@ -57,8 +58,9 @@ public abstract class MockPanelWithLink extends Panel
         * The callback to execute when the link is clicked.
         * 
         * @param target
-        *            the current Ajax request target. May be {@code null} if
-        *            {@link 
org.apache.wicket.util.tester.BaseWicketTester#clickLink(String, boolean 
false)} is used.
+        *            the current Ajax request target. May be {@code null} if 
{@link
+        *            
org.apache.wicket.util.tester.BaseWicketTester#clickLink(String, boolean false)}
+        *            is used.
         */
        protected abstract void onLinkClick(AjaxRequestTarget target);
 

http://git-wip-us.apache.org/repos/asf/wicket/blob/676bd386/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxHeaderContributionPage.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxHeaderContributionPage.java
 
b/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxHeaderContributionPage.java
index a7ccde9..ca6c6f0 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxHeaderContributionPage.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxHeaderContributionPage.java
@@ -19,6 +19,7 @@ package org.apache.wicket.ajax;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
 import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.util.lang.Optional;
 
 /**
  * @author jcompagner
@@ -43,13 +44,13 @@ public class AjaxHeaderContributionPage extends WebPage
                        private static final long serialVersionUID = 1L;
 
                        @Override
-                       public void onClick(AjaxRequestTarget target)
+                       public void onClick(Optional<AjaxRequestTarget> target)
                        {
-                               target.prependJavaScript("prepend();");
-                               target.add(test1);
-                               target.add(test2);
-                               target.add(test3);
-                               target.appendJavaScript("append();");
+                               target.get().prependJavaScript("prepend();");
+                               target.get().add(test1);
+                               target.get().add(test2);
+                               target.get().add(test3);
+                               target.get().appendJavaScript("append();");
                        }
                });
        }

http://git-wip-us.apache.org/repos/asf/wicket/blob/676bd386/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxHeaderContributionPage2.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxHeaderContributionPage2.java
 
b/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxHeaderContributionPage2.java
index 44c6d4f..327b9ea 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxHeaderContributionPage2.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxHeaderContributionPage2.java
@@ -19,6 +19,7 @@ package org.apache.wicket.ajax;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
 import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.util.lang.Optional;
 
 /**
  * @author jcompagner
@@ -50,16 +51,16 @@ public class AjaxHeaderContributionPage2 extends WebPage
                        private static final long serialVersionUID = 1L;
 
                        @Override
-                       public void onClick(AjaxRequestTarget target)
+                       public void onClick(Optional<AjaxRequestTarget> target)
                        {
-                               target.prependJavaScript("prepend();");
-                               target.add(test1);
-                               target.add(test2);
-                               target.add(test3);
-                               target.add(btest1);
-                               target.add(btest2);
-                               target.add(btest3);
-                               target.appendJavaScript("append();");
+                               target.get().prependJavaScript("prepend();");
+                               target.get().add(test1);
+                               target.get().add(test2);
+                               target.get().add(test3);
+                               target.get().add(btest1);
+                               target.get().add(btest2);
+                               target.get().add(btest3);
+                               target.get().appendJavaScript("append();");
                        }
                });
        }

http://git-wip-us.apache.org/repos/asf/wicket/blob/676bd386/wicket-core/src/test/java/org/apache/wicket/ajax/DomReadyOrderPage.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/ajax/DomReadyOrderPage.java 
b/wicket-core/src/test/java/org/apache/wicket/ajax/DomReadyOrderPage.java
index 4cef699..782cbc5 100644
--- a/wicket-core/src/test/java/org/apache/wicket/ajax/DomReadyOrderPage.java
+++ b/wicket-core/src/test/java/org/apache/wicket/ajax/DomReadyOrderPage.java
@@ -20,6 +20,7 @@ import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
 import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
 import org.apache.wicket.markup.html.WebPage;
 import org.apache.wicket.markup.html.internal.HtmlHeaderContainer;
+import org.apache.wicket.util.lang.Optional;
 
 /**
  * @author jcompagner
@@ -60,9 +61,9 @@ public class DomReadyOrderPage extends WebPage
                }
 
                @Override
-               public void onClick(AjaxRequestTarget target)
+               public void onClick(Optional<AjaxRequestTarget> target)
                {
-                       target.add(this);
+                       target.get().add(this);
                }
        }
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/676bd386/wicket-core/src/test/java/org/apache/wicket/util/tester/apps_5/AjaxLinkClickTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/util/tester/apps_5/AjaxLinkClickTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/util/tester/apps_5/AjaxLinkClickTest.java
index f8a8e25..b6d6aa5 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/util/tester/apps_5/AjaxLinkClickTest.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/util/tester/apps_5/AjaxLinkClickTest.java
@@ -21,6 +21,7 @@ import org.apache.wicket.WicketTestCase;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.util.lang.Optional;
 import org.junit.Before;
 
 
@@ -87,10 +88,10 @@ public class AjaxLinkClickTest extends WicketTestCase
                        private static final long serialVersionUID = 1L;
 
                        @Override
-                       public void onClick(AjaxRequestTarget target)
+                       public void onClick(Optional<AjaxRequestTarget> target)
                        {
                                linkClicked = true;
-                               ajaxRequestTarget = target;
+                               ajaxRequestTarget = target.getUnsafe();
                        }
                });
 
@@ -115,10 +116,10 @@ public class AjaxLinkClickTest extends WicketTestCase
                        private static final long serialVersionUID = 1L;
 
                        @Override
-                       public void onClick(AjaxRequestTarget target)
+                       public void onClick(Optional<AjaxRequestTarget> target)
                        {
                                linkClicked = true;
-                               ajaxRequestTarget = target;
+                               ajaxRequestTarget = target.getUnsafe();
                        }
                });
 

http://git-wip-us.apache.org/repos/asf/wicket/blob/676bd386/wicket-core/src/test/java/org/apache/wicket/util/tester/apps_6/LinkPage.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/util/tester/apps_6/LinkPage.java 
b/wicket-core/src/test/java/org/apache/wicket/util/tester/apps_6/LinkPage.java
index 9e6dc21..c129eaa 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/util/tester/apps_6/LinkPage.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/util/tester/apps_6/LinkPage.java
@@ -23,6 +23,7 @@ import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
 import org.apache.wicket.markup.html.WebPage;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.link.Link;
+import org.apache.wicket.util.lang.Optional;
 import org.apache.wicket.util.tester.WicketTester;
 
 /**
@@ -91,7 +92,7 @@ public class LinkPage extends WebPage
                        private static final long serialVersionUID = 1L;
 
                        @Override
-                       public void onClick(AjaxRequestTarget target)
+                       public void onClick(Optional<AjaxRequestTarget> target)
                        {
                                
getRequestCycle().setResponsePage(ResultPage.class);
                        }
@@ -102,7 +103,7 @@ public class LinkPage extends WebPage
                        private static final long serialVersionUID = 1L;
 
                        @Override
-                       public void onClick(AjaxRequestTarget target)
+                       public void onClick(Optional<AjaxRequestTarget> target)
                        {
                                getRequestCycle().setResponsePage(new 
ResultPage("A special label"));
                        }

http://git-wip-us.apache.org/repos/asf/wicket/blob/676bd386/wicket-util/src/main/java/org/apache/wicket/util/lang/Optional.java
----------------------------------------------------------------------
diff --git 
a/wicket-util/src/main/java/org/apache/wicket/util/lang/Optional.java 
b/wicket-util/src/main/java/org/apache/wicket/util/lang/Optional.java
new file mode 100644
index 0000000..1c33575
--- /dev/null
+++ b/wicket-util/src/main/java/org/apache/wicket/util/lang/Optional.java
@@ -0,0 +1,256 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+package org.apache.wicket.util.lang;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Iterator;
+
+/**
+ * Represents an optional value.
+ * <p>
+ * This class aids in making handling of possible {@code null} values (whether 
return values or
+ * parameter values) explicit and hopefully reduces the number of {@link 
NullPointerException}s that
+ * will be thrown.
+ * </p>
+ * <p>
+ * It also makes tracking down NPEs easier by not allowing {@code null} return 
values to be
+ * propagated as parameters to further function calls, it does it by making 
{@link #get()} throw an
+ * NPE if called on an {@link Optional} constructed with a {@code null} value.
+ * </p>
+ * <p>
+ * By supporting {@link Iterable} this class allows the developer to rewrite 
code like this: <code>
+ * if (optional.isSet()) {
+ *    optional.get().foo();
+ *    optional.get().bar();
+ *    optional.get().baz();
+ * }
+ * </code> With the following: <code>
+ * for (Value value:optional) {
+ *   value.foo();
+ *   value.bar();
+ *   value.baz();
+ * }
+ * </code> which some developers find easier to read.
+ * </p>
+ * 
+ * @author igor
+ * @param <T>
+ */
+public final class Optional<T> implements Iterable<T>, Serializable
+{
+       private static final long serialVersionUID = 1L;
+
+       private static final Optional<Void> NULL = new Optional<Void>(null);
+
+       private static final Iterator<?> EMPTY_ITERATOR = 
Collections.emptyList().iterator();
+
+       private final T value;
+
+       private Optional(T value)
+       {
+               this.value = value;
+       }
+
+       /**
+        * Gets the stored value or throws {@link NullPointerException} if the 
value is {@code null}
+        * 
+        * @throws NullPointerException
+        *             if the value is {@code null}
+        * 
+        * @return stored value
+        */
+       public T get()
+       {
+               if (value == null)
+               {
+                       throw new NullPointerException();
+               }
+               return value;
+       }
+
+       /**
+        * Gets the stored value or returns {@code defaultValue} if value is 
{@code null}
+        * 
+        * @param defaultValue
+        *            default value
+        * 
+        * @return stored value or {@code defaultValue}
+        */
+       public T get(T defaultValue)
+       {
+               if (value == null)
+               {
+                       return defaultValue;
+               }
+               return value;
+       }
+
+       /**
+        * @return {@code true} iff value is not {@code null}
+        */
+       public boolean exists()
+       {
+               return value != null;
+       }
+
+       /**
+        * @return {code true} if the store value is {@code null}
+        */
+       public boolean isNull()
+       {
+               return value == null;
+       }
+
+       /**
+        * @return {code true} if the store value is not {@code null}
+        */
+       public boolean isNotNull()
+       {
+               return value != null;
+       }
+
+       /**
+        * @return {code true} if the store value is not {@code null}
+        */
+       public boolean isSet()
+       {
+               return value != null;
+       }
+
+       /**
+        * @return {code true} if the store value is {@code null}
+        */
+       public boolean isNotSet()
+       {
+               return value == null;
+       }
+
+       @SuppressWarnings("unchecked")
+       public Iterator<T> iterator()
+       {
+               if (value == null)
+               {
+                       return (Iterator<T>)EMPTY_ITERATOR;
+               }
+               else
+               {
+                       return Collections.singleton(value).iterator();
+               }
+       }
+
+       /**
+        * Factory method for creating {@link Optional} values
+        * 
+        * @param <Z>
+        * @param value
+        * @return optional that represents the specified value
+        */
+       @SuppressWarnings("unchecked")
+       public static <Z> Optional<Z> of(Z value)
+       {
+               if (value == null)
+               {
+                       return (Optional<Z>)NULL;
+               }
+               else
+               {
+                       return new Optional<Z>(value);
+               }
+       }
+
+       /**
+        * Factory method for creating an {@link Optional} value that 
represents a {@code null}
+        * 
+        * @param <T>
+        * @return optional that represents a {@code null}
+        */
+       @SuppressWarnings("unchecked")
+       public static <Z> Optional<Z> ofNull()
+       {
+               return (Optional<Z>)NULL;
+       }
+
+       /**
+        * Checks if the stored value is the same as the {@code other} value
+        * 
+        * @param other
+        * @return {@code true} iff stored value == other
+        */
+       public boolean isValueSameAs(T other)
+       {
+               return value == other;
+       }
+
+       /**
+        * A null-safe checks to see if the stored value is equal to the {@code 
other} value
+        * 
+        * @param other
+        * @return {@code true} iff stored value equals other
+        */
+       public boolean isValueEqualTo(T other)
+       {
+               return Objects.equal(value, other);
+       }
+
+
+       @Override
+       public int hashCode()
+       {
+               final int prime = 31;
+               int result = 1;
+               result = prime * result + ((value == null) ? 0 : 
value.hashCode());
+               return result;
+       }
+
+       @Override
+       public boolean equals(Object obj)
+       {
+               if (this == obj)
+               {
+                       return true;
+               }
+               if (obj == null)
+               {
+                       return false;
+               }
+               if (!(obj instanceof Optional))
+               {
+                       return false;
+               }
+               Optional<?> other = (Optional<?>)obj;
+               return Objects.equal(value, other.value);
+       }
+
+       /**
+        * @return either the String "null" or the String "value: " followed by 
the contained value's
+        *         toString
+        */
+       @Override
+       public String toString()
+       {
+               return "[Optional value=" + value + "]";
+       }
+
+       /**
+        * Performs an unsafe {@link #get()}, may return {@code null}
+        * 
+        * @return stored {@code value} including {@code null}
+        */
+       public T getUnsafe()
+       {
+               return value;
+       }
+}
\ No newline at end of file

Reply via email to