1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.taglib.faces.converter;
24  
25  import com.liferay.portal.kernel.language.LanguageUtil;
26  
27  import java.util.Locale;
28  
29  import javax.faces.application.FacesMessage;
30  import javax.faces.component.StateHolder;
31  import javax.faces.component.UIComponent;
32  import javax.faces.context.ExternalContext;
33  import javax.faces.context.FacesContext;
34  import javax.faces.convert.Converter;
35  import javax.faces.convert.ConverterException;
36  
37  /**
38   * <a href="PhoneNumberConverter.java.html"><b><i>View Source</i></b></a>
39   *
40   * <p>
41   * This class is a JSF converter that can be used to convert phone numbers.
42   * Since phone numbers in the United States of America always have 10 digits,
43   * this converter provides automatic conversion of 10 digit phone numbers to
44   * a desired format. The format is specified by the unitedStatesFormat
45   * component attribute.
46   * </p>
47   *
48   * @author Neil Griffin
49   *
50   */
51  public class PhoneNumberConverter implements Converter, StateHolder {
52  
53      public boolean isTransient() {
54          return _transient;
55      }
56  
57      public void setTransient(boolean value) {
58          _transient = value;
59      }
60  
61      public String getUnitedStatesFormat() {
62          return _unitedStatesFormat;
63      }
64  
65      public void setUnitedStatesFormat(String unitedStatesFormat) {
66          _unitedStatesFormat = unitedStatesFormat;
67      }
68  
69      public Object getAsObject(
70          FacesContext facesContext, UIComponent uiComponent, String value) {
71  
72          if (value != null) {
73              StringBuilder integerChars = new StringBuilder();
74              StringBuilder invalidChars = new StringBuilder();
75  
76              for (int i = 0; i < value.length(); i++) {
77                  char curChar = value.charAt(i);
78  
79                  if (Character.isDigit(curChar)) {
80                      integerChars.append(curChar);
81                  }
82                  else if ((curChar != '-') && (curChar != '(') &&
83                           (curChar != ')') && (curChar != '.') &&
84                           (curChar != '+') && (curChar != ' ')) {
85  
86                      invalidChars.append(curChar);
87                  }
88              }
89  
90              if (invalidChars.length() > 0) {
91                  ExternalContext externalContext =
92                      facesContext.getExternalContext();
93  
94                  Locale locale = externalContext.getRequestLocale();
95  
96                  String summary = LanguageUtil.get(
97                      locale, "the-following-are-invalid-characters");
98  
99                  summary += " " + invalidChars.toString();
100 
101                 FacesMessage facesMessage = new FacesMessage(
102                     FacesMessage.SEVERITY_ERROR, summary, null);
103 
104                 throw new ConverterException(facesMessage);
105             }
106             else if ((integerChars.length() == 10)) {
107                 StringBuilder unitedStatesPhoneNumber = new StringBuilder();
108 
109                 int integerDigitIndex = 0;
110 
111                 for (int i = 0; i < _unitedStatesFormat.length(); i++) {
112                     char curChar = _unitedStatesFormat.charAt(i);
113 
114                     if (curChar == '#') {
115                         unitedStatesPhoneNumber.append(
116                             integerChars.charAt(integerDigitIndex++));
117                     }
118                     else {
119                         unitedStatesPhoneNumber.append(curChar);
120                     }
121                 }
122 
123                 return unitedStatesPhoneNumber.toString();
124             }
125         }
126 
127         return value;
128     }
129 
130     public String getAsString(
131         FacesContext facesContext, UIComponent uiComponent, Object value)
132         throws ConverterException {
133 
134         // ICE-1537
135 
136         return (String)value;
137     }
138 
139     public void restoreState(FacesContext facesContext, Object obj) {
140         Object[] values = (Object[])obj;
141 
142         _unitedStatesFormat = (String)values[0];
143     }
144 
145     public Object saveState(FacesContext facesContext) {
146         Object[] values = new Object[1];
147 
148         values[0] = _unitedStatesFormat;
149 
150         return values;
151     }
152 
153     private boolean _transient;
154     private String _unitedStatesFormat;
155 
156 }