• 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 
27 import java.io.ObjectStreamException;
28 import java.io.Serializable;
29 import java.util.List;
30 
31 /**
32  * An error message and the context in which it occured. Messages are usually created internally by
33  * Guice and its extensions. Messages can be created explicitly in a module using {@link
34  * com.google.inject.Binder#addError(Throwable) addError()} statements:
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   /**
50    * @since 2.0
51    */
Message(List<Object> sources, String message, Throwable cause)52   public Message(List<Object> sources, String message, Throwable cause) {
53     this.sources = ImmutableList.copyOf(sources);
54     this.message = checkNotNull(message, "message");
55     this.cause = cause;
56   }
57 
58   /**
59    * @since 4.0
60    */
Message(String message, Throwable cause)61   public Message(String message, Throwable cause) {
62     this(ImmutableList.of(), message, cause);
63   }
64 
Message(Object source, String message)65   public Message(Object source, String message) {
66     this(ImmutableList.of(source), message, null);
67   }
68 
Message(String message)69   public Message(String message) {
70     this(ImmutableList.of(), message, null);
71   }
72 
getSource()73   public String getSource() {
74     return sources.isEmpty()
75         ? SourceProvider.UNKNOWN_SOURCE.toString()
76         : Errors.convert(sources.get(sources.size() - 1)).toString();
77   }
78 
79   /** @since 2.0 */
getSources()80   public List<Object> getSources() {
81     return sources;
82   }
83 
84   /**
85    * Gets the error message text.
86    */
getMessage()87   public String getMessage() {
88     return message;
89   }
90 
91   /** @since 2.0 */
acceptVisitor(ElementVisitor<T> visitor)92   public <T> T acceptVisitor(ElementVisitor<T> visitor) {
93     return visitor.visit(this);
94   }
95 
96   /**
97    * Returns the throwable that caused this message, or {@code null} if this
98    * message was not caused by a throwable.
99    *
100    * @since 2.0
101    */
getCause()102   public Throwable getCause() {
103     return cause;
104   }
105 
toString()106   @Override public String toString() {
107     return message;
108   }
109 
hashCode()110   @Override public int hashCode() {
111     return message.hashCode();
112   }
113 
equals(Object o)114   @Override public boolean equals(Object o) {
115     if (!(o instanceof Message)) {
116       return false;
117     }
118     Message e = (Message) o;
119     return message.equals(e.message) && Objects.equal(cause, e.cause) && sources.equals(e.sources);
120   }
121 
122   /** @since 2.0 */
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