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