001    package org.apache.myfaces.tobago.component;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one or more
005     * contributor license agreements.  See the NOTICE file distributed with
006     * this work for additional information regarding copyright ownership.
007     * The ASF licenses this file to You under the Apache License, Version 2.0
008     * (the "License"); you may not use this file except in compliance with
009     * the License.  You may obtain a copy of the License at
010     *
011     *      http://www.apache.org/licenses/LICENSE-2.0
012     *
013     * Unless required by applicable law or agreed to in writing, software
014     * distributed under the License is distributed on an "AS IS" BASIS,
015     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016     * See the License for the specific language governing permissions and
017     * limitations under the License.
018     */
019    
020    import org.apache.commons.collections.iterators.SingletonIterator;
021    import org.apache.myfaces.tobago.TobagoConstants;
022    
023    import javax.faces.application.FacesMessage;
024    import javax.faces.context.FacesContext;
025    import javax.faces.el.ValueBinding;
026    import java.util.ArrayList;
027    import java.util.Collections;
028    import java.util.Comparator;
029    import java.util.Iterator;
030    import java.util.List;
031    
032    public class UIMessages extends javax.faces.component.UIMessages {
033    
034      public static final String COMPONENT_TYPE = "org.apache.myfaces.tobago.Messages";
035    
036      private FacesMessage.Severity minSeverity;
037      private FacesMessage.Severity maxSeverity;
038      private Integer maxNumber;
039      // todo: emnum
040      private OrderBy orderBy;
041      private String forValue;
042      private Boolean confirmation;
043    
044      public List<Item> createMessageList(FacesContext facesContext) {
045    
046        Iterator clientIds;
047        if (isGlobalOnly()) {
048          clientIds = new SingletonIterator(null);
049        } else if (getFor() != null) {
050          clientIds = new SingletonIterator(getFor());
051        } else {
052          clientIds = facesContext.getClientIdsWithMessages();
053        }
054    
055        List<Item> messages = collectMessageList(facesContext, clientIds);
056    
057        // todo
058        if (OrderBy.SEVERITY.equals(orderBy)) {
059          // sort
060          Collections.sort(messages, new ItemComparator());
061        }
062    
063    
064    
065        return messages;
066      }
067    
068      private List<Item> collectMessageList(FacesContext facesContext, Iterator clientIds) {
069        List<Item> messages = new ArrayList<Item>();
070        while(clientIds.hasNext()) {
071          String clientId = (String) clientIds.next();
072          Iterator<FacesMessage> i = facesContext.getMessages(clientId);
073          while (i.hasNext()) {
074            FacesMessage facesMessage = i.next();
075            if (maxNumber != null && messages.size() >= maxNumber) {
076              return messages;
077            }
078            if (facesMessage.getSeverity().getOrdinal() < getMinSeverity().getOrdinal()) {
079              continue;
080            }
081            if (facesMessage.getSeverity().getOrdinal() > getMaxSeverity().getOrdinal()) {
082              continue;
083            }
084            messages.add(new Item(clientId, facesMessage));
085          }
086        }
087        return messages;
088      }
089    
090      public static class Item {
091    
092        private String clientId;
093        private FacesMessage facesMessage;
094    
095        public Item(String clientId, FacesMessage facesMessage) {
096          this.clientId = clientId;
097          this.facesMessage = facesMessage;
098        }
099    
100        public String getClientId() {
101          return clientId;
102        }
103    
104        public void setClientId(String clientId) {
105          this.clientId = clientId;
106        }
107    
108        public FacesMessage getFacesMessage() {
109          return facesMessage;
110        }
111    
112        public void setFacesMessage(FacesMessage facesMessage) {
113          this.facesMessage = facesMessage;
114        }
115      }
116    
117      public static class ItemComparator implements Comparator<Item> {
118        public int compare(Item item1, Item item2) {
119          return item2.getFacesMessage().getSeverity().getOrdinal() - item1.getFacesMessage().getSeverity().getOrdinal();
120        }
121      }
122    
123      public FacesMessage.Severity getMinSeverity() {
124        if (minSeverity != null) {
125          return minSeverity;
126        }
127        ValueBinding vb = getValueBinding(TobagoConstants.ATTR_MIN_SEVERITY);
128        if (vb != null) {
129          return (FacesMessage.Severity) vb.getValue(getFacesContext());
130        } else {
131          return FacesMessage.SEVERITY_INFO;
132        }
133      }
134    
135      public void setMinSeverity(FacesMessage.Severity minSeverity) {
136        this.minSeverity = minSeverity;
137      }
138    
139      public FacesMessage.Severity getMaxSeverity() {
140        if (maxSeverity != null) {
141          return maxSeverity;
142        }
143        ValueBinding vb = getValueBinding(TobagoConstants.ATTR_MAX_SEVERITY);
144        if (vb != null) {
145          return (FacesMessage.Severity) vb.getValue(getFacesContext());
146        } else {
147          return FacesMessage.SEVERITY_FATAL;
148        }
149      }
150    
151      public void setMaxSeverity(FacesMessage.Severity maxSeverity) {
152        this.maxSeverity = maxSeverity;
153      }
154    
155      public Integer getMaxNumber() {
156        if (maxNumber != null) {
157          return maxNumber;
158        }
159        ValueBinding vb = getValueBinding(TobagoConstants.ATTR_MAX_NUMBER);
160        if (vb != null) {
161          Number number = (Number) vb.getValue(getFacesContext());
162          if (number != null) {
163            return Integer.valueOf(number.intValue());
164          }
165        }
166        return null;
167      }
168    
169      public void setMaxNumber(Integer maxNumber) {
170        this.maxNumber = maxNumber;
171      }
172    
173      public OrderBy getOrderBy() {
174        if (orderBy != null) {
175          return orderBy;
176        }
177        ValueBinding vb = getValueBinding(TobagoConstants.ATTR_ORDER_BY);
178        if (vb != null) {
179          return (OrderBy) vb.getValue(getFacesContext());
180        } else {
181          return OrderBy.OCCURENCE;
182        }
183      }
184    
185      public void setOrderBy(OrderBy orderBy) {
186        this.orderBy = orderBy;
187      }
188    
189      public void setFor(String forValue) {
190        this.forValue = forValue;
191      }
192    
193      public String getFor() {
194        if (forValue != null) {
195          return forValue;
196        }
197        ValueBinding vb = getValueBinding("for");
198        if (vb != null) {
199          return (String) vb.getValue(getFacesContext());
200        } else {
201          return null;
202        }
203      }
204    
205      public boolean isConfirmation() {
206        if (confirmation != null) {
207          return confirmation;
208        }
209        ValueBinding vb = getValueBinding(TobagoConstants.ATTR_CONFIRMATION);
210        if (vb != null) {
211          return (Boolean.TRUE.equals(vb.getValue(getFacesContext())));
212        } else {
213          return false;
214        }
215      }
216    
217      public void setConfirmation(boolean confirmation) {
218        this.confirmation = confirmation;
219      }
220    
221      @Override
222      public Object saveState(FacesContext context) {
223        Object[] values = new Object[7];
224        values[0] = super.saveState(context);
225        values[1] = minSeverity;
226        values[2] = maxSeverity;
227        values[3] = maxNumber;
228        values[4] = orderBy;
229        values[5] = forValue;
230        values[6] = confirmation;
231        return values;
232      }
233    
234      @Override
235      public void restoreState(FacesContext context, Object state) {
236        Object[] values = (Object[]) state;
237        super.restoreState(context, values[0]);
238        minSeverity = (FacesMessage.Severity) values[1];
239        maxSeverity = (FacesMessage.Severity) values[2];
240        maxNumber = (Integer) values[3];
241        orderBy = (OrderBy) values[4];
242        forValue = (String) values[5];
243        confirmation = (Boolean) values[6];
244      }
245    
246      public enum OrderBy {
247    
248        OCCURENCE,
249        SEVERITY;
250    
251        public static final String OCCURENCE_STRING = "occurence";
252        public static final String SEVERITY_STRING = "severity";
253    
254        public static OrderBy parse(String key) {
255          return valueOf(key.toUpperCase());
256        }
257    
258      }
259    }