1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights 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 a
44   * desired format. The format is specified by the unitedStatesFormat component
45   * attribute.
46   * </p>
47   *
48   * @author Neil Griffin
49   */
50  public class PhoneNumberConverter implements Converter, StateHolder {
51  
52      public boolean isTransient() {
53          return _transient;
54      }
55  
56      public void setTransient(boolean value) {
57          _transient = value;
58      }
59  
60      public String getUnitedStatesFormat() {
61          return _unitedStatesFormat;
62      }
63  
64      public void setUnitedStatesFormat(String unitedStatesFormat) {
65          _unitedStatesFormat = unitedStatesFormat;
66      }
67  
68      public Object getAsObject(
69          FacesContext facesContext, UIComponent uiComponent, String value) {
70  
71          if (value != null) {
72              StringBuilder integerChars = new StringBuilder();
73              StringBuilder invalidChars = new StringBuilder();
74  
75              for (int i = 0; i < value.length(); i++) {
76                  char curChar = value.charAt(i);
77  
78                  if (Character.isDigit(curChar)) {
79                      integerChars.append(curChar);
80                  }
81                  else if ((curChar != '-') && (curChar != '(') &&
82                           (curChar != ')') && (curChar != '.') &&
83                           (curChar != '+') && (curChar != ' ')) {
84  
85                      invalidChars.append(curChar);
86                  }
87              }
88  
89              if (invalidChars.length() > 0) {
90                  ExternalContext externalContext =
91                      facesContext.getExternalContext();
92  
93                  Locale locale = externalContext.getRequestLocale();
94  
95                  String summary = LanguageUtil.get(
96                      locale, "the-following-are-invalid-characters");
97  
98                  summary += " " + invalidChars.toString();
99  
100                 FacesMessage facesMessage = new FacesMessage(
101                     FacesMessage.SEVERITY_ERROR, summary, null);
102 
103                 throw new ConverterException(facesMessage);
104             }
105             else if ((integerChars.length() == 10)) {
106                 StringBuilder unitedStatesPhoneNumber = new StringBuilder();
107 
108                 int integerDigitIndex = 0;
109 
110                 for (int i = 0; i < _unitedStatesFormat.length(); i++) {
111                     char curChar = _unitedStatesFormat.charAt(i);
112 
113                     if (curChar == '#') {
114                         unitedStatesPhoneNumber.append(
115                             integerChars.charAt(integerDigitIndex++));
116                     }
117                     else {
118                         unitedStatesPhoneNumber.append(curChar);
119                     }
120                 }
121 
122                 return unitedStatesPhoneNumber.toString();
123             }
124         }
125 
126         return value;
127     }
128 
129     public String getAsString(
130         FacesContext facesContext, UIComponent uiComponent, Object value)
131         throws ConverterException {
132 
133         // ICE-1537
134 
135         return (String)value;
136     }
137 
138     public void restoreState(FacesContext facesContext, Object obj) {
139         Object[] values = (Object[])obj;
140 
141         _unitedStatesFormat = (String)values[0];
142     }
143 
144     public Object saveState(FacesContext facesContext) {
145         Object[] values = new Object[1];
146 
147         values[0] = _unitedStatesFormat;
148 
149         return values;
150     }
151 
152     private boolean _transient;
153     private String _unitedStatesFormat;
154 
155 }