• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.inject.spi;
18 
19 import static com.google.common.base.Preconditions.checkNotNull;
20 
21 import com.google.common.base.Objects;
22 import com.google.common.collect.ImmutableList;
23 import com.google.inject.Binder;
24 import com.google.inject.internal.Errors;
25 import com.google.inject.internal.util.SourceProvider;
26 import java.io.ObjectStreamException;
27 import java.io.Serializable;
28 import java.util.List;
29 
30 /**
31  * An error message and the context in which it occured. Messages are usually created internally by
32  * Guice and its extensions. Messages can be created explicitly in a module using {@link
33  * com.google.inject.Binder#addError(Throwable) addError()} statements:
34  *
35  * <pre>
36  *     try {
37  *       bindPropertiesFromFile();
38  *     } catch (IOException e) {
39  *       addError(e);
40  *     }</pre>
41  *
42  * @author crazybob@google.com (Bob Lee)
43  */
44 public final class Message implements Serializable, Element {
45   private final String message;
46   private final Throwable cause;
47   private final List<Object> sources;
48 
49   /** @since 2.0 */
Message(List<Object> sources, String message, Throwable cause)50   public Message(List<Object> sources, String message, Throwable cause) {
51     this.sources = ImmutableList.copyOf(sources);
52     this.message = checkNotNull(message, "message");
53     this.cause = cause;
54   }
55 
56   /** @since 4.0 */
Message(String message, Throwable cause)57   public Message(String message, Throwable cause) {
58     this(ImmutableList.of(), message, cause);
59   }
60 
Message(Object source, String message)61   public Message(Object source, String message) {
62     this(ImmutableList.of(source), message, null);
63   }
64 
Message(String message)65   public Message(String message) {
66     this(ImmutableList.of(), message, null);
67   }
68 
69   @Override
getSource()70   public String getSource() {
71     return sources.isEmpty()
72         ? SourceProvider.UNKNOWN_SOURCE.toString()
73         : Errors.convert(sources.get(sources.size() - 1)).toString();
74   }
75 
76   /** @since 2.0 */
getSources()77   public List<Object> getSources() {
78     return sources;
79   }
80 
81   /** Gets the error message text. */
getMessage()82   public String getMessage() {
83     return message;
84   }
85 
86   /** @since 2.0 */
87   @Override
acceptVisitor(ElementVisitor<T> visitor)88   public <T> T acceptVisitor(ElementVisitor<T> visitor) {
89     return visitor.visit(this);
90   }
91 
92   /**
93    * Returns the throwable that caused this message, or {@code null} if this message was not caused
94    * by a throwable.
95    *
96    * @since 2.0
97    */
getCause()98   public Throwable getCause() {
99     return cause;
100   }
101 
102   @Override
toString()103   public String toString() {
104     return message;
105   }
106 
107   @Override
hashCode()108   public int hashCode() {
109     return Objects.hashCode(message, cause, sources);
110   }
111 
112   @Override
equals(Object o)113   public boolean equals(Object o) {
114     if (!(o instanceof Message)) {
115       return false;
116     }
117     Message e = (Message) o;
118     return message.equals(e.message) && Objects.equal(cause, e.cause) && sources.equals(e.sources);
119   }
120 
121   /** @since 2.0 */
122   @Override
applyTo(Binder binder)123   public void applyTo(Binder binder) {
124     binder.withSource(getSource()).addError(this);
125   }
126 
127   /**
128    * When serialized, we eagerly convert sources to strings. This hurts our formatting, but it
129    * guarantees that the receiving end will be able to read the message.
130    */
writeReplace()131   private Object writeReplace() throws ObjectStreamException {
132     Object[] sourcesAsStrings = sources.toArray();
133     for (int i = 0; i < sourcesAsStrings.length; i++) {
134       sourcesAsStrings[i] = Errors.convert(sourcesAsStrings[i]).toString();
135     }
136     return new Message(ImmutableList.copyOf(sourcesAsStrings), message, cause);
137   }
138 
139   private static final long serialVersionUID = 0;
140 }
141