1 | // Copyright (C) 2005 Google Inc. |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | package com.google.caja.reporting; |
16 | |
17 | import java.io.IOException; |
18 | import java.util.Arrays; |
19 | import java.util.Collection; |
20 | |
21 | /** |
22 | * A part that may substitute for a placeholder in an error or logging message. |
23 | * |
24 | * @author mikesamuel@gmail.com |
25 | */ |
26 | public interface MessagePart { |
27 | |
28 | /** |
29 | * Formats this part to out. |
30 | * @param out receives the formatted form of this. |
31 | */ |
32 | void format(MessageContext context, Appendable out) throws IOException; |
33 | |
34 | public static class Factory { |
35 | private Factory() { |
36 | // namespace for static methods |
37 | } |
38 | |
39 | public static MessagePart valueOf(String s) { |
40 | return new MessagePartWrapper(s); |
41 | } |
42 | |
43 | public static MessagePart valueOf(final Number n) { |
44 | return new MessagePartWrapper(n); |
45 | } |
46 | |
47 | public static MessagePart valueOf(int n) { |
48 | return new MessagePartWrapper(n); |
49 | } |
50 | |
51 | public static MessagePart valueOf(long n) { |
52 | return new MessagePartWrapper(n); |
53 | } |
54 | |
55 | public static MessagePart valueOf(double n) { |
56 | return new MessagePartWrapper(n); |
57 | } |
58 | |
59 | public static MessagePart valueOf(Collection<?> parts) { |
60 | final MessagePart[] partArr = new MessagePart[parts.size()]; |
61 | int k = 0; |
62 | for (Object p : parts) { |
63 | if (!(p instanceof MessagePart)) { |
64 | if (p instanceof Number) { |
65 | p = valueOf((Number) p); |
66 | } else { |
67 | p = valueOf(p.toString()); |
68 | } |
69 | } |
70 | partArr[k++] = (MessagePart) p; |
71 | } |
72 | return new ArrayPart(partArr); |
73 | } |
74 | |
75 | private static class MessagePartWrapper implements MessagePart { |
76 | private final Object wrapped; |
77 | MessagePartWrapper(Object wrapped) { |
78 | if (wrapped == null) { throw new NullPointerException(); } |
79 | this.wrapped = wrapped; |
80 | } |
81 | public void format(MessageContext context, Appendable out) |
82 | throws IOException { |
83 | out.append(wrapped.toString()); |
84 | } |
85 | @Override |
86 | public boolean equals(Object o) { |
87 | if (!(o instanceof MessagePartWrapper)) { return false; } |
88 | return this.wrapped.equals(((MessagePartWrapper) o).wrapped); |
89 | } |
90 | @Override |
91 | public int hashCode() { |
92 | return wrapped.hashCode() ^ 0x2ed53af2; |
93 | } |
94 | @Override |
95 | public String toString() { return wrapped.toString(); } |
96 | } |
97 | |
98 | private static class ArrayPart implements MessagePart { |
99 | private final MessagePart[] partArr; |
100 | |
101 | ArrayPart(MessagePart[] partArr) { this.partArr = partArr; } |
102 | |
103 | public void format(MessageContext context, Appendable out) |
104 | throws IOException { |
105 | for (int i = 0; i < partArr.length; ++i) { |
106 | if (0 != i) { out.append(", "); } |
107 | partArr[i].format(context, out); |
108 | } |
109 | } |
110 | @Override |
111 | public String toString() { return Arrays.asList(partArr).toString(); } |
112 | |
113 | @Override |
114 | public int hashCode() { |
115 | return Arrays.hashCode(partArr) ^ 0x78abcd35; |
116 | } |
117 | |
118 | @Override |
119 | public boolean equals(Object o) { |
120 | if (!(o instanceof ArrayPart)) { return false; } |
121 | ArrayPart that = (ArrayPart) o; |
122 | if (that.partArr.length != this.partArr.length) { return false; } |
123 | for (int i = partArr.length; --i >= 0;) { |
124 | if (!this.partArr[i].equals(that.partArr[i])) { return false; } |
125 | } |
126 | return true; |
127 | } |
128 | } |
129 | } |
130 | } |