• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007-2008 Esmertec AG.
3  * Copyright (C) 2007-2008 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package com.android.im.imps;
19 
20 import android.os.Parcel;
21 
22 import com.android.im.engine.Address;
23 import com.android.im.engine.ImEntity;
24 
25 /**
26  * The abstract representation of an IMPS address.
27  */
28 public abstract class ImpsAddress extends Address {
29     private static final char[] SPECIALS = {'/', '@', '+'};
30 
31     protected String mUser;
32     protected String mResource;
33     protected String mDomain;
34 
35     private String mFullAddress;
36 
ImpsAddress()37     protected ImpsAddress() {
38     }
39 
ImpsAddress(String user, String resource, String domain)40     protected ImpsAddress(String user, String resource, String domain) {
41         // build the full address and unify the fields to lower case since imps
42         // address is case insensitive.
43         StringBuilder buf = new StringBuilder(ImpsConstants.ADDRESS_PREFIX);
44         if(user != null) {
45             buf.append(user.toLowerCase());
46         }
47         if(resource != null) {
48             buf.append('/').append(resource.toLowerCase());
49         }
50         if(domain != null) {
51             buf.append('@').append(domain.toLowerCase());
52         }
53         mFullAddress = buf.toString();
54         mUser = user;
55         mResource = resource;
56         mDomain = domain;
57         verifyAddress();
58     }
59 
ImpsAddress(String full)60     protected ImpsAddress(String full){
61         this(full, true);
62     }
63 
ImpsAddress(String full, boolean verify)64     protected ImpsAddress(String full, boolean verify) {
65         if (full == null || full.length() == 0) {
66             throw new IllegalArgumentException();
67         }
68 
69         //TODO: escape reserved characters.
70         if(!full.startsWith(ImpsConstants.ADDRESS_PREFIX)) {
71             full = ImpsConstants.ADDRESS_PREFIX + full;
72         }
73 
74         parse(full);
75         mFullAddress = full;
76 
77         if (verify) {
78             verifyAddress();
79         }
80     }
81 
parse(String full)82     private void parse(String full) {
83         mUser = parseUser(full);
84         mResource = parseResource(full);
85         mDomain = parseDomain(full);
86     }
87 
verifyAddress()88     private void verifyAddress() throws IllegalArgumentException {
89         ImpsLog.log("verifyAddress:" + mUser + ", " + mResource + ",  " + mDomain);
90         if(mUser == null && mResource == null) {
91             throw new IllegalArgumentException();
92         }
93 
94         if(mUser != null) {
95             if(mUser.length() == 0) {
96                 throw new IllegalArgumentException("Invalid user");
97             }
98             if(mUser.charAt(0) == '+') {//mobile number
99                 for(int i = 1; i < mUser.length(); i++) {
100                     if(!Character.isDigit(mUser.charAt(i))) {
101                         throw new IllegalArgumentException("Invalid user");
102                     }
103                 }
104             } else if(!isAlphaSequence(mUser)) {
105                 throw new IllegalArgumentException("Invalid user");
106             }
107         }
108 
109         if(mResource != null && !isAlphaSequence(mResource)) {
110             throw new IllegalArgumentException("Invalid resource");
111         }
112         if(mDomain != null && !isAlphaSequence(mDomain)) {
113             throw new IllegalArgumentException("Invalid domain");
114         }
115     }
116 
117     /**
118      * Gets the User-part of the address which refers to the identification of
119      * the IMPS user.
120      *
121      * @return the User-part of the address.
122      */
getUser()123     public String getUser() {
124         return mUser;
125     }
126 
127     /**
128      * Gets the Resource-part of the address which identifies the referred
129      * public or private resource.
130      *
131      * @return the Resource-part of the address.
132      */
getResource()133     public String getResource() {
134         return mResource;
135     }
136 
137     /**
138      * Gets the Domain-part of the address which identifies the IMPS server
139      * domain.
140      *
141      * @return the Domain-part of the address.
142      */
getDomain()143     public String getDomain() {
144         return mDomain;
145     }
146 
147     /**
148      * Gets the full string representation of the address.
149      */
150     @Override
getFullName()151     public String getFullName() {
152         return mFullAddress;
153     }
154 
155     @Override
writeToParcel(Parcel dest)156     public void writeToParcel(Parcel dest) {
157         dest.writeString(mFullAddress);
158     }
159 
160     @Override
readFromParcel(Parcel source)161     public void readFromParcel(Parcel source) {
162         mFullAddress = source.readString();
163         parse(mFullAddress);
164     }
165 
166     @Override
equals(Object other)167     public boolean equals(Object other) {
168         return other instanceof ImpsAddress
169                 && mFullAddress.equalsIgnoreCase(((ImpsAddress)other).mFullAddress);
170     }
171 
172     @Override
hashCode()173     public int hashCode() {
174         return mFullAddress.toLowerCase().hashCode();
175     }
176 
177     /**
178      * Formats the address to a PrimitiveElement which can be used as the
179      * content of Sender or Recipient.
180      *
181      * @return a PrimitiveElement.
182      */
toPrimitiveElement()183     public abstract PrimitiveElement toPrimitiveElement();
184 
185     /**
186      * Gets the entity this address object refers to.
187      *
188      * @param connection
189      * @return the entity this address refers to or <code>null</code> if the
190      *         entity not found.
191      */
getEntity(ImpsConnection connection)192     abstract ImEntity getEntity(ImpsConnection connection);
193 
194     /**
195      * Constructs an ImpsAddress from the Sender or Recipient element in a
196      * primitive.
197      *
198      * @param elem the Sender of Recipient element.
199      * @return the ImpsAddress object or <code>null</code> if it's not a valid
200      *         element.
201      */
fromPrimitiveElement(PrimitiveElement elem)202     public static ImpsAddress fromPrimitiveElement(PrimitiveElement elem) {
203         String type = elem.getTagName();
204         if(ImpsTags.User.equals(type)) {
205             return new ImpsUserAddress(elem.getChildContents(ImpsTags.UserID), false);
206         } else if(ImpsTags.Group.equals(type)) {
207             PrimitiveElement child = elem.getFirstChild();
208             if(child == null) {
209                 throw new IllegalArgumentException();
210             }
211             if(ImpsTags.GroupID.equals(child.getTagName())){
212                 return new ImpsGroupAddress(child.getContents());
213             } else {
214                 String screeName = child.getChildContents(ImpsTags.SName);
215                 String groupId = child.getChildContents(ImpsTags.GroupID);
216                 return new ImpsGroupAddress(groupId, screeName);
217             }
218         } else if(ImpsTags.ContactList.equals(type)) {
219             return new ImpsContactListAddress(elem.getContents(), false);
220         } else {
221             throw new IllegalArgumentException();
222         }
223     }
224 
parseUser(String full)225     private String parseUser(String full) {
226         int index = full.indexOf('/');
227         if(index == 3) {
228             return null;
229         }
230         if (index == -1) {
231             index = full.lastIndexOf('@');
232         }
233         if (index == -1) {
234             index = full.length();
235         }
236         return full.substring(3, index);
237     }
238 
parseResource(String full)239     private String parseResource(String full) {
240         int beginIndex = full.indexOf('/');
241         if (beginIndex == -1) {
242             return null;
243         }
244         int endIndex = full.lastIndexOf('@');
245         if (endIndex == -1 || endIndex < beginIndex) {
246             endIndex = full.length();
247         }
248         return full.substring(beginIndex + 1, endIndex);
249     }
250 
parseDomain(String full)251     private String parseDomain(String full) {
252         int beginIndex = full.lastIndexOf('@');
253         return beginIndex == -1 ? null : full.substring(beginIndex + 1);
254     }
255 
isAlphaSequence(String str)256     private boolean isAlphaSequence(String str) {
257         for(int i = 0; i < str.length(); i++) {
258             char ch = str.charAt(i);
259             if(ch < 32 || ch > 126 || isSpecial(ch)) {
260                 return false;
261             }
262         }
263         return true;
264     }
265 
isSpecial(char ch)266     private boolean isSpecial(char ch) {
267         for (char element : SPECIALS) {
268             if(ch == element) {
269                 return true;
270             }
271         }
272         return false;
273     }
274 }
275