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    
043      public List<Item> createMessageList(FacesContext facesContext) {
044    
045        Iterator clientIds;
046        if (isGlobalOnly()) {
047          clientIds = new SingletonIterator(null);
048        } else if (getFor() != null) {
049          clientIds = new SingletonIterator(getFor());
050        } else {
051          clientIds = facesContext.getClientIdsWithMessages();
052        }
053    
054        List<Item> messages = collectMessageList(facesContext, clientIds);
055    
056        // todo
057        if (OrderBy.SEVERITY.equals(orderBy)) {
058          // sort
059          Collections.sort(messages, new ItemComparator());
060        }
061    
062    
063    
064        return messages;
065      }
066    
067      private List<Item> collectMessageList(FacesContext facesContext, Iterator clientIds) {
068        List<Item> messages = new ArrayList<Item>();
069        while(clientIds.hasNext()) {
070          String clientId = (String) clientIds.next();
071          Iterator<FacesMessage> i = facesContext.getMessages(clientId);
072          while (i.hasNext()) {
073            FacesMessage facesMessage = i.next();
074            if (maxNumber != null && messages.size() >= maxNumber) {
075              return messages;
076            }
077            if (facesMessage.getSeverity().getOrdinal() < getMinSeverity().getOrdinal()) {
078              continue;
079            }
080            if (facesMessage.getSeverity().getOrdinal() > getMaxSeverity().getOrdinal()) {
081              continue;
082            }
083            messages.add(new Item(clientId, facesMessage));
084          }
085        }
086        return messages;
087      }
088    
089      public static class Item {
090    
091        private String clientId;
092        private FacesMessage facesMessage;
093    
094        public Item(String clientId, FacesMessage facesMessage) {
095          this.clientId = clientId;
096          this.facesMessage = facesMessage;
097        }
098    
099        public String getClientId() {
100          return clientId;
101        }
102    
103        public void setClientId(String clientId) {
104          this.clientId = clientId;
105        }
106    
107        public FacesMessage getFacesMessage() {
108          return facesMessage;
109        }
110    
111        public void setFacesMessage(FacesMessage facesMessage) {
112          this.facesMessage = facesMessage;
113        }
114      }
115    
116      public static class ItemComparator implements Comparator<Item> {
117        public int compare(Item item1, Item item2) {
118          return item2.getFacesMessage().getSeverity().getOrdinal() - item1.getFacesMessage().getSeverity().getOrdinal();
119        }
120      }
121    
122      public FacesMessage.Severity getMinSeverity() {
123        if (minSeverity != null) {
124          return minSeverity;
125        }
126        ValueBinding vb = getValueBinding(TobagoConstants.ATTR_MIN_SEVERITY);
127        if (vb != null) {
128          return (FacesMessage.Severity) vb.getValue(getFacesContext());
129        } else {
130          return FacesMessage.SEVERITY_INFO;
131        }
132      }
133    
134      public void setMinSeverity(FacesMessage.Severity minSeverity) {
135        this.minSeverity = minSeverity;
136      }
137    
138      public FacesMessage.Severity getMaxSeverity() {
139        if (maxSeverity != null) {
140          return maxSeverity;
141        }
142        ValueBinding vb = getValueBinding(TobagoConstants.ATTR_MAX_SEVERITY);
143        if (vb != null) {
144          return (FacesMessage.Severity) vb.getValue(getFacesContext());
145        } else {
146          return FacesMessage.SEVERITY_FATAL;
147        }
148      }
149    
150      public void setMaxSeverity(FacesMessage.Severity maxSeverity) {
151        this.maxSeverity = maxSeverity;
152      }
153    
154      public Integer getMaxNumber() {
155        if (maxNumber != null) {
156          return maxNumber;
157        }
158        ValueBinding vb = getValueBinding(TobagoConstants.ATTR_MAX_NUMBER);
159        if (vb != null) {
160          Number number = (Number) vb.getValue(getFacesContext());
161          if (number != null) {
162            return Integer.valueOf(number.intValue());
163          }
164        }
165        return null;
166      }
167    
168      public void setMaxNumber(Integer maxNumber) {
169        this.maxNumber = maxNumber;
170      }
171    
172      public OrderBy getOrderBy() {
173        if (orderBy != null) {
174          return orderBy;
175        }
176        ValueBinding vb = getValueBinding(TobagoConstants.ATTR_ORDER_BY);
177        if (vb != null) {
178          return (OrderBy) vb.getValue(getFacesContext());
179        } else {
180          return OrderBy.OCCURENCE;
181        }
182      }
183    
184      public void setOrderBy(OrderBy orderBy) {
185        this.orderBy = orderBy;
186      }
187    
188      public void setFor(String forValue) {
189        this.forValue = forValue;
190      }
191    
192      public String getFor() {
193        if (forValue != null) {
194          return forValue;
195        }
196        ValueBinding vb = getValueBinding("for");
197        if (vb != null) {
198          return (String) vb.getValue(getFacesContext());
199        } else {
200          return null;
201        }
202      }
203    
204      public Object saveState(FacesContext context) {
205        Object[] values = new Object[6];
206        values[0] = super.saveState(context);
207        values[1] = minSeverity;
208        values[2] = maxSeverity;
209        values[3] = maxNumber;
210        values[4] = orderBy;
211        values[5] = forValue;
212        return values;
213      }
214    
215      public void restoreState(FacesContext context, Object state) {
216        Object[] values = (Object[]) state;
217        super.restoreState(context, values[0]);
218        minSeverity = (FacesMessage.Severity) values[1];
219        maxSeverity = (FacesMessage.Severity) values[2];
220        maxNumber = (Integer) values[3];
221        orderBy = (OrderBy) values[4];
222        forValue = (String) values[5];
223      }
224    
225      public enum OrderBy {
226    
227        OCCURENCE,
228        SEVERITY;
229    
230        public static final String OCCURENCE_STRING = "occurence";
231        public static final String SEVERITY_STRING = "severity";
232    
233        public static OrderBy parse(String key) {
234          return valueOf(key.toUpperCase());
235        }
236    
237      }
238    }