View Javadoc

1   /*
2    * Copyright 2012-2013 smartics, Kronseder & Reiner GmbH
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  package de.smartics.properties.resource.util;
17  
18  import java.io.Serializable;
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import org.apache.commons.lang.StringUtils;
23  
24  import de.smartics.exceptions.i18n.message.MessageParam;
25  import de.smartics.properties.api.core.app.AbstractBaseMessageBean;
26  import de.smartics.properties.resource.domain.ResourceCode;
27  
28  /**
29   * Provides context information for errors regarding a type.
30   */
31  public final class TypeProblemMessageBean extends AbstractBaseMessageBean
32  {
33    // ********************************* Fields *********************************
34  
35    // --- constants ------------------------------------------------------------
36  
37    /**
38     * The class version identifier.
39     * <p>
40     * The value of this constant is {@value}.
41     * </p>
42     */
43    private static final long serialVersionUID = 1L;
44  
45    // --- members --------------------------------------------------------------
46  
47    /**
48     * The type that is the cause of the problem.
49     *
50     * @serial
51     */
52    @MessageParam("type:simpleName,fqn:name")
53    private final OgnlInterfaceFix type;
54  
55    /**
56     * The list of duplicates implementations of the same type.
57     *
58     * @serial
59     */
60    private final List<String> duplicates;
61  
62    /**
63     * The list of errors encountered while trying to instantiate a service type.
64     *
65     * @serial
66     */
67    private final List<String> errors;
68  
69    // ****************************** Initializer *******************************
70  
71    // ****************************** Constructors ******************************
72  
73    /**
74     * Convenience constructor without root cause.
75     *
76     * @param type the type that is the cause of the problem.
77     */
78    public TypeProblemMessageBean(final Class<?> type)
79    {
80      this(null, type);
81    }
82  
83    /**
84     * Default constructor.
85     *
86     * @param cause the cause to the problem.
87     * @param type the type that is the cause of the problem.
88     */
89    public TypeProblemMessageBean(final Throwable cause, final Class<?> type)
90    {
91      super(ResourceCode.FACTORY_CANNOT_INSTANTIATE_TYPE, cause);
92      this.type = new OgnlInterfaceFix(type);
93      this.duplicates = null;
94      this.errors = null;
95    }
96  
97    private TypeProblemMessageBean(final Builder builder)
98    {
99      super(ResourceCode.SERVICE_FACTORY_PROBLEMS);
100     this.type = builder.type;
101     this.duplicates = builder.duplicates;
102     this.errors = builder.errors;
103   }
104 
105   // ****************************** Inner Classes *****************************
106 
107   /**
108    * Wrapper around types since the OGNL library fails to get simple names from
109    * interfaces.
110    */
111   private static final class OgnlInterfaceFix implements Serializable
112   {
113     // ******************************** Fields ********************************
114 
115     // --- constants ----------------------------------------------------------
116 
117     /**
118      * The class version identifier.
119      * <p>
120      * The value of this constant is {@value}.
121      * </p>
122      */
123     private static final long serialVersionUID = 1L;
124 
125     // --- members ------------------------------------------------------------
126 
127     /**
128      * The simple name of the wrapped interface.
129      */
130     private final String simpleName;
131 
132     /**
133      * The fqn name of the wrapped interface.
134      */
135     private final String name;
136 
137     // ***************************** Initializer ******************************
138 
139     // ***************************** Constructors *****************************
140 
141     private OgnlInterfaceFix(final Class<?> type)
142     {
143       this.simpleName = type.getSimpleName();
144       this.name = type.getName();
145     }
146 
147     // ***************************** Inner Classes ****************************
148 
149     // ******************************** Methods *******************************
150 
151     // --- init ---------------------------------------------------------------
152 
153     // --- get&set ------------------------------------------------------------
154 
155     /**
156      * Returns the simple name of the wrapped interface.
157      *
158      * @return the simple name of the wrapped interface.
159      */
160     @SuppressWarnings("unused")
161     public String getSimpleName()
162     {
163       return simpleName;
164     }
165 
166     /**
167      * Returns the fqn name of the wrapped interface.
168      *
169      * @return the fqn name of the wrapped interface.
170      */
171     @SuppressWarnings("unused")
172     public String getName()
173     {
174       return name;
175     }
176 
177     // --- business -----------------------------------------------------------
178 
179     // --- object basics ------------------------------------------------------
180   }
181 
182   /**
183    * Creates instances of {@link TypeProblemMessageBean}.
184    */
185   public static final class Builder
186   {
187     // ******************************** Fields ********************************
188 
189     // --- constants ----------------------------------------------------------
190 
191     // --- members ------------------------------------------------------------
192 
193     /**
194      * The type that is the cause of the problem.
195      */
196     private OgnlInterfaceFix type;
197 
198     /**
199      * The list of duplicates implementations of the same type.
200      */
201     private final List<String> duplicates = new ArrayList<String>();
202 
203     /**
204      * The list of errors encountered while trying to instantiate a service
205      * type.
206      */
207     private final List<String> errors = new ArrayList<String>();
208 
209     // ***************************** Initializer ******************************
210 
211     // ***************************** Constructors *****************************
212 
213     // ***************************** Inner Classes ****************************
214 
215     // ******************************** Methods *******************************
216 
217     // --- init ---------------------------------------------------------------
218 
219     // --- get&set ------------------------------------------------------------
220 
221     /**
222      * Sets the type that is the cause of the problem.
223      *
224      * @param type the type that is the cause of the problem.
225      * @return a reference to the builder.
226      */
227     public Builder with(final Class<?> type)
228     {
229       this.type = new OgnlInterfaceFix(type);
230       return this;
231     }
232 
233     /**
234      * Adds the given duplicate implementation to the list.
235      *
236      * @param duplicate the name of the implementation that implements the given
237      *          type.
238      * @return a reference to the builder.
239      */
240     public Builder withDuplicate(final String duplicate)
241     {
242       duplicates.add(duplicate);
243       return this;
244     }
245 
246     /**
247      * Adds the given error message to the list.
248      *
249      * @param error the error message for detailed information on problems while
250      *          instantiating a service type.
251      * @return a reference to the builder.
252      */
253     public Builder withError(final String error)
254     {
255       errors.add(error);
256       return this;
257     }
258 
259     // --- business -----------------------------------------------------------
260 
261     /**
262      * Creates the instance.
263      *
264      * @return the created instance.
265      */
266     public TypeProblemMessageBean build()
267     {
268       return new TypeProblemMessageBean(this);
269     }
270 
271     /**
272      * Creates the message.
273      *
274      * @return the created message.
275      */
276     public String toMessage()
277     {
278       return new TypeProblemMessageBean(this).toString();
279     }
280 
281     /**
282      * Checks if duplicates or errors have been reported.
283      *
284      * @return <code>false</code> if neither duplicates or errors have been
285      *         reported, <code>true</code> otherwise.
286      */
287     public boolean hasReportedProblems()
288     {
289       return !(duplicates.isEmpty() && errors.isEmpty());
290     }
291 
292     // --- object basics ------------------------------------------------------
293   }
294 
295   // ********************************* Methods ********************************
296 
297   // --- init -----------------------------------------------------------------
298 
299   // --- get&set --------------------------------------------------------------
300 
301   // --- business -------------------------------------------------------------
302 
303   /**
304    * Returns the list of duplicates implementations of the same type.
305    *
306    * @return the list of duplicates implementations of the same type as a
307    *         message.
308    */
309   @MessageParam("duplicates")
310   public String getDuplicates()
311   {
312     return toString(duplicates);
313   }
314 
315   /**
316    * Returns the count of duplicates.
317    *
318    * @return the count of duplicates.
319    */
320   @MessageParam("duplicateCount")
321   public int getDuplicateCount()
322   {
323     return duplicates != null ? duplicates.size() : 0;
324   }
325 
326   /**
327    * Returns the list of errors encountered while trying to instantiate a
328    * service type.
329    *
330    * @return the list of errors encountered while trying to instantiate a
331    *         service type as a message.
332    */
333   @MessageParam("errors")
334   public String getErrors()
335   {
336     return toString(errors);
337   }
338 
339   /**
340    * Returns the count of errors.
341    *
342    * @return the count of errors.
343    */
344   @MessageParam("errorCount")
345   public int getErrorCount()
346   {
347     return errors != null ? errors.size() : 0;
348   }
349 
350   private static String toString(final List<String> items)
351   {
352     if (items == null)
353     {
354       return null;
355     }
356 
357     final StringBuilder buffer = new StringBuilder(64);
358     for (final String item : items)
359     {
360       buffer.append("  ").append(item).append('\n');
361     }
362     return StringUtils.chomp(buffer.toString());
363   }
364 
365   @Override
366   public String toString()
367   {
368     return this.getCode().getDisplayId() + ": " + this.getMessages();
369   }
370 
371   // --- object basics --------------------------------------------------------
372 
373 }