This project has retired. For details please refer to its Attic page.
Source code
001package org.apache.archiva.common;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.util.function.Function;
023
024/**
025 * This is a class that can be used for the Try monad
026 *
027 * The Try monad is able to collect exceptions during processing
028 * of a stream.
029 *
030 *
031 *
032 */
033public abstract class Try<V> {
034
035    private Try() {
036
037    }
038
039    public abstract Boolean isSuccess();
040
041    public abstract Boolean isFailure();
042
043    public abstract void throwException();
044
045    /**
046     * Returns the value if this is a success instance. Otherwise throws
047     * a runtime exception with the stored throwable as cause.
048     *
049     * @return The value
050     */
051    public abstract V get();
052
053    /**
054     * Returns the throwable that is stored in the failure.
055     *
056     * @return The Throwable or null.
057     */
058    public abstract Throwable getError();
059
060
061    /**
062     * A mapping method for mapping the current instance to a new type.
063     *
064     * @param fn
065     * @param <U>
066     * @return
067     */
068    public <U> Try<U> map(Function<? super V, U> fn) {
069        try {
070            return Try.success(fn.apply(get()));
071        } catch (Throwable e) {
072            return Try.failure(e);
073        }
074    }
075
076    /**
077     * This is the bind method.
078     * If this instance is success the function will be applied. If any error occurs
079     * a failure instance will be returned.
080     * If this instance is failure a new failure will be returned.
081     *
082     * @param fn
083     * @param <U>
084     * @return
085     */
086    public <U> Try<U> flatMap(Function<? super V, Try<U>> fn) {
087        try {
088            return fn.apply(get());
089        } catch (Throwable t) {
090            return Try.failure(t);
091        }
092    }
093
094    public static <V> Try<V> failure(String message) {
095
096        return new Failure<>(message);
097
098    }
099
100    public static <V> Try<V> failure(String message, Throwable e) {
101
102        return new Failure<>(message, e);
103
104    }
105
106    /**
107     * If you need type coercion, you should call this method as
108     *  Try.&lt;YOUR_TYPE&gt;failure(e)
109     *
110     *
111     *
112     * @param e The exception that is thrown
113     * @param <V> The generic type this monad keeps
114     * @return A new Try instance that represents a failure.
115     */
116    public static <V> Try<V> failure(Throwable e) {
117
118        return new Failure<>(e);
119
120    }
121
122
123    /**
124     * Returns a instance for the success case.
125     *
126     * @param value The value that should be stored.
127     * @param <V> The return type
128     * @return A new Try instance with the given value
129     */
130    public static <V> Try<V> success(V value) {
131
132        return new Success<>(value);
133
134    }
135
136    private static class Failure<V> extends Try<V> {
137
138        private Throwable exception;
139
140        public Failure(String message) {
141
142            super();
143
144            this.exception = new IllegalStateException(message);
145
146        }
147
148        public Failure(String message, Throwable e) {
149
150            super();
151
152            this.exception = new IllegalStateException(message, e);
153
154        }
155
156        public Failure(Throwable e) {
157
158            super();
159
160            this.exception = new IllegalStateException(e);
161
162        }
163
164        @Override
165
166        public Boolean isSuccess() {
167
168            return false;
169
170        }
171
172        @Override
173
174        public Boolean isFailure() {
175
176            return true;
177
178        }
179
180        @Override
181
182        public void throwException() {
183
184            throw new RuntimeException(this.exception);
185
186        }
187
188        @Override
189        public V get() {
190            throw new RuntimeException(this.exception);
191        }
192
193        @Override
194        public Throwable getError() {
195            return exception;
196        }
197    }
198
199    private static class Success<V> extends Try<V> {
200
201        private V value;
202
203        public Success(V value) {
204
205            super();
206
207            this.value = value;
208
209        }
210
211        @Override
212
213        public Boolean isSuccess() {
214
215            return true;
216
217        }
218
219        @Override
220
221        public Boolean isFailure() {
222
223            return false;
224
225        }
226
227        @Override
228
229        public void throwException() {
230
231            //log.error("Method throwException() called on a Success instance");
232
233        }
234
235        @Override
236        public V get() {
237            return value;
238        }
239
240        @Override
241        public Throwable getError() {
242            return null;
243        }
244    }
245
246    // various method such as map an flatMap
247
248
249    @Override
250    public String toString() {
251        return isSuccess() ? "true: "+get() : "false: "+ getError().getMessage();
252    }
253}