View Javadoc

1   /*
2    * Copyright 2007-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.exceptions.i18n;
17  
18  import java.io.Serializable;
19  import java.util.ArrayList;
20  import java.util.Collections;
21  import java.util.List;
22  import java.util.Locale;
23  
24  import org.apache.commons.lang.StringUtils;
25  
26  import de.smartics.exceptions.i18n.message.MessageType;
27  import de.smartics.exceptions.i18n.message.Messages;
28  
29  /**
30   * Stores the message information of the causes. The exception whose cause trail
31   * this instance is, is <strong>not</strong> part of the cause trail. This makes
32   * it possible to render all messages without need to skip the first one that is
33   * usually rendered otherwise.
34   */
35  public final class CauseTrailMessages implements Serializable
36  {
37    // ********************************* Fields *********************************
38  
39    // --- constants ------------------------------------------------------------
40  
41    /**
42     * The class version identifier.
43     */
44    private static final long serialVersionUID = 1L;
45  
46    // --- members --------------------------------------------------------------
47  
48    /**
49     * The trail of messages to the root.
50     */
51    private final List<Messages> trail = new ArrayList<Messages>();
52  
53    // ****************************** Initializer *******************************
54  
55    // ****************************** Constructors ******************************
56  
57    /**
58     * Convenience constructor using the default locale.
59     *
60     * @param cause the cause to the exception this is the cause trail instance
61     *          for.
62     */
63    public CauseTrailMessages(final Throwable cause)
64    {
65      this(Locale.getDefault(), cause);
66    }
67  
68    /**
69     * Default constructor.
70     *
71     * @param locale the locale for which the message is requested.
72     * @param cause the cause to the exception this is the cause trail instance
73     *          for.
74     */
75    public CauseTrailMessages(final Locale locale, final Throwable cause)
76    {
77      initCauseTrail(locale, cause);
78    }
79  
80    // ****************************** Inner Classes *****************************
81  
82    // ********************************* Methods ********************************
83  
84    // --- init -----------------------------------------------------------------
85  
86    private void initCauseTrail(final Locale locale, final Throwable cause)
87    {
88      Throwable current = cause;
89      while (current != null)
90      {
91        if (current instanceof LocalizedException)
92        {
93          final LocalizedException localizedException =
94              (LocalizedException) current;
95          final Messages messages = localizedException.createMessages(locale);
96          trail.add(messages);
97          final CauseTrailMessages causeTrail =
98              localizedException.getCauseTrail(locale);
99          trail.addAll(causeTrail.trail);
100         current = null;
101       }
102       else
103       {
104         final Messages messages = createNonSmarticsExceptionsMessages(current);
105         trail.add(messages);
106         current = current.getCause();
107       }
108     }
109   }
110 
111   private Messages createNonSmarticsExceptionsMessages(final Throwable current)
112   {
113     final String text = current.getLocalizedMessage();
114     return new Messages.Builder()
115         .put(MessageType.TITLE, current.getClass().getName())
116         .put(MessageType.SUMMARY, text != null ? text : "n/a").build();
117   }
118 
119   // --- get&set --------------------------------------------------------------
120 
121   /**
122    * Returns the trail of messages to the root.
123    *
124    * @return the trail of messages to the root.
125    */
126   public List<Messages> getTrail()
127   {
128     return Collections.unmodifiableList(trail);
129   }
130 
131   // --- business -------------------------------------------------------------
132 
133   // --- object basics --------------------------------------------------------
134 
135   @Override
136   public String toString()
137   {
138     final StringBuilder buffer = new StringBuilder(trail.size() * 256);
139 
140     int i = 0;
141     for (final Messages messages : trail)
142     {
143       final String prefix = StringUtils.repeat(" ", i++);
144 
145       for (final MessageType type : MessageType.values())
146       {
147         final String message = messages.getMessage(type);
148         if (message != null)
149         {
150           buffer.append(prefix).append(type).append('=').append(message)
151               .append('\n');
152         }
153       }
154     }
155 
156     return StringUtils.chomp(buffer.toString());
157   }
158 }